using ComPDFKit.PDFAnnotation;
using ComPDFKit.PDFDocument;
using ComPDFKit.PDFPage;
using ComPDFKitViewer.AnnotEvent;
using ComPDFKitViewer.PdfViewer;
using Microsoft.Win32;
using PDF_Office.Helper;
using PDF_Office.Model;
using PDF_Office.Model.AnnotPanel;
using PDF_Office.Properties;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using static Dropbox.Api.Files.FileCategory;

namespace PDF_Office.ViewModels.PropertyPanel.AnnotPanel
{
    internal class StampAnnotPropertyViewModel : BindableBase, INavigationAware
    {
        #region 标准图章相关默认配置(如果需要修改，要留意按顺序一一对应的，如果要支持多语，Path则需要替换成SDK获取图片的方法，并修改对应参数与实现代码)

        List<string> Path = new List<string>
        {
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/Approved.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/NotApproved.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/Completed.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/Final.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/Draft.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/Confidential.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/ForPublicRelease.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/NotForPublicRelease.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/ForComment.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/Void.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/PreliminaryResults.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/InformationOnly.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/Accepted.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/Rejected.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/Witness.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/InitialHere.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/SignHere.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/revised.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/PrivateMark1.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/PrivateMark2.png",
            "pack://application:,,,/PDF Office;component/Resources/StampIcons/PrivateMark3.png",
        };
        List<string> StampText = new List<string>
        {
            "Approved","NotApproved","Completed","Final","Draft","Confidential","ForPublicRelease","NotForPublicRelease",
            "ForComment","Void","PreliminaryResults","InformationOnly","Accepted","Rejected","Witness","InitialHere","SignHere",
            "revised","PrivateMark#1","PrivateMark#2","PrivateMark#3"
        };
        List<int> MaxWidth = new List<int>
        {
            218,292,234,130,150,280,386,461,282,121,405,366,30,30,133,133,133,173,30,30,30
        };
        List<int> MaxHeight = new List<int>
        {
           66,66,66,66,66,66,66,66,66,66,66,66,30,30,39,39,39,66,30,30,30
        };

        #endregion

        #region 动态图章相关配置(需要支持多语则修改DynamicStampText的内容)

        List<string> DynamicStampText = new List<string>
        {
            "REVISED","REVIEWED","Completed","RECEIVED","APPROVED","CONFIDENTIAL"
        };
        List<C_TEXTSTAMP_COLOR> DynamicColor = new List<C_TEXTSTAMP_COLOR>
        {
          C_TEXTSTAMP_COLOR.TEXTSTAMP_RED,  C_TEXTSTAMP_COLOR.TEXTSTAMP_GREEN,
          C_TEXTSTAMP_COLOR.TEXTSTAMP_GREEN,C_TEXTSTAMP_COLOR.TEXTSTAMP_GREEN,
          C_TEXTSTAMP_COLOR.TEXTSTAMP_GREEN,C_TEXTSTAMP_COLOR.TEXTSTAMP_RED,
        };

        #endregion

        private string author = "12312";

        public string Author
        {
            get { return author; }
            set
            {
                SetProperty(ref author, value);
            }
        }

        private bool isSetAuthor = false;

        public bool IsSetAuthor
        {
            get { return isSetAuthor; }
            set
            {
                SetProperty(ref isSetAuthor, value);
            }
        }

        private int tabControlSelectedIndex = 0;

        public int TabControlSelectedIndex
        {
            get { return tabControlSelectedIndex; }
            set
            {
                SetProperty(ref tabControlSelectedIndex, value);
                if (tabControlSelectedIndex == 0)
                {
                    UnStandard = false;
                }
                else
                {
                    UnStandard = true;
                }
            }
        }

        private int cusListboxIndex=-1;

        public int CusListboxIndex
        {
            get { return cusListboxIndex; }
            set
            {
                SetProperty(ref cusListboxIndex, value);
            }
        }


        
        private bool unStandard;
        /// <summary>
        /// 判断当前是否为非标准图章，控制UI展示
        /// </summary>
        public bool UnStandard
        {
            get { return unStandard; }
            set
            {
                SetProperty(ref unStandard, value);
            }
        }
        /// <summary>
        /// 日期格式
        /// </summary>
        private string dateType = "F";

        private IDialogService dialogs;

        public DelegateCommand ShowDialogCommand { get; set; }

        private CPDFViewer PDFViewer;
        public ObservableCollection<Stamp> StandardStampList { get; set; }
        public ObservableCollection<Stamp> DynamicStampList { get; set; }
        public ObservableCollection<Stamp> CustomStampList { get; set; }

        public StampAnnotPropertyViewModel(IDialogService dialogService)
        {
            dialogs = dialogService;
            StandardStampList = new ObservableCollection<Stamp>();
            DynamicStampList = new ObservableCollection<Stamp>();
            CustomStampList = new ObservableCollection<Stamp>();
            ShowDialogCommand = new DelegateCommand(ShowDialog);
            InitStandardStamp();
            UpDataDynamicStampList();
            LoadSettings();
        }

        /// <summary>
        /// 加载缓存的自定义图章
        /// </summary>
        private void LoadSettings()
        {
            PDFSettings.CustomStampList stamps = Settings.Default.CustomStampList;
            if (stamps != null)
            {
                for (int i = 0; i < stamps.Count; i++)
                {
                    Stamp customStamp = new Stamp();
                    customStamp.Opacity = 1;
                    customStamp.Author = stamps[i].Author;
                    customStamp.StampText = stamps[i].StampText;
                    customStamp.StampTextDate = stamps[i].StampTextDate;
                    customStamp.MaxWidth = stamps[i].ImageWidth;
                    customStamp.MaxHeight = stamps[i].ImageHeight;
                    customStamp.SourcePath = stamps[i].SourcePath;
                    customStamp.Type = stamps[i].Type;
                    customStamp.TextSharp = stamps[i].TextSharp;
                    customStamp.TextColor = stamps[i].TextColor;
                    customStamp.IsCheckedTime = stamps[i].IsCheckedTime;
                    customStamp.IsCheckedDate = stamps[i].IsCheckedDate;
                    CustomStampList.Add(customStamp);
                }
            }
        }

        /// <summary>
        /// 初始化标准图章相关内容
        /// </summary>
        private void InitStandardStamp()
        {
            for (int i = 0; i < Path.Count; i++)
            {
                Stamp standardStamp = new Stamp();
                standardStamp.Author = "";
                standardStamp.Opacity = 1;
                standardStamp.SourcePath = Path[i];
                standardStamp.StampText = StampText[i];
                standardStamp.MaxWidth = MaxWidth[i];
                standardStamp.MaxHeight = MaxHeight[i];
                standardStamp.Type = StampType.STANDARD_STAMP;
                StandardStampList.Add(standardStamp);
            }
        }
        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            return;
        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            navigationContext.Parameters.TryGetValue<CPDFViewer>(ParameterNames.PDFViewer, out PDFViewer);
            if (PDFViewer == null)
            {
                return;
            }
        }

        /// <summary>
        /// 在PDFView上创建图章的统一方法
        /// </summary>
        /// <param name="stamp"></param>
        public void SetStamp(Stamp stamp)
        {
            StampAnnotArgs Args = new StampAnnotArgs();
            Args.StampText = stamp.StampText;
            Args.Author = stamp.Author;
            Args.Opacity = stamp.Opacity;
            if (stamp.Type == StampType.IMAGE_STAMP)
            {

                Args.ImageWidth = stamp.MaxWidth;
                Args.ImageHeight = stamp.MaxHeight;
            }
            else
            {
                Args.MaxWidth = stamp.MaxWidth;
                Args.MaxHeight = stamp.MaxHeight;
            }
            Args.StampTextDate = stamp.StampTextDate;
            Args.TextColor = stamp.TextColor;
            Args.TextSharp = stamp.TextSharp;
            if (!string.IsNullOrEmpty(stamp.SourcePath))
            {
                BitmapImage image = new BitmapImage(new Uri(stamp.SourcePath));
                Args.ImageArray = new byte[image.PixelWidth * image.PixelHeight * 4];
                image.CopyPixels(Args.ImageArray, image.PixelWidth * 4, 0);
                Args.ImageHeight = image.PixelHeight;
                Args.ImageWidth = image.PixelWidth;
            }
            else
            {
                Args.ImageArray = new byte[stamp.ImageSource.PixelWidth * stamp.ImageSource.PixelHeight * 4];
                stamp.ImageSource.CopyPixels(Args.ImageArray, stamp.ImageSource.PixelWidth * 4, 0);
                Args.ImageHeight = stamp.ImageSource.PixelHeight;
                Args.ImageWidth = stamp.ImageSource.PixelWidth;
            }
            Args.Type = stamp.Type;
            PDFViewer.SetMouseMode(MouseModes.AnnotCreate);
            PDFViewer.SetToolParam(Args);
        }

        /// <summary>
        /// 更新动态图章对象相关属性
        /// </summary>
        public void UpDataDynamicStampList()
        {
            CPDFDocument doc = CPDFDocument.CreateDocument();
            bool tt = doc.InsertPage(0, 300, 500, null);
            CPDFPage docPage = doc.PageAtIndex(0);
            CPDFStampAnnotation stampCore = docPage.CreateAnnot(C_ANNOTATION_TYPE.C_ANNOTATION_STAMP) as CPDFStampAnnotation;
            var x = stampCore.GetTextAttribute();
            DynamicStampList.Clear();
            for (int i = 0; i < DynamicStampText.Count; i++)
            {
                string date = "";
                //区分机密（CONFIDENTIAL）和其他动态图章的区别
                if (i < DynamicStampText.Count - 1)
                {
                    date = System.DateTime.Now.ToString(dateType);
                }

                Stamp standardStamp = new Stamp();
                if (IsSetAuthor && !string.IsNullOrEmpty(Author))
                {
                    standardStamp.Author = Author;
                    if (i < DynamicStampText.Count - 1)
                    {
                        standardStamp.StampTextDate = "By " + Author + " at " + date;
                    }
                    else
                    {
                        standardStamp.StampTextDate = Author;
                    }

                }
                else
                {
                    standardStamp.StampTextDate = date;
                    standardStamp.Author = "";
                }

                var bytes = CPDFStampAnnotation.GetTempTextStampImage(DynamicStampText[i], standardStamp.StampTextDate,
                C_TEXTSTAMP_SHAPE.TEXTSTAMP_RECT, DynamicColor[i], out int stampWidth, out int stampHeight, out int width, out int height);
                PixelFormat fmt = PixelFormats.Bgra32;
                BitmapSource bps = BitmapSource.Create(width, height, 96, 96, fmt, null, bytes, (width * fmt.BitsPerPixel + 7) / 8);

                var flags = BindingFlags.NonPublic | BindingFlags.Static;
                var dpiProperty = typeof(SystemParameters).GetProperty("Dpi", flags);
                int Dpi = (int)dpiProperty.GetValue(null, null);

                standardStamp.Opacity = 1;
                standardStamp.SourcePath = "";
                standardStamp.StampText = DynamicStampText[i];
                standardStamp.MaxWidth = (int)DpiHelpers.GetDpiUnrelatedNum(stampWidth / 72D * DpiHelpers.Dpi);
                standardStamp.MaxHeight = (int)DpiHelpers.GetDpiUnrelatedNum(stampHeight / 72D * DpiHelpers.Dpi);
                standardStamp.Type = StampType.TEXT_STAMP;
                standardStamp.ImageSource = bps;
                standardStamp.IsCheckedDate = true;
                standardStamp.IsCheckedTime = true;
                switch (DynamicColor[i])
                {
                    case C_TEXTSTAMP_COLOR.TEXTSTAMP_WHITE:
                        break;
                    case C_TEXTSTAMP_COLOR.TEXTSTAMP_RED:
                        standardStamp.TextColor = TextStampColor.TEXTSTAMP_RED;
                        break;
                    case C_TEXTSTAMP_COLOR.TEXTSTAMP_GREEN:
                        standardStamp.TextColor = TextStampColor.TEXTSTAMP_GREEN;
                        break;
                    case C_TEXTSTAMP_COLOR.TEXTSTAMP_BLUE:
                        break;
                    default:
                        break;
                }
                DynamicStampList.Add(standardStamp);
            }
        }

        /// <summary>
        /// 导出图章
        /// </summary>
        public void SaveToPath(string FileType, Stamp Item)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Title = "保存" + FileType + "文件";
            saveFileDialog.Filter = "（*）|*." + FileType;

            if (saveFileDialog.ShowDialog() == false)
            {
                return;
            }
            BitmapEncoder encoder;
            if (FileType.ToUpper() == "JPG")
            {
                encoder = new JpegBitmapEncoder();
            }
            else
            {
                encoder = new PngBitmapEncoder();
            }
            encoder.Frames.Add(BitmapFrame.Create(new Uri(Item.SourcePath)));
            string path = saveFileDialog.FileName;
            switch (FileType.ToUpper())
            {
                case "PDF":
                    CPDFDocument newDoc = CPDFDocument.CreateDocument();
                    BitmapFrame frame = BitmapFrame.Create(new Uri(Item.SourcePath));
                    byte[] imageData = new byte[frame.PixelWidth * frame.PixelHeight * 4];
                    frame.CopyPixels(imageData, frame.PixelWidth * 4, 0);
                    newDoc.InsertPage(0, frame.PixelWidth, frame.PixelHeight, imageData, CPDFDocumentImageMode.CPDFDocumentImageModeScaleToFill);
                    newDoc.WriteToFilePath(path);
                    break;
                case "PNG":
                    using (FileStream stream = new FileStream(path, FileMode.Create))
                    {
                        encoder.Save(stream);
                    }
                    break;
                default:
                    break;
            }
            System.Diagnostics.Process.Start("explorer", "/select,\"" + path + "\"");
        }

        public void DeleteStamp(Stamp stamp)
        {
            int index = CustomStampList.IndexOf(stamp);
            App.CachePath.AddToDeleteFiles(stamp.SourcePath);
            CustomStampList.RemoveAt(index);
            PDFSettings.CustomStampList stamps = Settings.Default.CustomStampList;
            stamps.RemoveAt(index);
            Settings.Default.Save();
        }

        public void DeleteAll()
        {
            foreach (Stamp item in CustomStampList)
            {
                App.CachePath.AddToDeleteFiles(item.SourcePath);
            }
            CustomStampList.Clear();
            PDFSettings.CustomStampList stamps = Settings.Default.CustomStampList;
            stamps.Clear();
            Settings.Default.Save();
        }
        private void ShowDialog()
        {
            switch (TabControlSelectedIndex)
            {
                case 1:
                    ShowDynamicPropertyDialog();
                    break;
                case 2:
                    ShowCustomCreateDialog(null);
                    break;
                default:
                    break;
            }

        }
        private void ShowDynamicPropertyDialog()
        {
            bool result = true;
            dialogs.ShowDialog(DialogNames.DynamicPropertyDialog, null, e =>
            {
                if (e.Result != ButtonResult.OK)
                {
                    result = false;
                }
                DynamicPropertyDialogViewModel DynamicVM = e.Parameters.GetValue<DynamicPropertyDialogViewModel>(ParameterNames.DataModel);
                if (DynamicVM != null)
                {
                    Author = DynamicVM.Author;
                    IsSetAuthor = DynamicVM.IsChecked;
                    if (Settings.Default.AppProperties.culture == "en-US")
                    {
                        dateType = DynamicVM.SelectedIndex == 0 ? "F" : DynamicVM.DateFormatList[DynamicVM.SelectedIndex] + " HH:mm:ss";
                    }
                    else
                    {
                        dateType = DynamicVM.SelectedIndex == 0 ? "r" : DynamicVM.DateFormatList[DynamicVM.SelectedIndex] + " HH:mm:ss";
                    }
                    UpDataDynamicStampList();
                }
            });
            if (!result)
            {
                return;
            }
        }

        private void ShowCustomCreateDialog(Stamp stamp)
        {
            bool result = true;
            DialogParameters value = new DialogParameters();
            value.Add(ParameterNames.DataModel, stamp);
            dialogs.ShowDialog(DialogNames.CustomCreateDialog, value, e =>
            {
                if (e.Result != ButtonResult.OK)
                {
                    result = false;
                }
                CustomCreateDialogViewModel CustomVM = e.Parameters.GetValue<CustomCreateDialogViewModel>(ParameterNames.DataModel);
                if (CustomVM != null)
                {
                    CreateCustomStamp(CustomVM);
                }
            });
            if (!result)
            {
                return;
            }
        }

        public void EditorCustomStamp(Stamp stamp)
        {
            bool result = true;
            DialogParameters value = new DialogParameters();
            value.Add(ParameterNames.DataModel, stamp);
            dialogs.ShowDialog(DialogNames.CustomCreateDialog, value, e =>
            {
                if (e.Result != ButtonResult.OK)
                {
                    result = false;
                }
                CustomCreateDialogViewModel CustomVM = e.Parameters.GetValue<CustomCreateDialogViewModel>(ParameterNames.DataModel);
                if (CustomVM != null)
                {
                    UpDataCustomStamp(CustomVM, stamp);
                }
            });
            if (!result)
            {
                return;
            }
        }

        private void UpDataCustomStamp(CustomCreateDialogViewModel viewModel, Stamp oldstamp)
        {
            Stamp stamp = new Stamp();
            stamp.Author = "";
            stamp.Opacity = 1;
            stamp.SourcePath = viewModel.SaveToPath;
            stamp.StampText = viewModel.StampText;
            stamp.MaxWidth = (int)DpiHelpers.GetDpiUnrelatedNum(viewModel.StampWidth / 72D * DpiHelpers.Dpi);
            stamp.MaxHeight = (int)DpiHelpers.GetDpiUnrelatedNum(viewModel.StampHeight / 72D * DpiHelpers.Dpi);
            stamp.StampTextDate = viewModel.StampTextDate;
            stamp.Type = viewModel.Type;
            stamp.TextColor = (TextStampColor)(int)viewModel.Color;
            stamp.TextSharp = (TextStampSharp)(int)viewModel.Shape;
            stamp.IsCheckedDate = viewModel.IsCheckedDate;
            stamp.IsCheckedTime = viewModel.IsCheckedTime;
            int index= CustomStampList.IndexOf(oldstamp);
            CustomStampList[index] = stamp;

            PDFSettings.CustomStampList stamps = Settings.Default.CustomStampList;
            if (stamps == null)
            {
                stamps = Settings.Default.CustomStampList = new PDFSettings.CustomStampList();
            }
            PDFSettings.StampAnnote annote = new PDFSettings.StampAnnote();
            Stamp customStamp = new Stamp();
            annote.Author = stamp.Author;
            annote.StampText = stamp.StampText;
            annote.StampTextDate = stamp.StampTextDate;
            annote.ImageWidth = stamp.MaxWidth;
            annote.ImageHeight = stamp.MaxHeight;
            annote.SourcePath = stamp.SourcePath;
            annote.Type = stamp.Type;
            annote.TextSharp = stamp.TextSharp;
            annote.TextColor = stamp.TextColor;
            annote.IsCheckedDate = stamp.IsCheckedDate;
            annote.IsCheckedTime = stamp.IsCheckedTime;
            App.CachePath.AddToDeleteFiles(stamp.SourcePath);
            stamps[index] = annote;
            Settings.Default.Save();
        }

        /// <summary>
        /// 创建自定义图章，并且保存到APP缓存
        /// </summary>
        private void CreateCustomStamp(CustomCreateDialogViewModel viewModel)
        {
            Stamp stamp = new Stamp();
            stamp.Author = "";
            stamp.Opacity = 1;
            if (viewModel.IsRemoveBackground)
            {
                if (!string.IsNullOrEmpty(viewModel.SaveToPath))
                {
                    App.CachePath.AddToDeleteFiles(viewModel.SaveToPath);
                }
                stamp.SourcePath = viewModel.RemoveBackgroundSaveToPath;
            }
            else
            {
                stamp.SourcePath = viewModel.SaveToPath;
            }
         
            stamp.StampText = viewModel.StampText;
            stamp.MaxWidth = (int)DpiHelpers.GetDpiUnrelatedNum(viewModel.StampWidth / 72D * DpiHelpers.Dpi);
            stamp.MaxHeight = (int)DpiHelpers.GetDpiUnrelatedNum(viewModel.StampHeight / 72D * DpiHelpers.Dpi);
            stamp.StampTextDate = viewModel.StampTextDate;
            stamp.Type = viewModel.Type;
            stamp.TextColor = (TextStampColor)(int)viewModel.Color;
            stamp.TextSharp = (TextStampSharp)(int)viewModel.Shape;
            stamp.IsCheckedDate = viewModel.IsCheckedDate;
            stamp.IsCheckedTime = viewModel.IsCheckedTime;
            CustomStampList.Add(stamp);

            //缓存数据
            PDFSettings.CustomStampList stamps = Settings.Default.CustomStampList;
            if (stamps == null)
            {
                stamps = Settings.Default.CustomStampList = new PDFSettings.CustomStampList();
            }
            PDFSettings.StampAnnote annote = new PDFSettings.StampAnnote();
            annote.Author = stamp.Author;
            annote.StampText = stamp.StampText;
            annote.StampTextDate = stamp.StampTextDate;
            annote.ImageWidth = stamp.MaxWidth;
            annote.ImageHeight = stamp.MaxHeight;
            annote.SourcePath = stamp.SourcePath;
            annote.Type = stamp.Type;
            annote.TextSharp = stamp.TextSharp;
            annote.TextColor = stamp.TextColor;
            annote.IsCheckedDate = stamp.IsCheckedDate;
            annote.IsCheckedTime = stamp.IsCheckedTime;
            stamps.Add(annote);
            Settings.Default.Save();

            SetStamp(stamp);
            CusListboxIndex = CustomStampList.Count-1;
        }
    }
}
