using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Media.Imaging;
using InABox.Clients;
using InABox.Core;
using InABox.DynamicGrid;
using InABox.Core.Reports;
using InABox.WPF;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
using SaveFileDialog = Microsoft.Win32.SaveFileDialog;
using ScriptEditor = InABox.DynamicGrid.ScriptEditorWindow;
using System.Threading;

namespace InABox.Wpf.Reports
{
    public class ReportGrid : DynamicDataGrid<ReportTemplate>
    {

        private ReportTemplate? SelectedTemplate;

        public ReportGrid()
        {
            //OnAddItem += ReportGrid_OnAddItem;
            //OnEditItem += ReportGrid_OnEditItem;
        }

        protected override void Init()
        {
            base.Init();
            ActionColumns.Add(new DynamicImageColumn(Wpf.Resources.load.AsBitmapImage(), ImportClick)
            { Position = DynamicActionColumnPosition.Start });
            ActionColumns.Add(new DynamicImageColumn(Wpf.Resources.save.AsBitmapImage(), ExportClick)
            { Position = DynamicActionColumnPosition.Start });

            ActionColumns.Add(new DynamicImageColumn(ScriptImage, ScriptClick));
            ActionColumns.Add(new DynamicImageColumn(Wpf.Resources.pencil.AsBitmapImage(), DesignClick));
            HiddenColumns.Add(x => x.IsRDL);
            HiddenColumns.Add(x => x.Script);
        }

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

            options.RecordCount = true;
            options.ShowHelp = true;
        }

        public DataModel DataModel { get; set; }

        public string Section { get; set; }

        public bool Populate { get; set; }

        private bool ScriptClick(CoreRow? arg)
        {
            if (arg != null)
            {
                var template = arg.ToObject<ReportTemplate>();
                var script = template.Script;
                if (string.IsNullOrWhiteSpace(script))
                    script = string.Format(ReportTemplate.DefaultScriptTemplate, DataModel.GetType().Name.Split('.').Last());
                var editor = new ScriptEditor(script);
                if (editor.ShowDialog() == true)
                {
                    template.Script = editor.Script;
                    new Client<ReportTemplate>().Save(template, "Updated Script");
                    return true;
                }
            }

            return false;
        }

        private BitmapImage? ScriptImage(CoreRow? arg)
        {
            return arg == null ?Wpf.Resources.edit.AsBitmapImage() :
                arg.Get<ReportTemplate, bool>(x => x.IsRDL) ? null :Wpf.Resources.edit.AsBitmapImage();
        }


        protected override DynamicGridColumns LoadColumns()
        {
            var columns = new DynamicGridColumns<ReportTemplate>();
            columns.Add(x => x.Name, width: 0);
            columns.Add(x => x.Visible, width: 50, alignment: Alignment.MiddleCenter);
            return columns;
        }

        protected override void Reload(
            Filters<ReportTemplate> criteria, Columns<ReportTemplate> columns, ref SortOrder<ReportTemplate>? sort,
            CancellationToken token, Action<CoreTable?, Exception?> action)
        {
            criteria.Add(new Filter<ReportTemplate>(x => x.DataModel).IsEqualTo(DataModel.Name).And(x => x.Section).IsEqualTo(Section));
            base.Reload(criteria, columns, ref sort, token, action);
        }

        private bool ReportGrid_OnEditItem(object sender, object item)
        {
            var editor = new DynamicEditorForm(item.GetType());
            //editor.OnCustomiseColumns += Editor_OnDefineGridColumns;
            editor.Items = new[] { (BaseObject)item };
            var bOK = editor.ShowDialog() == true;
            return bOK;
        }

        // private void Editor_OnDefineGridColumns(object sender, DynamicGridColumns columns)
        // {
        //      LoadColumns();
        // }

        private bool ExportClick(CoreRow? row)
        {
            if (row is null) return false;

            var id = row.Get<ReportTemplate, Guid>(x => x.ID);
            SelectedTemplate = new Client<ReportTemplate>().Load(new Filter<ReportTemplate>(x => x.ID).IsEqualTo(id)).FirstOrDefault();
            if(SelectedTemplate is null)
            {
                Logger.Send(LogType.Error, "", $"Report Template {id} does not exist!");
                return false;
            }
            var dlg = new SaveFileDialog
            {
                Filter = "RDL Files|*.rdl"
            };
            if (dlg.ShowDialog() == true)
                File.WriteAllText(dlg.FileName, SelectedTemplate.RDL);
            return false;
        }

        private bool ImportClick(CoreRow? row)
        {
            if (row is null) return false;

            var id = row.Get<ReportTemplate, Guid>(x => x.ID);

            var dlg = new OpenFileDialog
            {
                Filter = "RDL Files|*.rdl"
            };
            if (dlg.ShowDialog() == true)
            {
                SelectedTemplate = new Client<ReportTemplate>().Load(new Filter<ReportTemplate>(x => x.ID).IsEqualTo(id)).FirstOrDefault();
                if (SelectedTemplate is null)
                {
                    Logger.Send(LogType.Error, "", $"Report Template {id} does not exist!");
                    return false;
                }
                SelectedTemplate.RDL = File.ReadAllText(dlg.FileName);
                new Client<ReportTemplate>().Save(SelectedTemplate, "Imported from " + dlg.FileName);
            }

            return false;
        }

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

            var id = row.Get<ReportTemplate, Guid>(x => x.ID);
            SelectedTemplate = new Client<ReportTemplate>().Load(new Filter<ReportTemplate>(x => x.ID).IsEqualTo(id)).FirstOrDefault();
            if (SelectedTemplate is null)
            {
                Logger.Send(LogType.Error, "", $"Report Template {id} does not exist!");
                return false;
            }
            ReportUtils.DesignReport(SelectedTemplate, DataModel, Populate);
            return false;
        }

        public override ReportTemplate CreateItem()
        {
            var template = base.CreateItem();
            template.DataModel = DataModel.Name;
            template.Section = Section;
            template.Name = "Untitled Report";
            return template;
        }

        /*private void ReportGrid_OnAddItem(object sender, object item)
        {
            SelectedTemplate = (ReportTemplate)item;
            SelectedTemplate.DataModel = DataModel.Name;
            SelectedTemplate.Section = Section;
            SelectedTemplate.Name = "Untitled Report";
        }


        private void Form_ReportSaved(object sender, string RDL)
        {
            var rdl = Convert.ToBase64String(Encoding.UTF8.GetBytes(RDL));
            SelectedTemplate.RDL = rdl;
            File.WriteAllText(@"test.rdl", RDL);
            using (var client = new Client<ReportTemplate>())
            {
                client.Save(SelectedTemplate, "Report Saved from Designer");
            }
        }*/
    }
}