using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using InABox.Configuration;
using InABox.Core;

namespace InABox.DynamicGrid;

public class DynamicGridColumns : List<DynamicGridColumn>, IGlobalConfigurationSettings, IUserConfigurationSettings
{
    public string GridName { get; set; }

    private static Dictionary<Type, List<DynamicGridColumn>> _columnscache = new Dictionary<Type, List<DynamicGridColumn>>();

    public DynamicGridColumns ExtractColumns(Type type)
    {
        if (!_columnscache.ContainsKey(type))
        {
            _columnscache[type] = new List<DynamicGridColumn>();
            var properties = DatabaseSchema.Properties(type).OrderBy(x => x.Sequence);
            foreach (var prop in properties)
            {
                if ((prop.Editor != null && !(prop.Editor is NullEditor)) || prop.Required)
                {
                    var col = new DynamicGridColumn
                    {
                        ColumnName = prop.Name,
                        Width = prop.Editor.Width,
                        Alignment = prop.Editor.Alignment,
                        Format = prop.Editor.Format,
                        Editor = prop.Editor,
                        Caption = prop.Caption
                    };
                    _columnscache[type].Add(col);
                }
            }
        }
        AddRange(_columnscache[type]);

        return this;
    }

    public DynamicGridColumn Add<TType, TProperty>(Expression<Func<TType, TProperty>> member, int width, string caption, string format,
        Alignment alignment)
    {
        var name = CoreUtils.GetFullPropertyName(member, ".");
        var result = new DynamicGridColumn
        {
            ColumnName = name,
            Caption = caption,
            Width = width,
            Format = format,
            Alignment = alignment
        };
        Add(result);
        return result;
    }
}

public class DynamicGridColumns<T> : DynamicGridColumns
{
    public DynamicGridColumn Add<TProperty>(Expression<Func<T, TProperty>> member, int width, string caption, string format, Alignment alignment)
    {
        return Add<T, TProperty>(member, width, caption, format, alignment);
    }
}

public class DynamicGridColumnGroup(string header, DynamicColumnBase start, DynamicColumnBase end)
{
    public string Header { get; set; } = header;

    public DynamicColumnBase StartColumn { get; set; } = start;

    public DynamicColumnBase EndColumn { get; set; } = end;
}

public class DynamicGridColumnGrouping
{
    public List<DynamicGridColumnGroup> Groups = new();

    public DynamicGridColumnGrouping AddGroup(string header, DynamicColumnBase start, DynamicColumnBase end)
    {
        Groups.Add(new(header, start, end));
        return this;
    }
}

public class DynamicGridColumnGroupings : List<DynamicGridColumnGrouping>
{
}