using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using InABox.Core;
using InABox.DynamicGrid;
using InABox.Scripting;
using InABox.Wpf;
using InABox.WPF;
using Microsoft.Win32;
using Org.BouncyCastle.Asn1.Mozilla;
using Syncfusion.Windows.Shared;
using UnderlineType = InABox.Core.UnderlineType;

namespace InABox.DynamicGrid;

public abstract class DynamicFormLayoutGrid : DynamicOneToManyGrid<DigitalForm, DigitalFormLayout>
{
    private readonly BitmapImage design = Wpf.Resources.design.AsBitmapImage();

    protected override void Init()
    {
        base.Init();

        ActionColumns.Add(new DynamicImageColumn(DesignImage, DesignClick));
        //AddButton("Design", PRSDesktop.Resources.design.AsBitmapImage(), DesignClick);
        HiddenColumns.Add(x => x.Code);
        HiddenColumns.Add(x => x.Description);
        HiddenColumns.Add(x => x.Type);
        HiddenColumns.Add(x => x.Layout);
        HiddenColumns.Add(x => x.Form.Code);
        HiddenColumns.Add(x => x.Form.Description);

        AddButton("Auto Generate", null, AutoGenerate_Click);
        AddButton("Duplicate", null, Duplicate_Click);
    }

    protected override void DoReconfigure(DynamicGridOptions options)
    {
        base.DoReconfigure(options);

        options.RecordCount = true;
        options.ImportData = true;
    }

    private DFLayout LoadLayoutFromSpreadsheet(ISpreadsheet spreadsheet)
    {
        return DigitalFormUtils.LoadLayout(spreadsheet);
    }

    protected override void DoImport()
    {
        var dialog = new OpenFileDialog();
        dialog.Filter = "Excel Spreadsheet (.xlsx)|*.xlsx";
        if (dialog.ShowDialog() == true)
        {
            try
            {
                DFLayout layout;
                Dictionary<String, String> variablegroups = new Dictionary<string, string>();
                using (var fs = new FileStream(dialog.FileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    layout = LoadLayoutFromSpreadsheet(new Spreadsheet(fs));
                }

                var dfLayout = CreateItem();
                dfLayout.Code = Path.GetFileNameWithoutExtension(dialog.FileName).ToUpper();
                dfLayout.Description = $"Imported From {Path.GetFileName(dialog.FileName)}";
                dfLayout.Layout = layout.SaveLayout();
                if(EditItems(new DigitalFormLayout[] { dfLayout }))
                {
                    var newVariables = new List<DigitalFormVariable>();
                    String group = "";
                    foreach (var element in layout.Elements)
                    {
                        if (element is DFLayoutHeader header)
                        {
                            group = header.Header;
                        }
                        else if (element is DFLayoutField field)
                        {
                            var variable = new DigitalFormVariable();
                            variable.SetFieldType(field.GetType());
                            variable.SaveProperties(field.GetProperties());
                            variable.Group = group;
                            variable.Code = field.Name;
                            variable.Description = field.Name;
                            newVariables.Add(variable);
                        }
                    }
                    if(newVariables.Count > 0)
                    {
                        var variables = GetVariableGrid();
                        if (variables is not null)
                        {
                            var save = new List<DigitalFormVariable>();
                            foreach(var newVariable in newVariables)
                            {
                                var variable = variables.GetVariable(newVariable.Code);
                                if(variable is not null)
                                {
                                    if(variable.FieldType() != newVariable.FieldType())
                                    {
                                        MessageBox.Show($"Variable [{newVariable.Code}] already exists with a different type!");
                                    }
                                }
                                else
                                {
                                    save.Add(newVariable);
                                }
                            }

                            variables.SaveItems(save.ToArray());
                            variables.Refresh(false, true);
                        }
                    }

                    Refresh(false, true);
                }
            }
            catch(Exception e)
            {
                MessageWindow.ShowError("Something went wrong", e);
            }
        }
    }

    private bool Duplicate_Click(Button btn, CoreRow[] rows)
    {
        if (!rows.Any()) return false;

        SaveItems(rows.Select(x =>
        {
            var layout = x.ToObject<DigitalFormLayout>();

            var newLayout = CreateItem();
            newLayout.Code = layout.Code;
            newLayout.Description = layout.Description;
            newLayout.Type = layout.Type;
            newLayout.Layout = layout.Layout;

            return newLayout;
        }).ToArray());
        return true;
    }

    private bool AutoGenerate_Click(Button btn, CoreRow[] rows)
    {
        var menu = new ContextMenu();

        menu.AddItem("Desktop Layout", null, AddDesktop_Click);
        menu.AddItem("Mobile Layout", null, AddMobile_Click);

        menu.IsOpen = true;

        return false;
    }

    private BitmapImage? DesignImage(CoreRow? row)
    {
        return row != null ? design : null;
    }

    private void AddMobile_Click()
    {
        var item = CreateItem();

        item.Layout = DFLayout.GenerateAutoMobileLayout(GetVariables()).SaveLayout();
        item.Type = DFLayoutType.Mobile;

        if (EditItems(new[] { item }))
        {
            SaveItem(item);
            Refresh(false, true);
            DoChanged();
        }
    }

    private void AddDesktop_Click()
    {
        var item = CreateItem();

        item.Layout = DFLayout.GenerateAutoDesktopLayout(GetVariables()).SaveLayout();
        item.Type = DFLayoutType.Desktop;

        if (EditItems(new[] { item }))
        {
            SaveItem(item);
            Refresh(false, true);
            DoChanged();
        }
    }

    private DynamicVariableGrid? GetVariableGrid()
        => EditorGrid.Pages?.FirstOrDefault(x => x is DynamicVariableGrid)
            as DynamicVariableGrid;

    private List<DigitalFormVariable> GetVariables()
        => GetVariableGrid()?.Items.ToList() ?? new List<DigitalFormVariable>();

    private void Design(DigitalFormLayout layout)
    {
        var variables = GetVariables();

        var newVariables = new List<DigitalFormVariable>();

        var form = new DynamicFormDesignWindow
        {
            Type = layout.Type
        };
        form.OnCreateVariable += (fieldType) =>
        {
            if (DynamicVariableUtils.CreateAndEdit(Item, GetVariables(), fieldType, out var variable))
            {
                newVariables.Add(variable);
                return variable;
            }
            return null;
        };
        /*form.OnEditVariable += (variable) =>
        {
            var properties = variable.CreateProperties();
            if (DynamicVariableUtils.EditProperties(Item, GetVariables(), properties.GetType(), properties))
            {
                variable.SaveProperties(properties);
                return true;
            }
            return false;
        };*/
        form.LoadLayout(layout, variables);
        form.Initialize();

        if (form.ShowDialog() == true)
        {
            layout.Layout = form.SaveLayout();
            SaveItem(layout);

            var grid = GetVariableGrid();
            if (grid is not null)
            {
                grid.SaveItems(newVariables.ToArray());
                grid.Refresh(false, true);
            }
        }
    }

    private bool DesignClick(CoreRow? row)
    {
        if (row == null)
            return false;

        Design(LoadItem(row));

        return false;
    }


    //public override void SaveItem(DigitalFormLayout item)
    //{
    //    bool bActive = item.Active;
    //    foreach (var other in Items.Where(x=>(x != item) && (x.Type == item.Type)))
    //    {
    //        if (item.Active)
    //        {
    //            if (other.Active)
    //                other.Active = false;
    //        }
    //        else
    //            bActive = bActive || other.Active;
    //    }
    //    if (!bActive)
    //        item.Active = true;
    //    base.SaveItem(item);
    //}

    protected override void DoDoubleClick(object sender, DynamicGridCellClickEventArgs args)
    {
        DesignClick(SelectedRows.FirstOrDefault());
    }
}