using AyCode.Core.Consts;
using AyCode.Core.Extensions;
using AyCode.Core.Loggers;
using AyCode.Services.SignalRs;
using AyCode.Utils.Extensions;
using DevExpress.Blazor;
using FruitBank.Common.Dtos;
using FruitBank.Common.Models;
using FruitBank.Common.Models.SignalRs;
using FruitBank.Common.SignalRs;
using FruitBankHybrid.Shared.Pages;
using FruitBankHybrid.Shared.Services.Loggers;
using FruitBankHybrid.Shared.Services.SignalRs;
using Mango.Nop.Core.Loggers;
using Microsoft.AspNetCore.Components;

namespace FruitBankHybrid.Shared.Layout;

public partial class MainLayout : LayoutComponentBase, IDisposable
{
    [Inject] public required IEnumerable<IAcLogWriterClientBase> LogWriters { get; set; }
    [Inject] public required NavigationManager NavManager { get; set; }
    [Inject] public required LoggedInModel LoggedInModel { get; set; }
    [Inject] IToastNotificationService ToastService { get; set; }
    [Inject] public required FruitBankSignalRClient FruitBankSignalRClient { get; set; }

    private EventCallback RefreshMainLayoutEventCallback => EventCallback.Factory.Create(this, RefreshMainLayout);
    private NavMenu _navMenu = null!;
    private LoggerClient _logger = null!;

    private bool IsOnLoginPage => NavManager.Uri.Equals(NavManager.ToAbsoluteUri("/Login").ToString(), StringComparison.OrdinalIgnoreCase);

    // Toast fields
    private DxToast orderNotificationToast;
    private string toastTitle = "Értesítő!";
    private string? toastMessage;
    private string? toastOrderNumber;
    private DateTime? toastDateOfReceipt;

    protected override void OnInitialized()
    {
        _logger = new LoggerClient<MainLayout>(LogWriters.ToArray());
        _logger.Info("OnInitialized");

        // Setup login delegates
        LoggedInModel.LoginFunc = FruitBankSignalRClient.LoginMeasuringUser;
        LoggedInModel.GetRolesFunc = FruitBankSignalRClient.GetCustomerRolesByCustomerId;

        FruitBankSignalRClient.OnMessageReceived += SignalRClientOnMessageReceived;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (!firstRender) return;

        await LoggedInModel.TryAutoLoginAsync();

        if (!LoggedInModel.IsLoggedIn && !IsOnLoginPage)
        {
            NavManager.NavigateTo("/Login");
        }
        else if (LoggedInModel.IsLoggedIn)
        {
            RefreshMainLayout();
            //StateHasChanged(); // Refresh UI after successful auto-login
        }
    }

    private async Task SignalRClientOnMessageReceived(int messageTag, SignalResponseDataMessage? responseDataMessage)
    {
        if (messageTag != SignalRTags.NotificationReceived || !LoggedInModel.IsLoggedIn) return;

        try
        {
            var notificationMessage = responseDataMessage?.GetResponseData<SignalRMessageToClientWithText<OrderDto>>();
            if (notificationMessage == null)
            {
                _logger.Error($"MainLayout.SignalRClientOnMessageReceived; notificationMessage == null; messageTag: {messageTag}");
                return;
            }

            toastOrderNumber = null;
            toastDateOfReceipt = null;

            toastMessage = notificationMessage.Message;

            var orderDto = notificationMessage.Content;
            var hasPermission = orderDto == null || (orderDto.HasMeasuringAccess(LoggedInModel.CustomerDto!.Id, LoggedInModel.IsRevisor) || orderDto.MeasurementOwnerId == 0);

            if (orderDto != null && hasPermission)
            {
                toastOrderNumber = orderDto.CustomOrderNumber;
                toastDateOfReceipt = orderDto.DateOfReceipt;
            }

            if (!hasPermission) return;

            _logger.Debug($"MainLayout.SignalRClientOnMessageReceived; NotificationMessage received. {toastMessage}");

            await InvokeAsync(() =>
            {
                orderNotificationToast?.Show();
                StateHasChanged();
            });
        }
        catch (Exception ex)
        {
            _logger.Error($"MainLayout.SignalRClientOnMessageReceived ERROR; messageTag: {messageTag}", ex);
        }
    }

    private async void OnLogoutClick()
    {
        try
        {
            await LoggedInModel.LogOutAsync();
            RefreshMainLayout();
            NavManager.NavigateTo("/Login");
        }
        catch (Exception e)
        {
            _logger.Error($"OnLogoutClick error");
        }
    }

    public void RefreshMainLayout()
    {
        _navMenu.RefreshNavMenu();
        StateHasChanged();
    }

    public void Dispose()
    {
        FruitBankSignalRClient.OnMessageReceived -= SignalRClientOnMessageReceived;
    }
}