using Compdfkit_Tools.PDFControl;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.IO;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Dragablz;
using Compdfkit_Tools.Helper;
using ComPDFKitViewer;
using ComPDFKit.PDFDocument;

namespace PDFViewer
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region Property
        private PDFViewControl passwordViewer;
        private PDFViewControl pdfViewControl = new PDFViewControl();
        private string[] oldAndNewFilePath;

        #endregion

        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded; ;

        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            PasswordUI.Closed -= PasswordUI_Closed;
            PasswordUI.Canceled -= PasswordUI_Canceled;
            PasswordUI.Confirmed -= PasswordUI_Confirmed;
            PasswordUI.Confirmed += PasswordUI_Confirmed;
            PasswordUI.Canceled += PasswordUI_Canceled;
            PasswordUI.Closed += PasswordUI_Closed;

            if (App.DefaultPDFLoaded == false)
            {
                LoadDefaultDocument();
                App.DefaultPDFLoaded = true;
            }
        }

        private void LoadDefaultDocument()
        {
            string defaultFilePath = "PDF32000_2008.pdf";
            TabControlLoadDocument(defaultFilePath);
        }


        private void TabControlLoadDocument(string filePath)
        {
            if (App.OpenedFilePathList.Contains(filePath))
            {
                for (int i = 0; i < App.Current.Windows.Count; i++)
                {
                    MainWindow win = App.Current.Windows[i] as MainWindow;
                    if (win != null)
                    {
                        var items = win.TabControl.Items;

                        foreach (TabItemExt item in items)
                        {
                            if (item.Tag.ToString().ToLower() == filePath.ToLower())
                            {
                                win.Activate();
                                item.IsSelected = true;
                                return;
                            }
                        }
                    }
                }
            }

            TabItemExt tabItem = new TabItemExt();
            MainPage viewPage = new MainPage();

            viewPage.CheckExistBeforeOpenFileEvent -= ViewPage_CheckExistBeforeOpenFileEvent;
            viewPage.FileChangeEvent -= ViewPage_FileChangeEvent;
            viewPage.CheckExistBeforeOpenFileEvent += ViewPage_CheckExistBeforeOpenFileEvent;
            viewPage.FileChangeEvent += ViewPage_FileChangeEvent;

            passwordViewer = new PDFViewControl();
            passwordViewer.InitDocument(filePath);
            if (passwordViewer != null && passwordViewer.PDFViewTool != null)
            {
                CPDFViewer tempViewer = passwordViewer.PDFViewTool.GetCPDFViewer();
                CPDFDocument pdfDoc = tempViewer?.GetDocument();
                if (pdfDoc == null)
                {
                    MessageBox.Show("Open File Failed");
                    return;
                }

                if (pdfDoc.IsLocked)
                {
                    PasswordUI.SetShowText(System.IO.Path.GetFileName(filePath) + " password encrypted.");
                    PasswordUI.ClearPassword();
                    PopupBorder.Visibility = Visibility.Visible;
                    PasswordUI.Visibility = Visibility.Visible;
                }
                else
                {
                    viewPage.InitWithFilePath(filePath);
                    tabItem.Content = viewPage;
                    tabItem.IsSelected = true;
                    tabItem.FileName = Path.GetFileName(filePath);
                    tabItem.Tag = filePath;

                    App.OpenedFilePathList.Add(filePath);
                    TabControl.Items.Add(tabItem);
                }
            }
        }

        private void PasswordUI_Closed(object sender, EventArgs e)
        {
            PopupBorder.Visibility = Visibility.Collapsed;
            PasswordUI.Visibility = Visibility.Collapsed;
        }

        private void PasswordUI_Canceled(object sender, EventArgs e)
        {
            PopupBorder.Visibility = Visibility.Collapsed;
            PasswordUI.Visibility = Visibility.Collapsed;
        }

        private void PasswordUI_Confirmed(object sender, string e)
        {
            if (passwordViewer != null && passwordViewer.PDFViewTool != null)
            {
                CPDFViewer tempViewer=passwordViewer.PDFViewTool.GetCPDFViewer();
                CPDFDocument pdfDoc=tempViewer?.GetDocument();
                if(pdfDoc==null)
                {
                    return;
                }

                pdfDoc.UnlockWithPassword(e);
                if (pdfDoc.IsLocked == false)
                {
                    PasswordUI.SetShowError("", Visibility.Collapsed);
                    PasswordUI.ClearPassword();
                    PasswordUI.Visibility = Visibility.Collapsed;
                    PopupBorder.Visibility = Visibility.Collapsed;
                    pdfViewControl = passwordViewer;

                    string filePath = pdfDoc.FilePath;
                    TabItemExt tabItem = new TabItemExt();
                    MainPage viewPage = new MainPage();

                    tabItem.Content = viewPage;
                    tabItem.IsSelected = true;
                    tabItem.FileName = Path.GetFileName(filePath);
                    tabItem.Tag = filePath;

                    viewPage.SetPDFViewer(pdfViewControl);
                    App.OpenedFilePathList.Add(filePath);

                    TabControl.Items.Add(tabItem);
                }
                else
                {
                    PasswordUI.SetShowError("error", Visibility.Visible);
                }
            }

        }


        private void ViewPage_FileChangeEvent(object sender, EventArgs e)
        {
            for (int i = 0; i < App.Current.Windows.Count; i++)
            {
                MainWindow win = App.Current.Windows[i] as MainWindow;
                if (win != null)
                {
                    var items = win.TabControl.Items;

                    foreach (TabItemExt item in items)
                    {
                        if (item.Tag.ToString().ToLower() == oldAndNewFilePath[1].ToLower())
                        {
                            item.IsSelected = true;
                            item.FileName = Path.GetFileName(oldAndNewFilePath[0]);
                            item.IsSelected = true;
                            item.Tag = oldAndNewFilePath[0];
                        }
                    }
                }
            }

            for (int i = 0; i < App.OpenedFilePathList.Count; i++)
            {
                if (oldAndNewFilePath[1].ToLower() == App.OpenedFilePathList[i].ToLower())
                {
                    App.OpenedFilePathList[i] = oldAndNewFilePath[0];
                    break;
                }
            }
        }

        private bool ViewPage_CheckExistBeforeOpenFileEvent(string[] arg)
        {

            if (App.OpenedFilePathList.Contains(arg[0]))
            {
                for (int i = 0; i < App.Current.Windows.Count; i++)
                {
                    MainWindow win = App.Current.Windows[i] as MainWindow;
                    if (win != null)
                    {
                        var items = win.TabControl.Items;

                        foreach (TabItemExt item in items)
                        {
                            if (item.Tag.ToString().ToLower() == arg[0].ToLower())
                            {
                                win.Activate();
                                item.IsSelected = true;
                                return true;
                            }
                        }
                    }
                }
            }
            oldAndNewFilePath = arg;
            return false;
        }

        public class TabItemExt : TabItem, INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            private string _fileName;
            public string FileName
            {
                get
                {
                    return _fileName;
                }
                set
                {
                    if (_fileName != value)
                    {
                        _fileName = value;
                        OnPropertyChanged();
                    }
                }
            }

            private Visibility _fileChanged = Visibility.Hidden;

            public Visibility FileChanged
            {
                get
                {
                    return _fileChanged;
                }
                set
                {
                    if (_fileChanged != value)
                    {
                        _fileChanged = value;
                        OnPropertyChanged();
                    }
                }
            }

            public void OnPropertyChanged([CallerMemberName] string name = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
            }
        }

        private DragablzItem FindParentDragablzItem(DependencyObject element)
        {
            while (element != null && !(element is DragablzItem))
            {
                element = VisualTreeHelper.GetParent(element);
            }

            return element as DragablzItem;
        }

        private TabControl FindParentTabControl(DependencyObject element)
        {
            while (element != null && !(element is TabControl))
            {
                element = VisualTreeHelper.GetParent(element);
            }

            return element as TabControl;
        }

        private void CloseFileButton_Click(object sender, RoutedEventArgs e)
        {
            var button = sender as Button;
            var dragablzItem = FindParentDragablzItem(button);
            var tabControl = FindParentTabControl(dragablzItem);
            MainPage mainPage = (dragablzItem.Content as TabItemExt).Content as MainPage;

            if (mainPage.CanSave)
            {
                string fileName = (dragablzItem.Content as TabItemExt).FileName;
                var message = string.Format("Do you want to save the changes in {0}?", fileName);
                var result = MessageBox.Show(message, "Alert", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);

                if (result == MessageBoxResult.Yes)
                {
                    mainPage.SaveFile();
                    App.OpenedFilePathList.Remove((dragablzItem.Content as TabItemExt).Tag.ToString());
                    tabControl.Items.Remove(dragablzItem.Content);

                }
                else if (result == MessageBoxResult.No)
                {
                    App.OpenedFilePathList.Remove((dragablzItem.Content as TabItemExt).Tag.ToString());
                    tabControl.Items.Remove(dragablzItem.Content);
                }
                else
                {

                }
            }
            else
            {
                App.OpenedFilePathList.Remove((dragablzItem.Content as TabItemExt).Tag.ToString());
                tabControl.Items.Remove(dragablzItem.Content);
            }

            if (tabControl.Items.Count == 0)
            {
                SystemCommands.CloseWindow(this);
            }
        }

        private void DefaultAddButton_Click(object sender, RoutedEventArgs e)
        {
            string filePath = CommonHelper.GetExistedPathOrEmpty();
            if (filePath != string.Empty)
            {
                TabControlLoadDocument(filePath);
            }
        }

        private void MinimizeButton_Click(object sender, RoutedEventArgs e)
        {
            SystemCommands.MinimizeWindow(this);
        }

        private void MaximizeRestoreButton_Click(object sender, RoutedEventArgs e)
        {
            if (this.WindowState == WindowState.Maximized)
            {
                SystemCommands.RestoreWindow(this);
            }
            else
            {
                SystemCommands.MaximizeWindow(this);
            }
        }

        private void CloseButton_Click(object sender, RoutedEventArgs e)
        {
            int count = TabControl.Items.Count;
            while (count > 0)
            {
                TabItemExt item = TabControl.Items[0] as TabItemExt;

                MainPage mainPage = item.Content as MainPage;
                if (mainPage.CanSave)
                {
                    string fileName = item.FileName;
                    var message = string.Format("Do you want to save the changes in {0}?", fileName);
                    var result = MessageBox.Show(message, "Alert", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);

                    if (result == MessageBoxResult.Yes)
                    {
                        mainPage.SaveFile();
                        App.OpenedFilePathList.Remove(item.Tag.ToString());
                        TabControl.Items.Remove(item);
                        count--;
                    }
                    else if (result == MessageBoxResult.No)
                    {
                        App.OpenedFilePathList.Remove(item.Tag.ToString());
                        TabControl.Items.Remove(item);
                        count--;
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    App.OpenedFilePathList.Remove(item.Tag.ToString());
                    TabControl.Items.Remove(item);
                    count--;
                }
            }

            if (count == 0)
            {
                SystemCommands.CloseWindow(this);
            }
        }
    }
}
