@page "/Notifications"
@attribute [Authorize]
@using CommunityToolkit.Mvvm.Messaging
@using salesbook.Shared.Components.Layout
@using salesbook.Shared.Components.Layout.Spinner
@using salesbook.Shared.Components.SingleElements
@using salesbook.Shared.Core.Dto.PageState
@using salesbook.Shared.Core.Entity
@using salesbook.Shared.Core.Interface
@using salesbook.Shared.Core.Interface.IntegryApi
@using salesbook.Shared.Core.Messages.Notification.Loaded
@using salesbook.Shared.Core.Messages.Notification.NewPush
@inject NotificationState Notification
@inject NewPushNotificationService NewPushNotificationService
@inject IJSRuntime JS
@inject IIntegryNotificationRestClient IntegryNotificationRestClient
@inject INotificationService NotificationService
@inject IMessenger Messenger

<HeaderLayout Title="Notifiche" />

<div class="container container-notifications">
    @if (Loading)
    {
        <SpinnerLayout FullScreen="true" />

    }
    else
    {
        if (Notification.ReceivedNotifications.IsNullOrEmpty() && Notification.UnreadNotifications.IsNullOrEmpty() && Notification.NotificationsRead.IsNullOrEmpty())
        {
            <NoDataAvailable Text="Nessuna notifica meno recente" />
        }
        else
        {
            <div class="list" id="list">
                @foreach(var notification in Notification.ReceivedNotifications)
                {
                    <NotificationCard Unread="true" Notification="notification" />
                }
                
                @foreach(var notification in Notification.UnreadNotifications)
                {
                    <NotificationCard Unread="true" Notification="notification" />
                }

                @foreach (var notification in Notification.NotificationsRead)
                {
                    <NotificationCard Notification="notification" />
                }
            </div>
        }
    }
</div>

@code {
    private DotNetObjectReference<Notifications>? _objectReference;
    private bool Loading { get; set; }

    protected override Task OnInitializedAsync()
    {
        _objectReference = DotNetObjectReference.Create(this);
        NewPushNotificationService.OnNotificationReceived += NewNotificationReceived;
        return Task.CompletedTask;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await JS.InvokeVoidAsync("initNotifications", _objectReference);
    }

    private void NewNotificationReceived(WtbNotification notification)
    {
        InvokeAsync(StateHasChanged);
    }

    [JSInvokable]
    public async Task Delete(string id)
    {
        if (!long.TryParse(id, out var notificationId)) return;

        Loading = true;
        StateHasChanged();

        var removed = false;

        if (Notification.ReceivedNotifications.RemoveAll(x => x.Id == notificationId) > 0)
            removed = true;
        else if (Notification.UnreadNotifications.RemoveAll(x => x.Id == notificationId) > 0)
            removed = true;
        else if (Notification.NotificationsRead.RemoveAll(x => x.Id == notificationId) > 0)
            removed = true;

        if (!removed)
        {
            Loading = false;
            StateHasChanged();
            return;
        }

        await IntegryNotificationRestClient.Delete(notificationId);

        NotificationService.OrderNotificationList();
        Loading = false;
        StateHasChanged();

        Messenger.Send(new NotificationsLoadedMessage());
    }

    [JSInvokable]
    public async Task MarkAsRead(string id)
    {
        Loading = true;
        StateHasChanged();

        var notificationId = long.Parse(id);

        var wtbNotification = Notification.ReceivedNotifications
            .FindLast(x => x.Id == notificationId);

        if (wtbNotification == null)
        {
            wtbNotification = Notification.UnreadNotifications
                .FindLast(x => x.Id == notificationId);

            Notification.UnreadNotifications.Remove(wtbNotification!);
        }
        else
        {
            Notification.ReceivedNotifications.Remove(wtbNotification);
        }

        wtbNotification = await IntegryNotificationRestClient.MarkAsRead(notificationId);
        Notification.NotificationsRead.Add(wtbNotification);

        NotificationService.OrderNotificationList();
        Messenger.Send(new NotificationsLoadedMessage());
        Loading = false;
        StateHasChanged();
    }

    public void Dispose()
    {
        _objectReference?.Dispose();
    }
}