using Microsoft.Win32;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComPDFKitViewer.PdfViewer;
using Prism.Regions;
using DryIoc;
using System.Diagnostics;
using Prism.Services.Dialogs;
using PDF_Office.CustomControl;
using PDF_Office.Model;
using System.Windows;
using System.Windows.Controls;
using System.IO;

namespace PDF_Office.ViewModels
{

    public class ViewContentViewModel : BindableBase, INavigationAware
    {
        #region 属性、变量
        private CPDFViewer PDFViewer { get; set; }

        private MainContentViewModel mainViewModel { get; set; }

        public IRegionManager region;

        public IDialogService dialogs;

        public string ViwerRegionName { get; set; }

        public string BOTARegionName { get; set; }

        public string PropertyRegionName { get; set; }

        public string ToolContentRegionName { get; set; }

        public string ToolsBarContentRegionName { get; set; }

        /// <summary>
        /// 是否处于页面编辑模式，用于执行undo redo 的具体操作
        /// </summary>
        public bool isInPageEdit = false;

        public Action PageEditUndo { get; set; }

        public Action PageEditRedo { get; set; }


        private int gridToolRow = 1;
        /// <summary>
        /// 控制ToolContent的Row
        /// </summary>
        public int GridToolRow
        {
            get { return gridToolRow; }
            set
            {
                SetProperty(ref gridToolRow, value);
            }
        }

        private int gridToolRowSpan = 3;
        /// <summary>
        /// 控制ToolContent的RowSpan
        /// </summary>
        public int GridToolRowSpan
        {
            get { return gridToolRowSpan; }
            set
            {
                SetProperty(ref gridToolRowSpan, value);
            }
        }

        private Visibility toolContentVisible = Visibility.Collapsed;
        /// <summary>
        /// 控制Content的显示 用于显示水印、贝茨码、密文等功能模块
        /// 留意：显示前需要先注入内容、设置好行和跨行数
        /// </summary>
        public Visibility ToolContentVisible
        {
            get { return toolContentVisible; }
            set
            {
                SetProperty(ref toolContentVisible, value);
            }
        }

        private Visibility isLoading = Visibility.Collapsed;
        /// <summary>
        /// 是否正在加载中
        /// </summary>
        public Visibility IsLoading
        {
            get { return isLoading; }
            set
            {
                SetProperty(ref isLoading, value);
            }
        }

        private Visibility toolsbarContentVisible = Visibility.Collapsed;
        /// <summary>
        /// 控制ToolsBarContent的显示
        /// 留意：显示前需要先注入内容、设置好行和跨行数
        /// </summary>
        public Visibility ToolsBarContentVisible
        {
            get { return toolsbarContentVisible; }
            set
            {
                SetProperty(ref toolsbarContentVisible, value);
            }
        }

        private bool canSave;
        /// <summary>
        /// 是否可以保存
        /// </summary>
        public bool CanSave
        {
            get { return canSave; }
            set
            {
                SetProperty(ref canSave, value);
            }
        }

        private bool canUndo;

        public bool CanUndo
        {
            get { return canUndo; }
            set
            {
                SetProperty(ref canUndo, value);
            }
        }

        private bool canRedo;

        public bool CanRedo
        {
            get { return canRedo; }
            set
            {
                SetProperty(ref canRedo, value);
            }
        }


        private Dictionary<string, string> regionNameByTabItem;

        private Dictionary<string, string> barContentByTabItem;

        private string previousBar = "";

        private string currentBar = "";

        /// <summary>
        /// 用来避免重复触发导航事件的标志符
        /// </summary>
        private bool isOpenFile = false;

        /// <summary>
        /// 鼠标滚轮缩放的缩放值
        /// </summary>
        private double[] zoomLevel = { 1.00f, 10, 25, 50, 75, 100, 125, 150, 200, 300, 400, 600, 800, 1000 };
        #endregion


        #region 命令
        public DelegateCommand LoadFile { get; set; }

        public DelegateCommand Load { get; set; }

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

        public DelegateCommand SaveFile { get; set; }

        public DelegateCommand SaveAsFile { get; set; }

        public DelegateCommand UndoCommand { get; set; }

        public DelegateCommand RedoCommand { get; set; }
        #endregion

        public ViewContentViewModel(IRegionManager regionManager, IDialogService dialogService)
        {
            region = regionManager;
            dialogs = dialogService;

            LoadFile = new DelegateCommand(loadFile);
            Load = new DelegateCommand(LoadControl);
            SaveFile = new DelegateCommand(()=> { saveFile(); });
            SaveAsFile = new DelegateCommand(() => { saveAsFile(); });
            UndoCommand = new DelegateCommand(Undo);
            RedoCommand = new DelegateCommand(Redo);
            TabControlSelectionChangedCommand = new DelegateCommand<object>(TabControlSelectonChangedEvent);

            ViwerRegionName = Guid.NewGuid().ToString();
            BOTARegionName = Guid.NewGuid().ToString();
            PropertyRegionName = Guid.NewGuid().ToString();

            //未显示时无法注册上Region名称
            ToolContentVisible = Visibility.Visible;
            ToolContentRegionName = Guid.NewGuid().ToString();
            ToolsBarContentRegionName = Guid.NewGuid().ToString();

            ToolContentVisible = Visibility.Collapsed;
            ToolsBarContentVisible = Visibility.Collapsed;
            regionNameByTabItem = new Dictionary<string, string>();
            barContentByTabItem = new Dictionary<string, string>();
            InitialregionNameByTabItem(ref regionNameByTabItem);
            InitialbarContentByTabItem(ref barContentByTabItem);
        }

        private void InitialregionNameByTabItem(ref Dictionary<string, string> dictionary)
        {
            dictionary.Add("TabItemPageEdit", ToolContentRegionName);
            dictionary.Add("TabItemTool", ToolsBarContentRegionName);
            //其他工具菜单栏共用一个ToolsBarContentRegionName
            dictionary.Add("TabItemAnnotation", ToolsBarContentRegionName);
            dictionary.Add("TabItemConvert", ToolsBarContentRegionName);
            dictionary.Add("TabItemScan", ToolsBarContentRegionName);
            dictionary.Add("TabItemEdit", ToolsBarContentRegionName);
            dictionary.Add("TabItemForm", ToolsBarContentRegionName);
            dictionary.Add("TabItemFill", ToolsBarContentRegionName);
        }

        private void InitialbarContentByTabItem(ref Dictionary<string, string> dictionary)
        {
            dictionary.Add("TabItemPageEdit", "PageEditContent");
            dictionary.Add("TabItemTool", "ToolsBarContent");
            dictionary.Add("TabItemAnnotation", "AnnotToolContent");
            dictionary.Add("TabItemConvert", "");
            dictionary.Add("TabItemScan", "");
            dictionary.Add("TabItemEdit", "");
            dictionary.Add("TabItemForm", "");
            dictionary.Add("TabItemFill", "");
        }

        private void UndoManager_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "CanSave")
            {
                CanSave = PDFViewer.UndoManager.CanSave;
            }
            if(e.PropertyName == "CanUndo")
            {
                CanUndo = PDFViewer.UndoManager.CanUndo;
            }
            if(e.PropertyName =="CanRedo")
            {
                CanRedo = PDFViewer.UndoManager.CanRedo;
            }
        }

        /// <summary>
        /// 选项卡切换事件
        /// </summary>
        /// <param name="e"></param>
        private void TabControlSelectonChangedEvent(object e)
        {
            var args = e as SelectionChangedEventArgs;
            if (args != null)
            {
                var item = args.AddedItems[0] as TabItem;
                currentBar = item.Name;
                if (previousBar != currentBar)
                {
                    if(currentBar== "TabItemPageEdit")//如果是页面编辑则进入页面编辑模式
                    {
                        EnterToolMode(barContentByTabItem[currentBar]);
                        isInPageEdit = true;
                    }
                    else//其余情况直接导航至对应的工具栏即可，不需要清空之前的content,region里是单例模式
                    {
                        EnterSelectedBar(currentBar);
                        isInPageEdit = false;
                    }
                    previousBar = currentBar;
                }
            }
        }

        #region PDFViewer鼠标滚轮缩放事件
        public void PdfViewer_MouseWheelZoomHandler(object sender, bool e)
        {
            double newZoom = CheckZoomLevel(PDFViewer.ZoomFactor + (e ? 0.01 : -0.01), e);
            PDFViewer.Zoom(newZoom);
        }

        private double CheckZoomLevel(double zoom, bool IsGrowth)
        {
            double standardZoom = 100;
            if (zoom <= 0.01)
            {
                return 0.01;
            }
            if (zoom >= 10)
            {
                return 10;
            }

            zoom *= 100;
            for (int i = 0; i < zoomLevel.Length - 1; i++)
            {
                if (zoom > zoomLevel[i] && zoom <= zoomLevel[i + 1] && IsGrowth)
                {
                    standardZoom = zoomLevel[i + 1];
                    break;
                }
                if (zoom >= zoomLevel[i] && zoom < zoomLevel[i + 1] && !IsGrowth)
                {
                    standardZoom = zoomLevel[i];
                    break;
                }
            }
            return standardZoom / 100;
        }
        #endregion

        #region Navigate
        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            if (isOpenFile)
                return;

            var mainVM = navigationContext.Parameters[ParameterNames.MainViewModel] as MainContentViewModel;
            if (mainVM != null)
            {
                mainViewModel = mainVM;
            }
            var pdfview = navigationContext.Parameters[ParameterNames.PDFViewer] as CPDFViewer;
            if (pdfview != null)
            {
                PDFViewer = pdfview;
                loadFile();
            }


            isOpenFile = true;
        }

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

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {

        }
        #endregion

        #region 方法
        private void Undo()
        {
            if(isInPageEdit)
            {
                //执行页面编辑的Undo
                PageEditUndo?.Invoke();
            }
            else
            {
                PDFViewer.UndoManager.Undo();
            }
        }

        private void Redo()
        {
            if(isInPageEdit)
            {
                //执行页面编辑的Redo
                PageEditRedo?.Invoke();
            }
            else
            {
                PDFViewer.UndoManager.Redo();
            }
        }

        private void LoadControl()
        {
            //在构造函数中使用Region需要借助Dispatcher 确保UI已经加载完成,加载BOTA区域
            System.Windows.Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send, new Action(() =>
            {
                NavigationParameters parameters = new NavigationParameters();
                parameters.Add(ParameterNames.PDFViewer, PDFViewer);
                parameters.Add(ParameterNames.ViewContentViewModel, this);
                region.RequestNavigate(BOTARegionName, "BOTAContent",parameters);
            }
            ));
        }

        /// <summary>
        /// 将PDFViwer添加到Region
        /// </summary>
        private void loadFile()
        {
            PDFViewer.MouseWheelZoomHandler += PdfViewer_MouseWheelZoomHandler;
            PDFViewer.UndoManager.PropertyChanged += UndoManager_PropertyChanged;
            CanSave = PDFViewer.UndoManager.CanSave;
            CanUndo = PDFViewer.UndoManager.CanUndo;
            CanRedo = PDFViewer.UndoManager.CanRedo;
            region.AddToRegion(ViwerRegionName, PDFViewer);
        }

        /// <summary>
        /// 已有路径文档的保存逻辑
        /// </summary>
        private bool saveFile()
        {
            try
            {
                if (string.IsNullOrEmpty(PDFViewer.Document.FilePath))
                    return saveAsFile();

                //文档已被修复时 提示另存为
                if (PDFViewer.Document.HasRepaired)
                {
                    AlertsMessage alertsMessage = new AlertsMessage();
                    alertsMessage.ShowDialog("", "文件已被修复，建议另存为", "Cancel", "OK");
                    if (alertsMessage.result == ContentResult.Ok)
                        return saveAsFile();
                    else
                        return false;
                }

                //文件路径无法存在时
                if (!File.Exists(PDFViewer.Document.FilePath))
                {
                    AlertsMessage alertsMessage = new AlertsMessage();
                    alertsMessage.ShowDialog("", "文件路径不存在，需要另存为", "Cancel", "OK");
                    if (alertsMessage.result == ContentResult.Ok)
                        return saveAsFile();
                    else
                        return false;
                }

                //只读文件无法写入时，提示另存为
                FileInfo fileInfo = new FileInfo(PDFViewer.Document.FilePath);
                if (fileInfo.IsReadOnly)
                {
                    AlertsMessage alertsMessage = new AlertsMessage();
                    alertsMessage.ShowDialog("", "文件为只读文件，需要另存为", "Cancel", "OK");
                    if (alertsMessage.result == ContentResult.Ok)
                        return saveAsFile();
                    else
                        return false;
                }

                bool result = PDFViewer.Document.WriteToLoadedPath();
                if (result)
                {
                    PDFViewer.UndoManager.CanSave = false;
                    App.Current.Dispatcher.Invoke(() =>
                    {
                        //TODO:更新缩略图
                        //OpenFileInfo info = SettingHelper.GetFileInfo(PdfViewer.Document.FilePath);
                        //try
                        //{
                        //    if (!string.IsNullOrEmpty(info.ThumbImgPath) && !PdfViewer.Document.IsEncrypted)//加密的文档不获取缩略图
                        //    {
                        //        var size = PdfViewer.Document.GetPageSize(0);
                        //        System.Drawing.Bitmap bitmap = ToolMethod.RenderPageBitmapNoWait(PdfViewer.Document, (int)size.Width, (int)size.Height, 0, true, true);
                        //        string folderPath = System.IO.Path.Combine(App.CurrentPath, "CoverImage");
                        //        if (File.Exists(folderPath))
                        //            File.Delete(folderPath);
                        //        DirectoryInfo folder = new DirectoryInfo(folderPath);
                        //        if (!folder.Exists)
                        //            folder.Create();
                        //        string imagePath = info.ThumbImgPath;
                        //        if (!File.Exists(imagePath))//由加密文档变为非加密文档时 新建一个路径
                        //        {
                        //            string imageName = Guid.NewGuid().ToString();
                        //            imagePath = System.IO.Path.Combine(folderPath, imageName);
                        //            using (FileStream stream = new FileStream(imagePath, FileMode.Create))
                        //            {
                        //                bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                        //            }
                        //        }
                        //        else
                        //        {
                        //            using (FileStream stream = new FileStream(imagePath, FileMode.Open))
                        //            {
                        //                bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                        //            }
                        //        }
                        //        info.ThumbImgPath = imagePath;
                        //        SettingHelper.SetFileInfo(info);
                        //    }
                        //}
                        //catch
                        //{
                        //    info.ThumbImgPath = null;
                        //    SettingHelper.SetFileInfo(info);
                        //}
                    });
                }
                else
                {
                    //文件被占用 保存失败时
                    AlertsMessage alertsMessage = new AlertsMessage();
                    alertsMessage.ShowDialog("", "文件被占用，需要另存为", "Cancel", "OK");
                    if (alertsMessage.result == ContentResult.Ok)
                        return saveAsFile();
                    else
                        return false;
                }

                return result;
            }
            catch { return false; }
        }

        /// <summary>
        /// 另存为或新文档保存逻辑
        /// </summary>
        private bool saveAsFile()
        {
            var dlg = new SaveFileDialog();
            dlg.Filter = Properties.Resources.OpenDialogFilter;
            dlg.FileName = PDFViewer.Document.FileName;
            if (dlg.ShowDialog() == true && !string.IsNullOrEmpty(dlg.FileName))
            {
                bool result = false;
                if (App.OpenedFileList.Contains(dlg.FileName))
                {
                    //提示文件已经被打开
                }
                else
                {
                    result = PDFViewer.Document.WriteToFilePath(dlg.FileName);
                    if (result)
                    {
                        DoAfterSaveAs(dlg.FileName);
                    }
                    else
                    {
                        //提示文件被其他软件占用 无法保存
                        //MessageBoxEx.Show(App.MainPageLoader.GetString("Main_TheFileOccupiedWarning"), "", Winform.MessageBoxButtons.OKCancel, new string[] { App.MainPageLoader.GetString("Main_SaveAs"), App.MainPageLoader.GetString("Main_Cancel") })
                    }
                      ;
                }
                return result;
            }
            else
                return false;
        }

        /// <summary>
        /// 另存为后进行的操作
        /// 重新打开新文档
        /// </summary>
        /// <param name="targetPath"></param>
        public void DoAfterSaveAs(string targetPath)
        {
            App.OpenedFileList.Remove(targetPath);
            string oldFilePath = targetPath;

            PDFViewer.UndoManager.CanSave = false;

            mainViewModel.OpenFile(targetPath);
            //TODO：通知各模块更新PDFview对象
            //var result = OpenFile(targetPath, true);

            //if (result)
            //{
            //    FileChanged.Invoke(this, null);
            //    Zoomer.PdfViewer = PdfViewer;
            //    PageSelector.PdfViewer = PdfViewer;
            //    ViewModeSelector.PdfViewer = PdfViewer;

            //    OpenFileInfo fileInfo = SettingHelper.GetFileInfo(oldFilePath);
            //    if (fileInfo != null)
            //    {
            //        PdfViewer.ChangeViewMode(fileInfo.LastViewMode);
            //        PdfViewer.ChangeFitMode(fileInfo.LastFitMode);
            //        if (fileInfo.LastFitMode == FitMode.FitFree)
            //            PdfViewer.Zoom(fileInfo.LastZoom);

            //        PdfViewer.GoToPage(fileInfo.LastPageIndex);
            //        if (fileInfo.LastDrawMode == DrawModes.Draw_Mode_Custom && fileInfo.LastFillColor != 0)
            //            PdfViewer.SetDrawMode(fileInfo.LastDrawMode, fileInfo.LastFillColor);
            //        else
            //            PdfViewer.SetDrawMode(fileInfo.LastDrawMode);
            //    }
            //}
        }

        /// <summary>
        /// 显示前添加内容到Region
        /// </summary>
        /// <param name="isPageEdit"></param>
        private void ShowContent(string currentBar,bool isToolMode=false)
        {
            //显示页面编辑或其他工具
            if (currentBar == "TabItemPageEdit"||isToolMode)
            {
                if (currentBar == "TabItemPageEdit")//进入页面编辑
                {
                    if (GridToolRow != 1)
                    {
                        GridToolRow = 1;
                    }

                    if (GridToolRowSpan != 3)
                    {
                        GridToolRowSpan = 3;
                    }
                }
                else//进入水印等其他工具模式
                {
                    if (GridToolRow != 0)
                    {
                        GridToolRow = 0;
                    }

                    if (GridToolRowSpan != 4)
                    {
                        GridToolRowSpan = 4;
                    }
                }
                //ToolContent的visible跟toolsbarContent 的visible是互斥的
                ToolContentVisible = Visibility.Visible;
                ToolsBarContentVisible = Visibility.Collapsed;
            }
            else
            {
                if (GridToolRow != 1)
                {
                    GridToolRow = 1;
                }
                ToolContentVisible = Visibility.Collapsed;
                ToolsBarContentVisible = Visibility.Visible;
            }
        }

        /// <summary>
        /// 进入工具编辑(如页面编辑、水印、密文等)模式
        /// </summary> 
        /// <param name="targetToolMode">要导航过去的控件名称</param>
        /// <param name="valuePairs">导航需要传送的参数，为空时，默认传送PDFView和ViewContentViewModel</param>
        private async void EnterToolMode(string targetToolMode, NavigationParameters valuePairs = null)
        {
            IsLoading = Visibility.Visible;
            await Task.Delay(3);
            NavigationParameters param = new NavigationParameters();
            if (valuePairs == null)
            {
                param.Add(ParameterNames.PDFViewer, PDFViewer);
                param.Add(ParameterNames.ViewContentViewModel, this);
            }
            else//有传入其他内容的参数时
            {
                param = valuePairs;
            }
            region.RequestNavigate(ToolContentRegionName, targetToolMode, param);
            ShowContent(currentBar,true);

            IsLoading = Visibility.Collapsed;
        }

        private void EnterSelectedBar(string currentBar)
        {
            NavigationParameters param = new NavigationParameters();
            param.Add(ParameterNames.PDFViewer, PDFViewer);
            param.Add(ParameterNames.ViewContentViewModel, this);
            region.RequestNavigate(regionNameByTabItem[currentBar], barContentByTabItem[currentBar], param);
            ShowContent(currentBar);
        }

        /// <summary>
        /// 退出工具(水印、密文等)编辑模式，隐藏ToolContent
        /// </summary>
        public void ExitToolMode()
        {
            ToolContentVisible = Visibility.Collapsed;
        }
        #endregion
    }
}



