@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Shared.Schemas.Web
@inject IJSRuntime Js

<dialog class="attachment-view" @onkeydown="OnKeyDown" @ref="Dialog">
    <button @onclick="CloseDialog" @onclick:stopPropagation="true" class="close">
        <Icon Name="Icons.X" Size="5rem"></Icon>
    </button>
    @if (Focused < _refs.Count - 1)
    {
        <button @onclick="Next" @onclick:stopPropagation="true" class="carousel-btn next">
            <Icon Name="Icons.ArrowRight" Size="2rem" />
        </button>
    }
    @if (Focused > 0)
    {
        <button @onclick="Prev" @onclick:stopPropagation="true" class="carousel-btn prev">
            <Icon Name="Icons.ArrowLeft" Size="2rem" />
        </button>
    }
    <div class="wrap" @ref="Scroller" @onscroll="Scroll">
        @foreach (var element in Attachments)
        {
            <div class="container" @ref="@Ref">
                <img class="attachment" src="@element.Url" alt="@element.AltText" fetchpriority="low"/>
                @if (!string.IsNullOrWhiteSpace(element.AltText))
                {
                    <div class="alt-text">@element.AltText</div>
                }
            </div>
        }
    </div>
</dialog>

@code {
    [Parameter] [EditorRequired] public required IList<NoteAttachment>  Attachments { get; set; }
    private                                      ElementReference       Dialog      { get; set; }
    private                                      IJSObjectReference     Module      { get; set; } = null!;
    private                                      int                    Focused     { get; set; }
    private                                      List<ElementReference> _refs = [];

    public ElementReference Ref
    {
        set => _refs.Add(value);
    }

    private async Task OnKeyDown(KeyboardEventArgs e)
    {
        switch (e.Key)
        {
            case "ArrowRight":
                await Next();
                break;
            case "ArrowLeft":
                await Prev();
                break;
        }
    }

    private ElementReference Scroller    { get; set; }
    private double              ScrollWidth { get; set; }
    private double              ScrollLeft  { get; set; }

    protected override void OnParametersSet()
    {
        Focused = 0;
    }

    private async Task Scroll()
    {
        ScrollLeft = await Module.InvokeAsync<double>("getScrollLeft", Scroller);
        var fraction = ScrollWidth / _refs.Count;
        var section  = ScrollLeft / fraction;
        Focused = Convert.ToInt32(section); //ToInt32 rounds
    }

    private async Task Next()
    {
        if (Focused >= _refs.Count -1)
        {
            return;
        }

        Focused += 1;
        await Module.InvokeVoidAsync("scrollTo", _refs[Focused]);
    }

    private async Task Prev()
    {
        if (Focused <= 0)
        {
            return;
        }

        Focused -= 1;
        await Module.InvokeVoidAsync("scrollTo", _refs[Focused]);
    }

    public async Task OpenDialog(NoteAttachment attachment)
    {
        await Module.InvokeVoidAsync("openDialog", Dialog);
        ScrollWidth = await Module.InvokeAsync<int>("getScrollWidth", Scroller);
        var index = Attachments.IndexOf(attachment);
        await Module.InvokeVoidAsync("scrollTo", _refs[index]);
    }

    private async Task CloseDialog()
    {
        await Module.InvokeVoidAsync("closeDialog", Dialog);
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            Module = await Js.InvokeAsync<IJSObjectReference>("import",
                                                              "./Components/AttachmentView.razor.js");
        }
    }
}