using AyCode.Blazor.Components.Components.Grids;
using AyCode.Core.Extensions;
using AyCode.Core.Loggers;
using AyCode.Utils.Extensions;
using DevExpress.Blazor;
using DevExpress.Data.Helpers;
using DevExpress.Utils.Filtering.Internal;
using FruitBank.Common.Models;
using FruitBankHybrid.Shared.Services.SignalRs;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System.Collections.ObjectModel;
using System.Reflection;

namespace FruitBankHybrid.Shared.Components;

public class MgGridBase : DxGrid, IMgGridBase
{
    private bool _isFirstInitializeParameterCore;
    private bool _isFirstInitializeParameters;
    public bool PreRendered { get; set; }

    /// <inheritdoc />
    public bool IsSyncing => false;

    /// <inheritdoc />
    public MgGridEditState GridEditState { get; private set; } = MgGridEditState.None;

    /// <inheritdoc />
    [CascadingParameter]
    public IMgGridBase? ParentGrid { get; set; }

    /// <inheritdoc />
    public IMgGridBase GetRootGrid()
    {
        var current = (IMgGridBase)this;
        while (current.ParentGrid != null)
        {
            current = current.ParentGrid;
        }
        return current;
    }
    
    /// <inheritdoc />
    public IInfoPanelBase? InfoPanelInstance { get; set; }

    /// <inheritdoc />
    public bool IsFullscreen => false;

    public string AutomaticLayoutStorageKey => $"{AutoSaveLayoutName}_Master_AutoSave_{LoggedInModel.CustomerDto?.Id ?? 0}";

    private string UserLayoutStorageKey => AutomaticLayoutStorageKey.Replace("_AutoSave_", "_UserSave_");

    /// <inheritdoc />
    public void ToggleFullscreen()
    {
        // Not implemented in this legacy class - will be removed
    }

    [Inject] public required IEnumerable<IAcLogWriterClientBase> LogWriters { get; set; }
    [Inject] public required FruitBankSignalRClient FruitBankSignalRClient { get; set; }
    [Inject] public required LoggedInModel LoggedInModel { get; set; }
    [Inject] public required IJSRuntime JSRuntime { get; set; }

    [Parameter] public bool IsMasterGrid { get; set; } = false;
    [Parameter] public string AutoSaveLayoutName { get; set; }

    [Parameter]
    public required object DataSource
    {
        get => Data;
        set => Data = value;
    }

    protected override async Task OnInitializedAsync()
    {
        //var json = await GetLocalStorageItemAsync(LocalStorageItemsKey);
        //if (!string.IsNullOrEmpty(json))
        //    Layouts = JsonSerializer.Deserialize<ObservableCollection<UserLayout>>(json);
    }

    protected virtual void CustomizeElementHideDetailButton(GridCustomizeElementEventArgs e)
    {
        if (e.ElementType == GridElementType.DataRow && !LoggedInModel.IsAdministrator)
        {
            e.CssClass = "hideDetailButton";
        }
    }

    protected void OnCustomizeElement(GridCustomizeElementEventArgs e)
    {
        //if (!IsMasterGrid) e.CssClass = "hideDetailButton";

        if (IsMasterGrid && e.ElementType == GridElementType.DataRow && e.VisibleIndex % 2 == 1 && !e.Grid.IsRowSelected(e.VisibleIndex) && !e.Grid.IsRowFocused(e.VisibleIndex))
        {
            e.CssClass = " alt-item";
        }

        CustomizeElementHideDetailButton(e);

        if (e.ElementType == GridElementType.HeaderCell)
        {
            e.Style = "background-color: #E6E6E6;";
            //e.CssClass = "header-bold";
        }
    }
    protected override Task SetParametersAsyncCore(ParameterView parameters)
    {
        if (!_isFirstInitializeParameterCore)
        {
            //if (typeof(TDataItem) is IId<Guid> || typeof(TDataItem) is IId<int>)
            KeyFieldName = "Id";

            //base.DataItemDeleting = EventCallback.Factory.Create<GridDataItemDeletingEventArgs>(this, OnItemDeleting);
            //base.EditModelSaving = EventCallback.Factory.Create<GridEditModelSavingEventArgs>(this, OnItemSaving);

            CustomizeElement += OnCustomizeElement;

            _isFirstInitializeParameterCore = true;
        }

        return base.SetParametersAsyncCore(parameters);
    }


    protected override void OnParametersSet()
    {
        if (!_isFirstInitializeParameters)
        {
            SizeMode = DevExpress.Blazor.SizeMode.Small;
            ShowGroupPanel = IsMasterGrid;
            ShowSearchBox = IsMasterGrid;
            ShowFilterRow = IsMasterGrid;

            FilterMenuButtonDisplayMode = (IsMasterGrid ? GridFilterMenuButtonDisplayMode.Never : GridFilterMenuButtonDisplayMode.Always);

            DetailRowDisplayMode = IsMasterGrid ? GridDetailRowDisplayMode.Auto : GridDetailRowDisplayMode.Never;
            DetailExpandButtonDisplayMode = IsMasterGrid ? GridDetailExpandButtonDisplayMode.Auto : GridDetailExpandButtonDisplayMode.Never;

            TextWrapEnabled = false;
            AllowSelectRowByClick = true;
            HighlightRowOnHover = true;
            AutoCollapseDetailRow = true;
            AutoExpandAllGroupRows = false;

            PagerVisible = true; //IsMasterGrid;
            PageSize = IsMasterGrid ? (SizeMode == DevExpress.Blazor.SizeMode.Small ? 20 : 15) : 10;

            AllowColumnReorder = true;
            AllowGroup = IsMasterGrid;
            AllowSort = true;

            EditMode = GridEditMode.EditRow;
            FocusedRowEnabled = true;
            ColumnResizeMode = GridColumnResizeMode.NextColumn;
            //VirtualScrollingEnabled = IsMasterGrid;
            PageSizeSelectorVisible = true;

            if (IsMasterGrid && !AutoSaveLayoutName.IsNullOrWhiteSpace())
            {
                LayoutAutoLoading = Grid_LayoutAutoLoading;
                LayoutAutoSaving = Grid_LayoutAutoSaving;
            }

            _isFirstInitializeParameters = true;
        }

        base.OnParametersSet();
    }

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            PreRendered = true;
            //StateHasChanged();
        }
    }
    /// <summary>
    /// Navigates to the previous row in the grid
    /// </summary>
    public void StepPrevRow()
    {
        var currentIndex = GetFocusedRowIndex();
        if (currentIndex > 0)
        {
            SetFocusedRowIndex(currentIndex - 1);
        }
    }

    /// <summary>
    /// Navigates to the next row in the grid
    /// </summary>
    public void StepNextRow()
    {
        var currentIndex = GetFocusedRowIndex();
        var visibleRowCount = GetVisibleRowCount();
        if (currentIndex >= 0 && currentIndex < visibleRowCount - 1)
        {
            SetFocusedRowIndex(currentIndex + 1);
        }
    }

    public bool ShowInfoPanel { get; set; } = false;
    public string Caption { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

    async Task Grid_LayoutAutoLoading(GridPersistentLayoutEventArgs e)
    {
        e.Layout = await LoadLayoutFromLocalStorageAsync(AutomaticLayoutStorageKey);
    }

    private async Task Grid_LayoutAutoSaving(GridPersistentLayoutEventArgs e)
    {
        await SaveLayoutToLocalStorageAsync(e.Layout, AutomaticLayoutStorageKey);
    }

    async Task<GridPersistentLayout?> LoadLayoutFromLocalStorageAsync(string localStorageKey)
    {
        try
        {
            var json = await JSRuntime.InvokeAsync<string>("localStorage.getItem", localStorageKey);

            if (!json.IsNullOrWhiteSpace()) return json.JsonTo<GridPersistentLayout>();
        }
        catch
        {
            // Mute exceptions for the server prerender stage
        }

        return null;
    }

    async Task SaveLayoutToLocalStorageAsync(GridPersistentLayout layout, string localStorageKey)
    {
        try
        {
            var json = layout.ToJson();
            await JSRuntime.InvokeVoidAsync("localStorage.setItem", localStorageKey, json);
        }
        catch
        {
            // Mute exceptions for the server prerender stage
        }
    }
    async Task RemoveLayoutFromLocalStorageAsync()
    {
        try
        {
            await JSRuntime.InvokeVoidAsync("localStorage.removeItem", AutomaticLayoutStorageKey);
        }
        catch
        {
            // Mute exceptions for the server prerender stage
        }
    }

    /// <inheritdoc />
    public async Task SaveUserLayoutAsync()
    {
        var layout = SaveLayout();
        await SaveLayoutToLocalStorageAsync(layout, UserLayoutStorageKey);
    }

    /// <inheritdoc />
    public async Task LoadUserLayoutAsync()
    {
        var layout = await LoadLayoutFromLocalStorageAsync(UserLayoutStorageKey);
        if (layout != null)
        {
            LoadLayout(layout);
        }
    }

    /// <inheritdoc />
    public async Task ResetLayoutAsync()
    {
        await RemoveLayoutFromLocalStorageAsync();
        await JSRuntime.InvokeVoidAsync("location.reload");
    }

    /// <inheritdoc />
    public async Task<bool> HasUserLayoutAsync()
    {
        try
        {
            var value = await JSRuntime.InvokeAsync<string>("localStorage.getItem", UserLayoutStorageKey);
            return !string.IsNullOrWhiteSpace(value);
        }
        catch
        {
            return false;
        }
    }
}