using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using InABox.Clients;
using InABox.Core;
using InABox.WPF;
using Syncfusion.Data;
using Syncfusion.UI.Xaml.Grid;
using Syncfusion.UI.Xaml.TreeGrid;
using Columns = InABox.Core.Columns;

namespace InABox.DynamicGrid;

public class DynamicGridCodePopupColumn<TEntity>(DynamicGridColumn definition) : DynamicGridEditorColumn<CodePopupEditor, GridTemplateColumn, TreeGridTemplateColumn>(definition), IDynamicGridEditorColumn<TEntity>
    where TEntity : BaseObject, new()
{
    public Func<BaseObject?>? GetEntity { get; set; }

    private IColumns GetLinkColumns(Type type, string prefix)
    {
        var prefixwithstop = $"{prefix}.";
        var cols = Columns.None(type);
        var props = DatabaseSchema.Properties(typeof(TEntity))
            .Where(x => x.Name.StartsWith(prefixwithstop, StringComparison.OrdinalIgnoreCase));
        foreach (var prop in props)
            cols.Add(prop.Name.Remove(0,prefixwithstop.Length));
        return cols;

    }

    private Tuple<DataTemplate, DataTemplate> GetTemplates(CodePopupEditor editor)
    {
        var prefix = string.Join(".", Definition.ColumnName.Split('.').SkipLast(1));

        var colname = String.IsNullOrWhiteSpace(editor.CodeColumn)
            ? DatabaseSchema.Properties(editor.Type).FirstOrDefault(x => x.Editor is UniqueCodeEditor)?.Name ?? ""
            : editor.CodeColumn;
        
        var codecolname = prefix.IsNullOrWhiteSpace()
            ? colname
            : $"{prefix}.{colname}";
        ExtraColumns.Add(codecolname);
        codecolname = codecolname.Replace('.', '_');
        
        var cellTemplate = TemplateGenerator.CreateDataTemplate
        (
            () =>
            {
                var result = new Label();
                result.SetBinding(Label.ContentProperty, new Binding(codecolname));
                result.VerticalContentAlignment = VerticalAlignment.Center;
                return result;
            }
        );
        var editTemplate = TemplateGenerator.CreateDataTemplate
        (
            () =>
            {

                var result = new Grid();
                result.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
                result.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) });

                var textbox = new TextBox();
                textbox.CharacterCasing = CharacterCasing.Upper;
                textbox.SetBinding(TextBox.TextProperty, new Binding(codecolname));
                textbox.SetValue(Grid.ColumnProperty, 0);
                textbox.SetValue(Grid.ColumnSpanProperty, 2);

                textbox.Padding = new Thickness(2, 0, 0, 0);
                textbox.VerticalContentAlignment = VerticalAlignment.Center;
                textbox.PreviewKeyDown += (sender, args) => textbox.Tag = true;
                textbox.SetValue(FocusManagerHelper.FocusedElementProperty, true);
                textbox.Tag = false;
                textbox.TextChanged += (sender, args) =>
                {
                    if (Equals(textbox.Tag, false))
                        textbox.SelectAll();
                };
                // textbox.GotFocus += (sender, args) =>
                //     textbox.SelectAll();
                
                textbox.LostFocus += (sender, args) =>
                {
                    if (sender is TextBox { Tag: true } box &&
                        (sender as FrameworkElement)?.DataContext is DataRowView view)
                    {
                        if (String.IsNullOrWhiteSpace(box.Text))
                        {
                            var table = new CoreTable();
                            var columns = GetLinkColumns(editor.Type, prefix);
                            table.LoadColumns(columns);
                            var newrow = table.NewRow(true);
                            UpdateCodePopupColumnValue(newrow,prefix);
                        }
                        else
                        {
                            var lookup = ClientFactory.CreateClient(editor.Type).Query(
                                Filter.Create(editor.Type, colname, Operator.BeginsWith,
                                    box.Text),
                                GetLinkColumns(editor.Type,prefix),
                                null
                            );
                            if (lookup.Rows.Count == 1)
                                UpdateCodePopupColumnValue(lookup.Rows[0], prefix);
                            
                            else
                                PopupCodeList(editor.Type, prefix, codecolname, box.Text, GetLinkColumns(editor.Type,prefix));
                        }
                    }

                };
                result.Children.Add(textbox);

                var button = new Button();
                button.Content = "..";
                button.Width = 25;
                button.SetValue(Grid.ColumnProperty, 1);
                button.Margin = new Thickness(1);
                button.BorderThickness = new Thickness(0.75, 0, 0, 0);
                button.Tag = textbox;
                button.Click += (sender, args) =>
                {
                    PopupCodeList(editor.Type, prefix, codecolname, (button.Tag as TextBox).Text, GetLinkColumns(editor.Type,prefix));
                };
                result.Children.Add(button);

                return result;
            }

        );
        return new Tuple<DataTemplate, DataTemplate>(cellTemplate, editTemplate);
    }

    protected override void Configure(TreeGridTemplateColumn column, CodePopupEditor editor)
    {
        var (cell, edit) = GetTemplates(editor);
        column.CellTemplate = cell;
        column.EditTemplate = edit;
        column.SetCellBoundValue = false;
    }

    protected override void Configure(GridTemplateColumn column, CodePopupEditor editor)
    {
        var (cell, edit) = GetTemplates(editor);
        column.CellTemplate = cell;
        column.EditTemplate = edit;
        column.SetCellBoundValue = false;
    }

    private void PopupCodeList(Type type, string prefix, string codecolname, string value, IColumns columns)
    {
        var entity = GetEntity?.Invoke() as TEntity;
        if (entity != null)
        {
            var msdtype = typeof(MultiSelectDialog<>).MakeGenericType(type);
            var coltype = typeof(Columns<>).MakeGenericType(type);
            var cols = (Activator.CreateInstance(coltype, ColumnTypeFlags.IncludeID) as IColumns);
            
            var msd = Activator.CreateInstance(
                msdtype,
                new object?[]
                {
                    LookupFactory.DefineLookupFilter(typeof(TEntity), type, prefix, new TEntity[] { entity }),
                    cols,
                    false
                }
            ) as IMultiSelectDialog;
            if (msd.ShowDialog(codecolname, value, FilterType.StartsWith))
            {
                var row = msd.Data().Rows.FirstOrDefault();
                if (row != null)
                {
                    row = ClientFactory.CreateClient(type)
                        .Query(Filter.Create(type, "ID", Operator.IsEqualTo, row.Get<Guid>("ID")), columns)
                        .Rows
                        .FirstOrDefault();
                    if (row != null)
                        UpdateCodePopupColumnValue(row,prefix);
                }
            }
        }

    }

    private void UpdateCodePopupColumnValue(CoreRow row, string prefix)
    {
        var dict = row.ToDictionary();
        var updates = dict.ToDictionary(x => $"{prefix}.{x.Key}", x => x.Value);
        this.UpdateData(updates);
    }
}