using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using InABox.Core;
using javax.swing;

namespace InABox.DynamicGrid;

public abstract class BaseEmbeddedListEditorControl<T> : DynamicEditorControl<T, EmbeddedListEditor>
{
    private Button Editor;

    private T _data = default;

    public Action<IDynamicGrid>? CustomiseGrid;

    protected abstract object? GetList(T data);

    protected abstract T SetList(object? data);

    protected abstract void CancelEdit();

    public override void Configure()
    {
    }

    protected override FrameworkElement CreateEditor()
    {
        Editor = new Button
        {
            Content = EditorDefinition.Label,
            HorizontalAlignment = HorizontalAlignment.Stretch,
            VerticalAlignment = VerticalAlignment.Stretch,
            VerticalContentAlignment = VerticalAlignment.Center,
        };
        Editor.Click += Editor_Click;

        return Editor;
    }

    private void Editor_Click(object sender, RoutedEventArgs e)
    {
        var gridtype = DynamicGridUtils.FindDynamicGrid(typeof(DynamicItemsListGrid<>), EditorDefinition.DataType);
        var list = GetList(_data);
        
        var grid = (Activator.CreateInstance(gridtype) as IDynamicItemsListGrid)!;
        grid.Items = list as IList;
        if(grid.GetType().IsGenericType && grid.GetType().GetGenericTypeDefinition() == typeof(DynamicItemsListGrid<>))
        {
            // This is not an overriden grid, so we can customise how we want.

            grid.Reconfigure(options =>
            {
                options.AddRows = EditorDefinition.AddRows;
                options.EditRows = true;
                options.DeleteRows = true;
                options.RecordCount = true;
                if (EditorDefinition.DirectEdit)
                    options.DirectEdit = true;
            });
        }
        CustomiseGrid?.Invoke(grid);
        grid.Refresh(true, true);

        EditorDefinition.CreateButtons(grid);

        var window = new DynamicContentDialog((FrameworkElement)grid)
        {
            Title = $"Edit {ColumnName}",
            CanSave = true
        };
        if (window.ShowDialog() == true)
        {
            _data = SetList(grid.Items);
            CheckChanged();
        }
        else
        {
            CancelEdit();
        }

    }

    public override int DesiredHeight()
    {
        return 25;
    }

    public override int DesiredWidth()
    {
        return 100;
    }

    protected override T RetrieveValue()
    {
        return _data;
    }

    protected override void UpdateValue(T value)
    {
        _data = value;
    }

    public override void SetFocus()
    {
        Editor.Focus();
    }

    public override void SetColor(Color color)
    {
    }
}

public class StringEmbeddedListEditorControl : BaseEmbeddedListEditorControl<string>
{
    protected override object? GetList(string data)
    {
        var listtype = typeof(List<>).MakeGenericType(EditorDefinition.DataType);
        return Serialization.Deserialize(listtype, data) ?? (IList)Activator.CreateInstance(listtype)!;
    }

    protected override string SetList(object? data)
    {
        return Serialization.Serialize(data);
    }

    protected override void CancelEdit()
    {
    }
}

public class ListEmbeddedListEditorControl : BaseEmbeddedListEditorControl<IList>
{
    BaseObjectSnapshot<BaseObject>[]? Snapshots;
    
    protected override object? GetList(IList data)
    {
        Snapshots = data.Cast<BaseObject>().Select(x => x.TakeSnapshot()).ToArray();

        return data;
    }

    protected override IList SetList(object? data)
    {
        return data as IList;
    }

    protected override void CancelEdit()
    {
        foreach(var snapshot in Snapshots)
        {
            snapshot.ResetObject();
        }
    }
}