@using AngleSharp.Text
@using Iceshrimp.Frontend.Core.Services
@using Iceshrimp.Shared.Schemas.Web
@inject EmojiService       EmojiService
@inject GlobalComponentSvc GlobalComponentSvc
@inject IJSRuntime         Js

<dialog class="dialog" @ref="EmojiPickerRef">
    <div class="emoji-picker" style="--top: @(_top)px; --left: @(_left)px">
        <input @bind="EmojiFilter" @bind:event="oninput" @bind:after="FilterEmojis" class="search" type="text" placeholder="Search" aria-label="search"/>
        @foreach (var category in Categories)
        {
            <details open>
                <summary aria-label="category">@category.Key</summary>
                <div class="emoji-list">
                    @foreach (var emoji in category.Value)
                    {
                        <div @onclick="() => Select(emoji)" class="emoji" title=":@emoji.Name:">
                            <InlineEmoji Name="@emoji.Name" Url="@emoji.PublicUrl" Size="2rem"/>
                        </div>
                    }
                </div>
            </details>
        }
    </div>
    <ClosingBackdrop OnClose="Close"></ClosingBackdrop>
</dialog>


@code {
    private EventCallback<EmojiResponse> OnEmojiSelect  { get; set; }
    private List<EmojiResponse>          EmojiList      { get; set; } = [];
    private ElementReference             EmojiPickerRef { get; set; }
    private float                        _top;
    private float                        _left;
    private IJSInProcessObjectReference  _module = null!;

    private string                                  EmojiFilter { get; set; } = "";
    private Dictionary<string, List<EmojiResponse>> Categories  { get; set; } = [];

    protected override async Task OnInitializedAsync()
    {
        GlobalComponentSvc.EmojiPicker = this;
        EmojiList                      = await EmojiService.GetEmojiAsync();
        _module = (IJSInProcessObjectReference)await Js.InvokeAsync<IJSObjectReference>("import",
                                                                                        "./Components/EmojiPicker.razor.js");
        FilterEmojis();
    }

    private async Task Select(EmojiResponse emoji)
    {
        await OnEmojiSelect.InvokeAsync(emoji);
        Close();
    }

    private void Close()
    {
        _module.InvokeVoid("closeDialog", EmojiPickerRef);
    }

    public void Open(ElementReference root, EventCallback<EmojiResponse> func)
    {
        OnEmojiSelect = func;
        var pos = _module.Invoke<List<float>>("getPosition", root);
        _left = pos[0];
        _top  = pos[1];
        StateHasChanged();
        _module.InvokeVoid("openDialog", EmojiPickerRef);
    }

    private void FilterEmojis()
    {
        Categories = EmojiList
            .Where(p => p.Name.Contains(EmojiFilter.StripLeadingTrailingSpaces()) || p.Aliases.Count(a => a.Contains(EmojiFilter.StripLeadingTrailingSpaces())) != 0)
            .OrderBy(p => p.Name)
            .ThenBy(p => p.Id)
            .GroupBy(p => p.Category)
            .OrderBy(p => string.IsNullOrEmpty(p.Key))
            .ThenBy(p => p.Key)
            .ToDictionary(p => p.Key ?? "Other", p => p.ToList());
    }
}