@implements IDisposable
@inject NavigationManager NavigationManager

@if (Messages.Count == 0)
{
    return;
}

<div class="messages-container grid px-4 pt-6 lg:gap-4 dark:bg-gray-900">
    @foreach (var message in Messages)
    {
        if (message.Key == "success")
        {
            <AlertMessageSuccess Message="@message.Value" />
        }
    }
    @foreach (var message in Messages)
    {
        if (message.Key == "info")
        {
            <AlertMessageInfo Message="@message.Value" />
        }
    }
    @foreach (var message in Messages)
    {
        if (message.Key == "warning")
        {
            <AlertMessageWarning Message="@message.Value" />
        }
    }
    @foreach (var message in Messages)
    {
        if (message.Key == "error")
        {
            <AlertMessageError Message="@message.Value" />
        }
    }
</div>

<style>
    .messages-container > :last-child {
        margin-bottom: 0 !important;
    }
</style>

@code {
    private List<KeyValuePair<string, string>> Messages { get; set; } = new();

    /// <inheritdoc />
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);

        if (firstRender)
        {
            RefreshAddMessages();
            GlobalNotificationService.OnChange += RefreshAddMessages;
            NavigationManager.LocationChanged += HandleLocationChanged;
        }
    }

    /// <inheritdoc />
    public void Dispose()
    {
        GlobalNotificationService.OnChange -= RefreshAddMessages;
        NavigationManager.LocationChanged -= HandleLocationChanged;
    }

    /// <summary>
    /// Refreshes the messages on navigation to another page.
    /// </summary>
    private void HandleLocationChanged(object? sender, LocationChangedEventArgs e)
    {
        RefreshAddMessages();
        InvokeAsync(StateHasChanged);
    }

    /// <summary>
    /// Refreshes the messages by adding any new messages from the PortalMessageService.
    /// </summary>
    private void RefreshAddMessages()
    {
        // We retrieve any additional messages from the GlobalNotificationService that we do not yet have.
        var newMessages = GlobalNotificationService.GetMessagesForDisplay();
        foreach (var message in newMessages.Where(message => !Messages.Exists(m => m.Key == message.Key && m.Value == message.Value)))
        {
            Messages.Add(message);
        }

        // Remove messages that are no longer in the GlobalNotificationService and have already been displayed.
        var messagesToRemove = Messages.Where(m => !newMessages.Exists(nm => nm.Key == m.Key && nm.Value == m.Value)).ToList();
        foreach (var message in messagesToRemove)
        {
            Messages.Remove(message);
        }

        StateHasChanged();
    }
}
