@namespace SufiChain.SufiBlazor.Components.Forms
@using SufiChain.SufiBlazor.Components.Common
@inject IJSRuntime JSRuntime

<div class="sb-tag-input @(Disabled ? "sb-tag-input--disabled" : "") @Class" style="@Style" @ref="_containerRef">
    <div class="sb-tag-input__container" @onclick="FocusInput">
        @foreach (var tag in Tags)
        {
            <span class="sb-tag-input__tag">
                <span class="sb-tag-input__tag-text">@tag</span>
                @if (!Disabled && !ReadOnly)
                {
                    <button type="button" 
                            class="sb-tag-input__tag-remove"
                            @onclick="() => RemoveTag(tag)"
                            @onclick:stopPropagation="true"
                            aria-label="Remove @tag">
                        <SbIcon Name="x" Size="SbSize.Sm" />
                    </button>
                }
            </span>
        }
        
        @if (!Disabled && !ReadOnly && (!MaxTags.HasValue || Tags.Count < MaxTags.Value))
        {
            <input type="text"
                   class="sb-tag-input__input"
                   id="@Id"
                   @ref="_inputRef"
                   value="@_inputValue"
                   @oninput="OnInput"
                   @onkeydown="OnKeyDown"
                   @onblur="OnBlur"
                   placeholder="@(Tags.Any() ? "" : Placeholder)"
                   disabled="@Disabled"
                   readonly="@ReadOnly" />
        }
    </div>
    
    @if (MaxTags.HasValue)
    {
        <div class="sb-tag-input__counter">
            @Tags.Count / @MaxTags
        </div>
    }
</div>

@code {
    private ElementReference _containerRef;
    private ElementReference _inputRef;
    private string _inputValue = "";
    
    /// <summary>
    /// The list of tags.
    /// </summary>
    [Parameter]
    public List<string> Tags { get; set; } = new();
    
    /// <summary>
    /// Callback when tags change.
    /// </summary>
    [Parameter]
    public EventCallback<List<string>> TagsChanged { get; set; }
    
    /// <summary>
    /// Placeholder text when no tags.
    /// </summary>
    [Parameter]
    public string Placeholder { get; set; } = "Add tag...";
    
    /// <summary>
    /// Maximum number of tags allowed.
    /// </summary>
    [Parameter]
    public int? MaxTags { get; set; }
    
    /// <summary>
    /// Whether to allow duplicate tags.
    /// </summary>
    [Parameter]
    public bool AllowDuplicates { get; set; }
    
    /// <summary>
    /// Characters that trigger tag creation.
    /// </summary>
    [Parameter]
    public string[] Delimiters { get; set; } = { "Enter", "Tab", "," };
    
    /// <summary>
    /// Whether the input is disabled.
    /// </summary>
    [Parameter]
    public bool Disabled { get; set; }
    
    /// <summary>
    /// Whether the input is read-only.
    /// </summary>
    [Parameter]
    public bool ReadOnly { get; set; }

    /// <summary>
    /// Element ID for the input.
    /// </summary>
    [Parameter]
    public string? Id { get; set; }
    
    /// <summary>
    /// Additional CSS classes.
    /// </summary>
    [Parameter]
    public string? Class { get; set; }

    /// <summary>
    /// Inline styles for the wrapper element.
    /// </summary>
    [Parameter]
    public string? Style { get; set; }
    
    private void OnInput(ChangeEventArgs e)
    {
        var value = e.Value?.ToString() ?? "";
        
        // Check for comma delimiter in the value
        if (value.Contains(','))
        {
            var parts = value.Split(',');
            foreach (var part in parts)
            {
                var trimmed = part.Trim();
                if (!string.IsNullOrEmpty(trimmed))
                {
                    AddTag(trimmed);
                }
            }
            _inputValue = "";
        }
        else
        {
            _inputValue = value;
        }
    }
    
    private async Task OnKeyDown(KeyboardEventArgs e)
    {
        if (Delimiters.Contains(e.Key) && !string.IsNullOrWhiteSpace(_inputValue))
        {
            AddTag(_inputValue.Trim());
            _inputValue = "";
        }
        else if (e.Key == "Backspace" && string.IsNullOrEmpty(_inputValue) && Tags.Any())
        {
            await RemoveTag(Tags.Last());
        }
    }
    
    private void OnBlur()
    {
        if (!string.IsNullOrWhiteSpace(_inputValue))
        {
            AddTag(_inputValue.Trim());
            _inputValue = "";
        }
    }
    
    private async void AddTag(string tag)
    {
        if (string.IsNullOrWhiteSpace(tag)) return;
        if (MaxTags.HasValue && Tags.Count >= MaxTags.Value) return;
        if (!AllowDuplicates && Tags.Contains(tag, StringComparer.OrdinalIgnoreCase)) return;
        
        Tags.Add(tag);
        await TagsChanged.InvokeAsync(Tags);
        StateHasChanged();
    }
    
    private async Task RemoveTag(string tag)
    {
        Tags.Remove(tag);
        await TagsChanged.InvokeAsync(Tags);
    }
    
    private async Task FocusInput()
    {
        if (!Disabled && !ReadOnly && (!MaxTags.HasValue || Tags.Count < MaxTags.Value))
        {
            try
            {
                await _inputRef.FocusAsync();
            }
            catch
            {
                // Input might not be visible yet
            }
        }
    }
}
