@namespace SufiChain.SufiBlazor.Components.Overlays
@implements IAsyncDisposable
@inject IJSRuntime JSRuntime
@inject IStringLocalizer<SufiBlazorResource> L
@inject IStringLocalizer<SufiBlazorResource> L

<dialog @ref="_dialogRef"
        class="@CssClass"
        style="@StyleValue"
        @onclick="HandleBackdropClick"
        @onkeydown="HandleKeyDown"
        @oncancel="HandleCancel"
        aria-modal="@(Modal ? "true" : null)"
        @attributes="AdditionalAttributes">
    <div class="sb-drawer__container" @onclick:stopPropagation="true">
        @if (ShowHeader)
        {
            <header class="sb-drawer__header">
                @if (Header != null)
                {
                    @Header
                }
                else if (Title != null)
                {
                    <h2 class="sb-drawer__title">@Title</h2>
                }
                <button type="button" 
                        class="sb-drawer__close-btn" 
                        @onclick="CloseAsync"
                        aria-label="@L["Close"]">
                    <span aria-hidden="true">×</span>
                </button>
            </header>
        }
        <div class="sb-drawer__body">
            @ChildContent
        </div>
        @if (Footer != null)
        {
            <footer class="sb-drawer__footer">
                @Footer
            </footer>
        }
    </div>
</dialog>

@code {
    private ElementReference _dialogRef;
    private bool _isOpen;

    /// <summary>
    /// Whether the drawer is open.
    /// </summary>
    [Parameter]
    public bool Open { get; set; }

    /// <summary>
    /// Callback when open state changes.
    /// </summary>
    [Parameter]
    public EventCallback<bool> OpenChanged { get; set; }

    /// <summary>
    /// Drawer placement.
    /// </summary>
    [Parameter]
    public SbDrawerPlacement Placement { get; set; } = SbDrawerPlacement.Start;

    /// <summary>
    /// Whether drawer is modal (has backdrop).
    /// </summary>
    [Parameter]
    public bool Modal { get; set; } = true;

    /// <summary>
    /// Drawer title.
    /// </summary>
    [Parameter]
    public string? Title { get; set; }

    /// <summary>
    /// Custom header content.
    /// </summary>
    [Parameter]
    public RenderFragment? Header { get; set; }

    /// <summary>
    /// Footer content.
    /// </summary>
    [Parameter]
    public RenderFragment? Footer { get; set; }

    /// <summary>
    /// Drawer body content.
    /// </summary>
    [Parameter]
    public RenderFragment? ChildContent { get; set; }

    /// <summary>
    /// Width for Start/End placement.
    /// </summary>
    [Parameter]
    public string Width { get; set; } = "320px";

    /// <summary>
    /// Height for Top/Bottom placement.
    /// </summary>
    [Parameter]
    public string Height { get; set; } = "320px";

    /// <summary>
    /// Whether to close on Escape key.
    /// </summary>
    [Parameter]
    public bool CloseOnEscape { get; set; } = true;

    /// <summary>
    /// Whether to close on backdrop click.
    /// </summary>
    [Parameter]
    public bool CloseOnBackdropClick { get; set; } = true;

    /// <summary>
    /// Additional CSS classes.
    /// </summary>
    [Parameter]
    public string? Class { get; set; }

    /// <summary>
    /// Additional inline styles.
    /// </summary>
    [Parameter]
    public string? Style { get; set; }

    /// <summary>
    /// Additional HTML attributes.
    /// </summary>
    [Parameter(CaptureUnmatchedValues = true)]
    public Dictionary<string, object>? AdditionalAttributes { get; set; }

    private bool ShowHeader => Header != null || Title != null;

    private string CssClass
    {
        get
        {
            var classes = new List<string> { "sb-drawer" };
            classes.Add($"sb-drawer--{Placement.ToString().ToLowerInvariant()}");
            if (Modal)
            {
                classes.Add("sb-drawer--modal");
            }
            if (!string.IsNullOrWhiteSpace(Class))
            {
                classes.Add(Class);
            }
            return string.Join(" ", classes);
        }
    }

    private string StyleValue
    {
        get
        {
            var styles = new List<string>();
            
            if (Placement is SbDrawerPlacement.Start or SbDrawerPlacement.End)
            {
                styles.Add($"--sb-drawer-width: {Width}");
            }
            else
            {
                styles.Add($"--sb-drawer-height: {Height}");
            }
            
            if (!string.IsNullOrWhiteSpace(Style))
            {
                styles.Add(Style);
            }
            
            return string.Join("; ", styles);
        }
    }

    protected override async Task OnParametersSetAsync()
    {
        if (Open != _isOpen)
        {
            _isOpen = Open;
            if (Open)
            {
                await ShowAsync();
            }
            else
            {
                await HideAsync();
            }
        }
    }

    private async Task ShowAsync()
    {
        if (Modal)
        {
            await JSRuntime.InvokeVoidAsync("SufiBlazor.dialog.showModal", _dialogRef);
        }
        else
        {
            // For non-modal, use show() - but we'll handle via CSS
            await JSRuntime.InvokeVoidAsync("SufiBlazor.dialog.showModal", _dialogRef);
        }
    }

    private async Task HideAsync()
    {
        await JSRuntime.InvokeVoidAsync("SufiBlazor.dialog.close", _dialogRef);
    }

    private async Task CloseAsync()
    {
        await OpenChanged.InvokeAsync(false);
    }

    private async Task HandleBackdropClick(MouseEventArgs args)
    {
        if (CloseOnBackdropClick)
        {
            await CloseAsync();
        }
    }

    private async Task HandleKeyDown(KeyboardEventArgs args)
    {
        if (args.Key == "Escape" && CloseOnEscape)
        {
            await CloseAsync();
        }
    }

    private async Task HandleCancel()
    {
        if (CloseOnEscape)
        {
            await CloseAsync();
        }
    }

    public async ValueTask DisposeAsync()
    {
        // Cleanup if needed
    }
}
