using ComPDFKitViewer.PdfViewer;
using Microsoft.Win32;
using PDF_Office.CustomControl;
using PDF_Office.EventAggregators;
using PDF_Office.Views;
using Prism.Commands;
using Prism.Events;
using Prism.Ioc;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using PDF_Office.Model;
using System.ComponentModel;
using PDF_Office.Helper;
using PDFSettings.Settings;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using ComPDFKit.PDFDocument;

namespace PDF_Office.ViewModels
{
    public class MainContentViewModel : BindableBase, INavigationAware
    {
        private string fileName = "Home";

        public string FileName
        {
            get { return fileName; }
            set { SetProperty(ref fileName, value); }
        }

        private string filePath;

        public string FilePath
        {
            get { return filePath; }
            set
            {
                SetProperty(ref filePath, value);
                if (!string.IsNullOrEmpty(filePath))
                {
                    FileName = System.IO.Path.GetFileName(filePath);
                }

            }
        }

        private Visibility fileChanged = Visibility.Collapsed;

        public Visibility FileChanged
        {
            get { return fileChanged; }
            set { SetProperty(ref fileChanged, value); }
        }

        private bool isNewDocument = false;

        public CPDFViewer PDFViewer { get; set; }


        public DelegateCommand<object> CloseTab { get; set; }

        public DelegateCommand<object> Loaded { get; set; }


        private string regionName;

        public string MainContentRegionName
        {
            get { return regionName; }
            set { SetProperty(ref regionName, value); }
        }

        public IRegionManager toolregion;

        public IEventAggregator eventer;

        public IContainerProvider container;

        public IDialogService dialogs;

        public MainContentViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, IContainerProvider containerProvider, IDialogService dialogService)
        {
            toolregion = regionManager;
            eventer = eventAggregator;
            container = containerProvider;
            dialogs = dialogService;

            CloseTab = new DelegateCommand<object>(CloseTabItem);

            MainContentRegionName = Guid.NewGuid().ToString();

            System.Windows.Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send, new Action(() =>
            {
                NavigationParameters parameters = new NavigationParameters
                {
                    {
                        "MainViewModel", this
                    }
                };
                if (toolregion.Regions.ContainsRegionWithName(MainContentRegionName))
                    toolregion.RequestNavigate(MainContentRegionName, "HomeContent", parameters);
            }));
        }

        private void CloseTabItem(object item)
        {
            App.mainWindowViewModel?.CloseTabItem(item);
            App.OpenedFileList.Remove(FilePath);
        }


        /// <summary>
        /// 打开指定路径的PDF文件
        /// </summary>
        /// <param name="filePath"></param>
        public void OpenFile(string filePath)
        {
            var result = LoadFileFormPath(filePath);
            if (!result)
            {
                return;
            }
            FilePath = filePath;

            NavigateToViewContent();

            //检查是否是新文档
            OpenFileInfo isnew = SettingHelper.GetFileInfo(filePath);
            if (isnew == null)
            {
                isNewDocument = true;
                if (App.OpenedFileList.Contains(filePath) == false)
                {
                    App.OpenedFileList.Add(filePath);
                }
         
            }
            //打开文件后，不管是新文件还是旧文件都需要更新排序
            SettingHelper.SortRecentOpenFiles(filePath);
        }

        /// <summary>
        /// 创建PDFviewer对象后导航到ViewContent
        /// </summary>
        private void NavigateToViewContent()
        {
            NavigationParameters parameters = new NavigationParameters {
                { ParameterNames.MainViewModel, this },
                { ParameterNames.PDFViewer,PDFViewer}
            };
            System.Windows.Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send, new Action(() =>
            {
                if (toolregion.Regions.ContainsRegionWithName(MainContentRegionName))
                    toolregion.RequestNavigate(MainContentRegionName, "ViewContent", parameters);
            }));

        }

        /// <summary>
        /// 从文件路径创建PDFViewer对象，已包含文档解密逻辑
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        private bool LoadFileFormPath(string path)
        {
            PDFViewer = new CPDFViewer();
            PDFViewer.InitDocument(path);
            PDFViewer.UndoManager.PropertyChanged += UndoManager_PropertyChanged;
            if (PDFViewer.Document == null)
            {
                //MessageBoxEx.Show(App.MainPageLoader.GetString("Main_OpenFileFailedWarning"));
                return false;
            }
            else
            {
                if (PDFViewer.Document.IsLocked)
                {
                    DialogParameters value = new DialogParameters();
                    value.Add(ParameterNames.PDFDocument, PDFViewer.Document);
                    dialogs.ShowDialog(DialogNames.VerifyPassWordDialog, value, e =>
                    {
                        if (e.Result == ButtonResult.OK)
                        {
                            if (e.Parameters.ContainsKey(ParameterNames.PassWord) && e.Parameters.GetValue<string>(ParameterNames.PassWord) != null)
                            {
                                PDFViewer.Tag = e.Parameters.GetValue<string>(ParameterNames.PassWord).ToString();
                            }
                        }
                    });

                    if (PDFViewer.Document.IsLocked)
                    {
                        //未成功解密文档时，释放Document对象，返回
                        PDFViewer.Document.Release();
                        return false;
                    }
                }
            }

            PDFViewer.Load();

            if (App.mainWindowViewModel != null)
            {
                App.mainWindowViewModel.CurrentPDFViewer = PDFViewer;
            }
            App.OpenedFileList.Add(path);
            return true;
        }

        /// <summary>
        /// 创建文件，路径为空时表示创建空白文档
        /// 否则表示从图片路径创建PDf
        /// </summary>
        /// <param name="imagePath"></param>
        /// <returns></returns>
        public bool CreateFile(string imagePath = null)
        {
            PDFViewer = new CPDFViewer();
            PDFViewer.CreateDocument();
            PDFViewer.UndoManager.PropertyChanged += UndoManager_PropertyChanged;
            if (PDFViewer.Document == null)
            {
                AlertsMessage alertsMessage = new AlertsMessage();
                alertsMessage.ShowDialog("","创建文件失败.","OK");
                return false;
            }

            if (string.IsNullOrEmpty(imagePath))
            {
                FileName = "Blank Page.pdf";
                //默认插入595*842 大小的页面
                PDFViewer.Document.InsertPage(0, 595, 842, null);
            }
            else
            {
                FileName = imagePath.Substring(imagePath.LastIndexOf("\\") + 1, imagePath.LastIndexOf(".") - imagePath.LastIndexOf("\\") - 1) + ".pdf";
                Bitmap pic = new Bitmap(imagePath);
                int width = pic.Size.Width;
                int height = pic.Size.Height;

                string ex = System.IO.Path.GetExtension(imagePath);
                //其他格式或者名称中含空格的图片 在本地先转存一下
                if ((ex != ".jpg" && ex != ".jpeg") || !Uri.IsWellFormedUriString(imagePath, UriKind.Absolute))
                {
                    //将其他格式图片转换成jpg
                    string folderPath = Path.GetTempPath();
                    if (File.Exists(folderPath))
                    {
                        File.Delete(folderPath);
                    }
                    DirectoryInfo tempfolder = new DirectoryInfo(folderPath);
                    if (!tempfolder.Exists)
                    {
                        tempfolder.Create();
                    }
                    string targetPath = System.IO.Path.Combine(folderPath, Guid.NewGuid().ToString());
                    imagePath = targetPath;
                    pic.Save(targetPath, ImageFormat.Jpeg);
                }
                pic.Dispose();

                var result = PDFViewer.Document.InsertPage(0, width, height, imagePath);
                if (!result)
                {
                    AlertsMessage alertsMessage = new AlertsMessage();
                    alertsMessage.ShowDialog("", "创建文件失败.", "OK");
                    return false;
                }
            }

            //设置背景色
            ////PDFViewer.SetBackgroundBrush(new SolidColorBrush((Color)System.Windows.Media.ColorConverter.ConvertFromString(Settings.Default.AppProperties.InitialVIew.Background)));
            PDFViewer.Load();
            PDFViewer.UndoManager.CanSave = true;
            FileChanged = Visibility.Visible;
            PDFViewer.SetFormFieldHighlight(true);

            NavigateToViewContent();
            return true;
        }

        /// <summary>
        /// 从office文件转换成PDF
        /// </summary>
        /// <param name="sourcepath"></param>
        /// <returns></returns>
        public async Task<bool> CreateFileFromOffice(string sourcepath)
        {
            try
            {
                string folderPath = Path.GetTempPath();
                if (File.Exists(folderPath))
                {
                    File.Delete(folderPath);
                }
                DirectoryInfo tempfolder = new DirectoryInfo(folderPath);
                if (!tempfolder.Exists)
                {
                    tempfolder.Create();
                }
                string targetPath = System.IO.Path.Combine(folderPath, Guid.NewGuid().ToString() + ".pdf");

                string ex = System.IO.Path.GetExtension(sourcepath);

                switch (ex)
                {

                    case ".doc":
                    case ".docx":
                    case "docm":
                    case ".dot":
                    case ".dotx":
                    case ".dotm":
                    case ".txt":
                        await Task.Run(() =>
                        {

                            Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();
                            Microsoft.Office.Interop.Word.Document document = null;

                            word.Visible = false;
                            word.ShowWindowsInTaskbar = true;
                            document = word.Documents.Open(sourcepath);
                            document?.ExportAsFixedFormat(targetPath, Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF);
                            document?.Close();
                            word?.Quit();
                        });
                        break;
                    case ".xls":
                    case ".xlsx":
                    case ".xlsm":
                    case ".xlsb":
                    case ".xlam":
                    case ".xltx":
                    case ".xlt":
                        await Task.Run(() =>
                        {
                            Microsoft.Office.Interop.Excel.Application excele = new Microsoft.Office.Interop.Excel.Application();
                            Microsoft.Office.Interop.Excel.Workbook workbook = null;

                            excele.Visible = false;
                            try
                            {
                                workbook = excele.Workbooks.Open(sourcepath);
                            }
                            catch (Exception e)
                            {
                                workbook = excele.Workbooks.Open(sourcepath, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "t", false, false, 0, true, 1, Microsoft.Office.Interop.Excel.XlCorruptLoad.xlRepairFile);
                            }


                            workbook?.ExportAsFixedFormat(Microsoft.Office.Interop.Excel.XlFixedFormatType.xlTypePDF, targetPath);
                            workbook?.Close();
                            excele?.Quit();
                        });
                        break;
                    case ".ppt":
                    case ".pptx":
                    case ".pptm":
                    case ".pptsx":
                    case ".pps":
                    case ".pptsm":
                    case ".pot":
                    case ".potm":
                        await Task.Run(() =>
                        {
                            Microsoft.Office.Interop.PowerPoint.Application ppt = new Microsoft.Office.Interop.PowerPoint.Application();
                            Microsoft.Office.Interop.PowerPoint.Presentation presentation = null;

                            ppt.Visible = Microsoft.Office.Core.MsoTriState.msoCTrue;
                            presentation = ppt.Presentations.Open(sourcepath);

                            presentation.ExportAsFixedFormat(targetPath, Microsoft.Office.Interop.PowerPoint.PpFixedFormatType.ppFixedFormatTypePDF);
                            presentation?.Close();
                            ppt?.Quit();
                        });
                        break;
                }

                PDFViewer = new CPDFViewer();
                PDFViewer.CreateDocument();

                if (PDFViewer.Document == null)
                {
                    AlertsMessage alertsMessage = new AlertsMessage();
                    alertsMessage.ShowDialog("","创建PDF失败","OK");
                    return false;
                }

                FileName = sourcepath.Substring(sourcepath.LastIndexOf("\\") + 1, sourcepath.LastIndexOf(".") - sourcepath.LastIndexOf("\\") - 1) + ".pdf";

                var tempdoc = CPDFDocument.InitWithFilePath(targetPath);
                if (tempdoc == null)
                {
                    AlertsMessage alertsMessage = new AlertsMessage();
                    alertsMessage.ShowDialog("", "创建PDF失败", "OK");
                    return false;
                }

                PDFViewer.Document.ImportPages(tempdoc, "");

                //PDFViewer.SetBackgroundBrush(new SolidColorBrush((Color)System.Windows.Media.ColorConverter.ConvertFromString(Settings.Default.AppProperties.InitialVIew.Background)));
                PDFViewer.Load();
                PDFViewer.UndoManager.CanSave = true;


                return true;
            }
            catch (Exception ex)
            {
                AlertsMessage alertsMessage = new AlertsMessage();
                alertsMessage.ShowDialog("", "没有安装Office", "OK");
                return false;
            }
        }

        private void UndoManager_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "CanSave")
            {
                if (PDFViewer.UndoManager.CanSave)
                {
                    FileChanged = Visibility.Visible;
                }
                else
                {
                    FileChanged = Visibility.Collapsed;
                }

                if (!string.IsNullOrEmpty(PDFViewer.Document.FileName))
                {
                    FileName = PDFViewer.Document.FileName;
                }
            }
        }

        #region Navigation
        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            if (navigationContext.Parameters.Count <= 0)
                return;
            var filepath = navigationContext.Parameters[ParameterNames.FilePath];
            if (filepath != null)
            {
                OpenFile(filepath.ToString());
            }
        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return false;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
        }
        #endregion
    }
}
