using InABox.Core;
using InABox.DynamicGrid;
using InABox.Wpf.Grids;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InABox.Wpf;

public class PostableSettingsGrid : DynamicItemsListGrid<PostableSettings>
{
    public PostableSettingsGrid()
    {
        OnCustomiseEditor += PostableSettingsGrid_OnCustomiseEditor;
        OnEditorValueChanged += PostableSettingsGrid_OnEditorValueChanged;
    }

    private Dictionary<string, object?> PostableSettingsGrid_OnEditorValueChanged(object sender, string name, object value)
    {
        var editorForm = (IDynamicEditorForm)sender;
        if (name == nameof(PostableSettings.PosterType))
        {
            var editor = (editorForm.FindEditor(name) as LookupEditorControl)!;
            (editor.EditorDefinition as ComboLookupEditor)!.Buttons![0].SetEnabled(!string.IsNullOrWhiteSpace(value as string));
            (editor.EditorDefinition as ComboLookupEditor)!.Buttons![1].SetVisible(
                CoreUtils.GetEntityOrNull(value as string)?.IsAssignableTo(typeof(IGlobalSettingsPoster)) == true);
        }
        return new();
    }

    private void PostableSettingsGrid_OnCustomiseEditor(IDynamicEditorForm sender, PostableSettings[]? items, DynamicGridColumn column, BaseEditor editor)
    {
        var settings = items?.FirstOrDefault();
        if (settings is null) return;

        if(column.ColumnName == nameof(PostableSettings.PosterType) && editor is ComboLookupEditor combo)
        {
            var settingsButton = new EditorButton(settings, "Settings", 60, ViewSettings, false);
            settingsButton.SetEnabled(!string.IsNullOrWhiteSpace(settings.PosterType));

            var globalSettingsButton = new EditorButton(settings, "Global Settings", 100, ViewGlobalSettings, false);
            globalSettingsButton.SetVisible(CoreUtils.GetEntityOrNull(settings.PosterType)?.IsAssignableTo(typeof(IGlobalSettingsPoster)) == true);

            combo.Buttons = [settingsButton, globalSettingsButton];
        }
        else if(column.ColumnName == nameof(PostableSettings.ShowPullButton))
        {
            var entityType = CoreUtils.GetEntityOrNull(settings.PostableType);
            var visible = false;
            if (entityType is not null)
            {
                var engine = PosterUtils.GetEngine(entityType);
                if(engine.Get(out var eType, out var _error))
                {
                    visible = eType.HasInterface(typeof(IPullerEngine<>));
                }
            }
            editor.Editable = visible ? Editable.Enabled : Editable.Hidden;
        }
    }

    private void ViewGlobalSettings(object editor, object? item)
    {
        if (item is not PostableSettings settings) return;

        var posterType = CoreUtils.GetEntityOrNull(settings.PosterType);
        var globalSettingsType = posterType?.GetInterfaceDefinition(typeof(IGlobalSettingsPoster<>))?.GenericTypeArguments[0];
        if (globalSettingsType is null) return;

        ConfigureGlobalPosterSettings(globalSettingsType);
    }

    private void ViewSettings(object editor, object? item)
    {
        if (item is not PostableSettings settings) return;

        var entityType = CoreUtils.GetEntityOrNull(settings.PostableType);
        if (entityType is null) return;

        var posterType = CoreUtils.GetEntityOrNull(settings.PosterType);
        var settingsType = posterType?.GetInterfaceDefinition(typeof(IPoster<,>))!.GenericTypeArguments[1];

        ConfigurePosterSettings(entityType, settingsType);
    }

    public static bool ConfigureGlobalPosterSettings(Type globalSettingsType)
    {
        var globalPosterSettings = PosterUtils.LoadGlobalPosterSettings(globalSettingsType);
        var grid = DynamicGridUtils.CreateDynamicGrid(typeof(DynamicItemsListGrid<>), globalSettingsType);
        if(grid.EditItems(new object[] { globalPosterSettings }))
        {
            PosterUtils.SaveGlobalPosterSettings(globalSettingsType, globalPosterSettings);
            return true;
        }
        return false;
    }

    public static bool ConfigurePosterSettings(Type entityType, Type settingsType)
    {
        var posterSettings = PosterUtils.LoadPosterSettings(entityType, settingsType);
        var grid = DynamicGridUtils.CreateDynamicGrid(typeof(PosterSettingsGrid<>), settingsType);
        if(grid.EditItems(new object[] { posterSettings }))
        {
            PosterUtils.SavePosterSettings(entityType, settingsType, posterSettings);
            return true;
        }
        return false;
    }

    public static bool ConfigurePosterSettings<T>(Type settingsType)
        where T : Entity, IPostable, IRemotable, IPersistent, new() => ConfigurePosterSettings(typeof(T), settingsType);
}
