using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using InABox.Core;
using InABox.Wpf;
using InABox.Wpf.Editors;
using InABox.WPF;
using Microsoft.Win32;

namespace InABox.DynamicGrid
{
    public enum DocumentAction
    {
        Replace,
        UseExisting,
        MakeCopy
    }

    public class DocumentEditorControl : DynamicEditorControl<Guid, BaseDocumentEditor>
    {
        
        static DocumentEditorControl()
        {
            //DynamicEditorControlFactory.Register<DocumentEditorControl, BaseDocumentEditor, ImageDocumentEditor>();
            //DynamicEditorControlFactory.Register<DocumentEditorControl, BaseDocumentEditor, PDFDocumentEditor>();
            //DynamicEditorControlFactory.Register<DocumentEditorControl, BaseDocumentEditor, VectorDocumentEditor>();
            //DynamicEditorControlFactory.Register<DocumentEditorControl, BaseDocumentEditor, MiscellaneousDocumentEditor>();
        }
        
        private Document _document = new();

        private TextBox Editor;

        public string Filter { get; set; }

        public override void Configure()
        {
            if (EditorDefinition is not BaseDocumentEditor editor) return;

            Filter = editor.FileMask;
        }

        protected override FrameworkElement CreateEditor()
        {
            var Grid = new Grid
            {
                VerticalAlignment = VerticalAlignment.Stretch,
                HorizontalAlignment = HorizontalAlignment.Stretch
            };
            //Grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(25, GridUnitType.Pixel) });
            Grid.AddColumn(GridUnitType.Star);
            Grid.AddColumn(50);
            Grid.AddColumn(50);
            Grid.AddColumn(50);
            Grid.AddColumn(60);

            Editor = new TextBox
            {
                VerticalAlignment = VerticalAlignment.Stretch,
                VerticalContentAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Stretch,
                Margin = new Thickness(0, 0, 0, 0),
                IsEnabled = false
            };
            //Editor.LostFocus += (o, e) => CheckChanged();
            Grid.AddChild(Editor, 0, 0);

            var Select = new Button
            {
                VerticalAlignment = VerticalAlignment.Stretch,
                VerticalContentAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Stretch,
                Margin = new Thickness(5, 1, 0, 1),
                Content = "Select",
                Focusable = false
            };
            Select.Click += Select_Click;
            Grid.AddChild(Select, 0, 1);

            var Clear = new Button
            {
                VerticalAlignment = VerticalAlignment.Stretch,
                VerticalContentAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Stretch,
                Margin = new Thickness(5, 1, 0, 1),
                Content = "Clear",
                Focusable = false
            };
            Clear.Click += Clear_Click;
            Grid.AddChild(Clear, 0, 2);

            var View = new Button
            {
                VerticalAlignment = VerticalAlignment.Stretch,
                VerticalContentAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Stretch,
                Margin = new Thickness(5, 1, 0, 1),
                Content = "View",
                Focusable = false
            };
            View.Click += View_Click;
            Grid.AddChild(View, 0, 3);

            var rename = new Button
            {
                VerticalAlignment = VerticalAlignment.Stretch,
                VerticalContentAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Stretch,
                Margin = new Thickness(5, 1, 0, 1),
                Content = "Rename",
                Focusable = false
            };
            rename.Click += Rename_Click;
            Grid.AddChild(rename, 0, 4);

            return Grid;
        }

        private void Rename_Click(object sender, RoutedEventArgs e)
        {
            var name = _document.FileName;
            if(TextEdit.Execute("Enter filename:", ref name))
            {
                _document.FileName = name;
                Editor.Text = _document.FileName;
                Host.SaveDocument(_document);
            }
        }

        private void Select_Click(object sender, RoutedEventArgs e)
        {
            var dlg = new OpenFileDialog();
            dlg.Filter = Filter;
            if (dlg.ShowDialog() == true)
            {
                byte[] data = null;
                var filename = Path.GetFileName(dlg.FileName).ToLower();
                var timestamp = new FileInfo(dlg.FileName).LastWriteTime;
                using (new WaitCursor())
                    data = File.ReadAllBytes(dlg.FileName);
                var crc = CoreUtils.CalculateCRC(data);
                
                var newDocument = DocumentConfirm.CheckDocument(new Document
                {
                    FileName = filename,
                    TimeStamp = timestamp,
                    Data = data,
                    CRC = crc
                }, Host.FindDocument, out var shouldSave);
                
                if(newDocument != null)
                {
                    _document = newDocument;
                    if (shouldSave)
                    {
                        using (new WaitCursor())
                            Host.SaveDocument(newDocument);
                    }
                }

                Editor.Text = _document.FileName;
                OtherValues[nameof(Document.FileName)] = _document.FileName;
                CheckChanged();
            }
        }

        private void View_Click(object sender, RoutedEventArgs e)
        {
            if (_document.ID == Guid.Empty)
            {
                MessageWindow.ShowMessage("Please select a document first!", "No document selected");
                return;
            }

            var ext = Path.GetExtension(_document.FileName);
            var filename = Path.ChangeExtension(Path.GetTempFileName(), ext);
            File.WriteAllBytes(filename, _document.Data);

            var gsProcessInfo = new ProcessStartInfo();
            gsProcessInfo.Verb = "open";
            gsProcessInfo.WindowStyle = ProcessWindowStyle.Normal;
            gsProcessInfo.FileName = filename;
            gsProcessInfo.UseShellExecute = true;
            Process.Start(gsProcessInfo);
        }

        private void Clear_Click(object sender, RoutedEventArgs e)
        {
            _document = new Document();
            Editor.Text = "";
            CheckChanged();
        }

        public override int DesiredHeight()
        {
            return 25;
        }

        public override int DesiredWidth()
        {
            return int.MaxValue;
        }

        protected override Guid RetrieveValue()
        {
            return _document.ID;
        }

        protected override void UpdateValue(Guid value)
        {
            if (value != Guid.Empty)
                _document = Host.GetDocument(value) ?? new Document();
            Editor.Text = _document.FileName;
        }

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

        public override void SetColor(Color color)
        {
            Editor.Background = new SolidColorBrush(color);
        }
    }
}