@namespace Lumeo
@implements IDisposable

@if (Visible)
{
    <button type="button" id="@_itemId" role="option" aria-selected="@IsSelected.ToString().ToLower()"
            class="@CssClass" @onclick="Select" @attributes="AdditionalAttributes">
        <span class="flex h-3.5 w-3.5 items-center justify-center">
            @if (IsSelected)
            {
                <Blazicon Svg="Lucide.Check" class="h-3.5 w-3.5" />
            }
        </span>
        @ChildContent
    </button>
}

@code {
    [CascadingParameter] public Combobox.ComboboxContext Context { get; set; } = default!;
    [Parameter] public RenderFragment? ChildContent { get; set; }
    [Parameter, EditorRequired] public string Value { get; set; } = "";
    [Parameter] public string? Class { get; set; }
    /// <summary>Optional text used to match against the search input. Falls back to Value.</summary>
    [Parameter] public string? SearchValue { get; set; }
    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }

    private readonly string _itemId = $"combobox-item-{Guid.NewGuid():N}";
    private bool _registered;

    private bool IsSelected => Context.Multiple
        ? Context.Values?.Contains(Value) == true
        : Context.Value == Value;

    private bool IsFocused => Context.FocusedItemId == _itemId;

    private bool Visible
    {
        get
        {
            if (string.IsNullOrEmpty(Context.SearchText)) return true;
            var haystack = SearchValue ?? Value;
            return haystack.Contains(Context.SearchText, StringComparison.OrdinalIgnoreCase);
        }
    }

    private string CssClass => string.Join(" ", new[] { "relative flex w-full cursor-pointer select-none items-center gap-2 rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none hover:bg-accent hover:text-accent-foreground", IsFocused ? "bg-accent text-accent-foreground" : null, Class }.Where(s => !string.IsNullOrWhiteSpace(s)));

    protected override void OnParametersSet()
    {
        if (Visible && !_registered)
        {
            Context.RegisterItem(_itemId, Value);
            _registered = true;
        }
        else if (!Visible && _registered)
        {
            Context.UnregisterItem(_itemId);
            _registered = false;
        }
    }

    public void Dispose()
    {
        if (_registered) Context.UnregisterItem(_itemId);
    }

    private async Task Select() => await Context.OnSelect.InvokeAsync(Value);
}
