@namespace Lumeo
@inject Lumeo.Services.ComponentInteropService Interop
@implements IAsyncDisposable

@if (Scrollable)
{
    <div class="overflow-hidden">
        <div id="@_listId" role="tablist" aria-orientation="@OrientationStr" class="@CssClass overflow-x-auto scrollbar-none" style="@IndicatorStyle" data-sliding-pill="@(UsePillIndicator ? "true" : null)" @attributes="AdditionalAttributes">
            @ChildContent
            @if (TrailingContent is not null)
            {
                @TrailingContent
            }
            @if (RenderIndicator)
            {
                <span aria-hidden="true" class="@IndicatorClass" data-ready="@(_indicatorReady ? "true" : "false")"></span>
            }
        </div>
    </div>
}
else
{
    <div id="@_listId" role="tablist" aria-orientation="@OrientationStr" class="@CssClass" style="@IndicatorStyle" data-sliding-pill="@(UsePillIndicator ? "true" : null)" @attributes="AdditionalAttributes">
        @ChildContent
        @if (TrailingContent is not null)
        {
            @TrailingContent
        }
        @if (RenderIndicator)
        {
            <span aria-hidden="true" class="@IndicatorClass" data-ready="@(_indicatorReady ? "true" : "false")"></span>
        }
    </div>
}

@code {
    [CascadingParameter] public Tabs.TabsContext? Context { get; set; }

    [Parameter] public RenderFragment? ChildContent { get; set; }
    [Parameter] public RenderFragment? TrailingContent { get; set; }
    [Parameter] public bool Scrollable { get; set; }
    [Parameter] public string? Class { get; set; }
    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }

    private readonly string _listId = $"tabslist-{Guid.NewGuid():N}";
    private double _indicatorX;
    private double _indicatorW;
    private bool _indicatorReady;
    private string? _lastMeasuredValue;

    private bool IsVertical => Context?.Orientation == Tabs.TabsOrientation.Vertical;
    private string OrientationStr => IsVertical ? "vertical" : "horizontal";
    private Tabs.TabsVariant CurrentVariant => Context?.Variant ?? Tabs.TabsVariant.Default;

    private bool RenderIndicator => Context?.AnimatedIndicator == true && !IsVertical;

    // Default and Pill variants render a background pill that slides; Card uses an underline.
    private bool UsePillIndicator => RenderIndicator && CurrentVariant != Tabs.TabsVariant.Card;

    private string IndicatorClass => UsePillIndicator ? "lumeo-tabs-indicator" : "lumeo-tabs-underline";

    private string? IndicatorStyle => RenderIndicator
        ? $"--lumeo-tabs-indicator-x: {_indicatorX.ToString(System.Globalization.CultureInfo.InvariantCulture)}px; --lumeo-tabs-indicator-w: {_indicatorW.ToString(System.Globalization.CultureInfo.InvariantCulture)}px;"
        : null;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (!RenderIndicator || Context is null) return;

        var active = Context.ActiveValue;
        if (string.IsNullOrEmpty(active)) return;
        if (!Context.TabIds.TryGetValue(active, out var ids)) return;
        if (_lastMeasuredValue == active && _indicatorReady) return;

        ComponentInteropService.TabMeasurement? measurement;
        try
        {
            measurement = await Interop.TabsMeasure(ids.TabId);
        }
        catch (JSDisconnectedException) { return; }
        catch (InvalidOperationException) { return; } // thrown during prerender when JS is unavailable
        if (measurement is null) return;

        var changed = Math.Abs(measurement.X - _indicatorX) > 0.5
                     || Math.Abs(measurement.Width - _indicatorW) > 0.5
                     || !_indicatorReady;

        _indicatorX = measurement.X;
        _indicatorW = measurement.Width;
        _indicatorReady = true;
        _lastMeasuredValue = active;

        if (changed)
        {
            StateHasChanged();
        }
    }

    public ValueTask DisposeAsync()
    {
        // No persistent JS state to clean up — measure is a one-shot invocation.
        return ValueTask.CompletedTask;
    }

    private string CssClass
    {
        get
        {
            var baseClasses = CurrentVariant switch
            {
                Tabs.TabsVariant.Card => IsVertical
                    ? "flex flex-col h-auto w-auto items-stretch justify-start text-muted-foreground"
                    : "inline-flex h-10 items-center justify-center text-muted-foreground",
                Tabs.TabsVariant.Pill => IsVertical
                    ? "flex flex-col h-auto w-auto items-stretch justify-start gap-1 text-muted-foreground"
                    : "inline-flex h-10 items-center justify-center gap-1 text-muted-foreground",
                _ => IsVertical
                    ? "flex flex-col h-auto w-auto items-stretch justify-start rounded-lg bg-muted p-1 text-muted-foreground"
                    : "inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground"
            };
            var indicatorWrapper = RenderIndicator ? "relative lumeo-tabs-list" : null;
            return string.Join(" ", new[] { baseClasses, indicatorWrapper, Class }.Where(s => !string.IsNullOrWhiteSpace(s)));
        }
    }
}
