using InABox.Core;
using InABox.Wpf;
using NPOI.HPSF;
using System;
using System.IO;
using System.Reactive;
using System.Windows;
using InABox.WPF;
using InABox.Clients;
using System.Linq;
using System.Diagnostics.CodeAnalysis;

namespace InABox.DynamicGrid
{
    /// <summary>
    ///     Interaction logic for DocumentConfirm.xaml
    /// </summary>
    public partial class DocumentConfirm : ThemableWindow
    {
        public DocumentConfirm()
        {
            InitializeComponent();
        }

        public string FileName { get; set; }

        public DateTime LocalTimeStamp { get; set; }
        public DateTime RemoteTimeStamp { get; set; }

        public int LocalSize { get; set; }
        public int RemoteSize { get; set; }

        public DocumentAction Result { get; set; }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Header.Content = string.Format("A file named [{0}] already exists on the server!", FileName);
            NewTimeStamp.Content = string.Format("{0:dd MMM yy HH:mm:ss}", LocalTimeStamp);
            OldTimeStamp.Content = string.Format("{0:dd MMM yy HH:mm:ss}", RemoteTimeStamp);
            OldSize.Content = string.Format("{0:n0}", RemoteSize);
            NewSize.Content = string.Format("{0:n0}", LocalSize);
            Result = DocumentAction.MakeCopy;
        }

        private void ReplaceButton_Click(object sender, RoutedEventArgs e)
        {
            Result = DocumentAction.Replace;
            DialogResult = true;
            Close();
        }

        private void ExistingButton_Click(object sender, RoutedEventArgs e)
        {
            Result = DocumentAction.UseExisting;
            DialogResult = true;
            Close();
        }

        private void MakeCopyButton_Click(object sender, RoutedEventArgs e)
        {
            Result = DocumentAction.MakeCopy;
            DialogResult = true;
            Close();
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = false;
            Close();
        }

        public static Document? CheckDocument(Document newDocument, Func<string, Document?>? findDocument, out bool shouldSave)
        {
            Document? existing = null;
            
            using (new WaitCursor())
                existing = findDocument?.Invoke(newDocument.FileName);
            
            if (existing != null)
            {
                if ((existing.TimeStamp == DateTime.MinValue || existing.TimeStamp.ToString("yyyy-MM-ddThh:mm.ss.fff")
                        .Equals(newDocument.TimeStamp.ToString("yyyy-MM-ddThh:mm.ss.fff"))) && existing.CRC.Equals(newDocument.CRC))
                {
                    if (existing.TimeStamp == DateTime.MinValue)
                    {
                        existing.TimeStamp = newDocument.TimeStamp;
                        shouldSave = true;
                    }
                    else
                    {
                        shouldSave = false;
                    }

                    return existing;
                }
                else
                {
                    var confirm = new DocumentConfirm
                    {
                        FileName = newDocument.FileName,
                        LocalSize = newDocument.Data.Length,
                        RemoteSize = existing.Data.Length,
                        LocalTimeStamp = newDocument.TimeStamp,
                        RemoteTimeStamp = existing.TimeStamp
                    };
                    if (confirm.ShowDialog() == true)
                    {
                        if (confirm.Result == DocumentAction.Replace)
                        {
                            existing.Data = newDocument.Data;
                            existing.TimeStamp = newDocument.TimeStamp;
                            existing.CRC = newDocument.CRC;
                            shouldSave = true;
                            return existing;
                        }
                        else if (confirm.Result == DocumentAction.UseExisting)
                        {
                            shouldSave = false;
                            return existing;
                        }
                        else if (confirm.Result == DocumentAction.MakeCopy)
                        {
                            using (new WaitCursor())
                            {
                                var basefilename = Path.GetFileNameWithoutExtension(newDocument.FileName);
                                var ext = Path.GetExtension(newDocument.FileName);
                                var i = 0;
                                while (existing is not null)
                                {
                                    i++;
                                    newDocument.FileName = Path.ChangeExtension(string.Format("{0} ({1})", basefilename, i), ext);
                                    existing = findDocument?.Invoke(newDocument.FileName);
                                }
                            }
                            shouldSave = true;
                            return newDocument;
                        }
                    }
                }
            }
            else
            {
                shouldSave = true;
                return newDocument;
            }
            shouldSave = false;
            return null;
        }
    }
}