@*
   Reusable toast notification component.

   z-index ladder:
     Toast container   1090  (this component, on top)
     ConfirmDialog modal element  1055  (Bootstrap default for .modal)
     ConfirmDialog backdrop       1040  (Bootstrap default for .modal-backdrop)

   Toasts intentionally float above ConfirmDialog so confirmation feedback
   (Success/Error) is visible even while a dialog is open.
*@
@implements IDisposable

<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 1090;" aria-live="polite" aria-atomic="true">
    @foreach (var toast in _toasts)
    {
        <div class="toast show mb-2" role="alert">
            <div class="toast-header @GetHeaderClass(toast.Type)">
                <strong class="me-auto">@toast.Title</strong>
                <button type="button" class="btn-close btn-close-white" @onclick="() => Dismiss(toast)"></button>
            </div>
            <div class="toast-body">@toast.Message</div>
        </div>
    }
</div>

@code {
    private const int DefaultAutoDismissMs = 5000;

    private readonly List<ToastItem> _toasts = new();
    private readonly object _lock = new();

    public void ShowSuccess(string message, string title = "Success", int? autoDismissMs = null)
    {
        AddToast(title, message, ToastType.Success, autoDismissMs);
    }

    public void ShowError(string message, string title = "Error", int? autoDismissMs = null)
    {
        AddToast(title, message, ToastType.Error, autoDismissMs);
    }

    public void ShowWarning(string message, string title = "Warning", int? autoDismissMs = null)
    {
        AddToast(title, message, ToastType.Warning, autoDismissMs);
    }

    public void ShowInfo(string message, string title = "Info", int? autoDismissMs = null)
    {
        AddToast(title, message, ToastType.Info, autoDismissMs);
    }

    private void AddToast(string title, string message, ToastType type, int? autoDismissMs)
    {
        var toast = new ToastItem { Title = title, Message = message, Type = type };
        lock (_lock)
        {
            _toasts.Add(toast);
        }
        StateHasChanged();

        var dismissMs = autoDismissMs ?? DefaultAutoDismissMs;
        _ = Task.Delay(dismissMs).ContinueWith(_ =>
        {
            lock (_lock)
            {
                _toasts.Remove(toast);
            }
            InvokeAsync(StateHasChanged);
        });
    }

    private void Dismiss(ToastItem toast)
    {
        lock (_lock)
        {
            _toasts.Remove(toast);
        }
    }

    private static string GetHeaderClass(ToastType type) => type switch
    {
        ToastType.Success => "bg-success text-white",
        ToastType.Error => "bg-danger text-white",
        ToastType.Warning => "bg-warning text-dark",
        ToastType.Info => "bg-info text-dark",
        _ => "bg-secondary text-white"
    };

    public void Dispose() { }

    private enum ToastType { Success, Error, Warning, Info }

    private class ToastItem
    {
        public string Title { get; init; } = "";
        public string Message { get; init; } = "";
        public ToastType Type { get; init; }
    }
}
