@namespace Lumeo
@implements IDisposable

@{
    var itemContext = new NavigationMenuItemContext(_itemId, _triggerId);
}

<CascadingValue Value="itemContext" IsFixed="true">
    <li class="@CssClass"
        @onpointerenter="HandlePointerEnter"
        @onpointerleave="HandlePointerLeave"
        @attributes="AdditionalAttributes">
        @ChildContent
    </li>
</CascadingValue>

@code {
    [CascadingParameter] public NavigationMenu.NavigationMenuContext Context { get; set; } = default!;
    [Parameter] public RenderFragment? ChildContent { get; set; }
    [Parameter] public string? Class { get; set; }
    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }

    private readonly string _itemId = $"nav-item-{Guid.NewGuid():N}";
    private readonly string _triggerId = $"nav-trigger-{Guid.NewGuid():N}";
    private readonly DelayedDispatch _dispatch = new();
    private const int CloseDelay = 150;

    private string CssClass => $"relative {Class}".Trim();

    // rc.44 — Approach B: pointer events with PointerType filter. On touch
    // devices the browser emulates `mouseenter` on tap and `mouseleave` when
    // the finger lifts — closing the submenu before the user can interact
    // with it. Only fire hover behavior for mouse pointers; touch users rely
    // on the explicit @onclick toggle in NavigationMenuTrigger.
    private void HandlePointerEnter(PointerEventArgs e)
    {
        if (e.PointerType != "mouse") return;
        _dispatch.Cancel();
    }

    private void HandlePointerLeave(PointerEventArgs e)
    {
        if (e.PointerType != "mouse") return;
        if (Context.ActiveItemId == _itemId)
        {
            _dispatch.Schedule(CloseDelay, () => InvokeAsync(async () =>
            {
                if (Context.ActiveItemId == _itemId)
                {
                    await Context.SetActiveItemId.InvokeAsync(null);
                    StateHasChanged();
                }
            }));
        }
    }

    public void Dispose() => _dispatch.Dispose();

    public record NavigationMenuItemContext(string ItemId, string TriggerId);
}
