@namespace Lumeo
@inject Lumeo.Services.IComponentInteropService Interop

<button @ref="_el" type="button" aria-pressed="@IsPressed.ToString().ToLower()" class="@CssClass" @onclick="Toggle" disabled="@Disabled" @attributes="AdditionalAttributes">
    @ChildContent
</button>

@code {
    [Parameter, EditorRequired] public string Value { get; set; } = "";
    [Parameter] public RenderFragment? ChildContent { get; set; }
    [Parameter] public bool Disabled { get; set; }

    /// <summary>
    /// Visual feedback when the item is pressed. Default is
    /// <see cref="Button.ButtonPressEffect.None"/>.
    /// </summary>
    [Parameter] public Button.ButtonPressEffect PressEffect { get; set; } = Button.ButtonPressEffect.None;

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

    [CascadingParameter] public ToggleGroup.ToggleGroupContext Context { get; set; } = default!;

    private Microsoft.AspNetCore.Components.ElementReference _el;

    private bool IsPressed => Context.SelectedItems.Contains(Value);

    private string CssClass => string.Join(" ", new[] { VariantClasses, SizeClasses, BaseClasses, "cursor-pointer disabled:cursor-not-allowed", PressEffectClass, Class }.Where(s => !string.IsNullOrWhiteSpace(s)));

    // gap-1.5 mirrors Button's base gap so icon+label children space cleanly without
    // requiring consumers to add Class="gap-1.5" manually. Single-child renders are
    // unaffected (gap only matters when there are multiple flex children).
    private const string BaseClasses = "inline-flex items-center justify-center gap-1.5 rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50";

    private string? PressEffectClass => PressEffect switch
    {
        Button.ButtonPressEffect.Scale => "lumeo-press-scale",
        Button.ButtonPressEffect.Brightness => "lumeo-press-brightness",
        Button.ButtonPressEffect.Ripple => "lumeo-press-ripple",
        _ => null
    };

    private string VariantClasses => (Context.Variant, IsPressed) switch
    {
        (ToggleGroup.ToggleGroupVariant.Default, true) => "bg-accent text-accent-foreground",
        (ToggleGroup.ToggleGroupVariant.Default, false) => "bg-transparent hover:bg-muted hover:text-muted-foreground",
        (ToggleGroup.ToggleGroupVariant.Outline, true) => "bg-accent text-accent-foreground border border-input",
        (ToggleGroup.ToggleGroupVariant.Outline, false) => "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
        _ => ""
    };

    private string SizeClasses => Context.Size switch
    {
        ToggleGroup.ToggleGroupSize.Default => "h-9 px-3",
        ToggleGroup.ToggleGroupSize.Sm => "h-8 px-2",
        ToggleGroup.ToggleGroupSize.Lg => "h-10 px-4",
        _ => ""
    };

    private async Task Toggle()
    {
        if (!Disabled)
        {
            await Context.Toggle.InvokeAsync(Value);
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender && PressEffect == Button.ButtonPressEffect.Ripple)
        {
            try
            {
                await Interop.RippleAttachAsync(_el);
            }
            catch (Microsoft.JSInterop.JSDisconnectedException) { }
        }
    }
}
