using ComPDFKit.PDFDocument;
using ComPDFKit.PDFPage;
using ComPDFKitViewer.PdfViewer;
using PDF_Office.EventAggregators;
using PDF_Office.Helper;
using PDF_Office.Model;
using PDF_Office.Model.EditTools.Background;
using PDF_Office.Model.EditTools.Watermark;
using PDF_Office.Properties;
using PDFSettings;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using static PDF_Office.Model.Dialog.ToolsDialogs.SaftyDialogs.DeleteSafetySettintgsModel;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrayNotify;

namespace PDF_Office.ViewModels.EditTools.Background
{
    public class BackgroundCreateFileContentViewModel : BindableBase, INavigationAware
    {
        IEventAggregator eventAggregator;
        IDialogService dialogs;
        private BackgroundItem TemplateBackgroundItem;

        public BackgroundInfo BackgroundInfo = new BackgroundInfo();
        private CPDFViewer PDFViewer;

        private List<string> _rotationList = new List<string>();
        public List<string> RotationList
        {
            get { return _rotationList; }
            set { SetProperty(ref _rotationList, value); }
        }

        private List<string> _opacityList = new List<string>();
        public List<string> OpacityList
        {
            get { return _opacityList; }
            set
            {
                SetProperty(ref _opacityList, value);
            }
        }

        private List<string> _relativeRatioList = new List<string>();
        public List<string> RelativeRatioList
        {
            get { return _relativeRatioList; }
            set
            {
                SetProperty(ref _relativeRatioList, value);
            }
        }

        private int _rotationValue = 0;
        public int RotationValue
        {
            get { return _rotationValue; }
            set
            {
                SetProperty(ref _rotationValue, value);
                BackgroundInfo.Rotation = value;
                eventAggregator.GetEvent<SetBackgroundEvent>().Publish(new BackgroundInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BackgroundInfo
                });
            }
        }


        private int _opacityValue = 100;
        public int OpacityValue
        {
            get { return _opacityValue; }
            set
            {
                SetProperty(ref _opacityValue, value);
                BackgroundInfo.Opacity = (byte)(value);
                eventAggregator.GetEvent<SetBackgroundEvent>().Publish(new BackgroundInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BackgroundInfo
                });
            }
        }

        private int _relativeRatioValue = 50;
        public int RelativeRatioValue
        {
            get { return _relativeRatioValue; }
            set
            {
                SetProperty(ref _rotationValue, value);
                BackgroundInfo.Scale = value;
                eventAggregator.GetEvent<SetBackgroundEvent>().Publish(new BackgroundInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BackgroundInfo
                });
            }
        }

        private string _verticalOffsetValue = "0";
        public string VerticalOffsetValue
        {
            get { return _verticalOffsetValue; }
            set
            {
                SetProperty(ref _verticalOffsetValue, value);
                BackgroundInfo.VertOffset = float.Parse(VerticalOffsetValue);
                eventAggregator.GetEvent<SetBackgroundEvent>().Publish(new BackgroundInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BackgroundInfo
                });
            }
        }

        private string _relativeScaleText = "50 %";
        public string RelativeScaleText
        {
            get { return _relativeScaleText; }
            set
            {
                SetProperty(ref _relativeScaleText, value);
                eventAggregator.GetEvent<SetBackgroundEvent>().Publish(new BackgroundInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BackgroundInfo
                });
            }
        }


        private string _horizOffsetValue = "0";
        public string HorizontalOffsetValue
        {
            get { return _horizOffsetValue; }
            set
            {
                SetProperty(ref _horizOffsetValue, value);
                BackgroundInfo.HorizOffset = float.Parse(HorizontalOffsetValue);
                eventAggregator.GetEvent<SetBackgroundEvent>().Publish(new BackgroundInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BackgroundInfo
                });
            }
        }

        private string _rotationText = "0";
        public string RotationText
        {
            get { return _rotationText; }
            set
            {
                SetProperty(ref _rotationText, value);
            }
        }

        private string _opacityText = "100 %";
        public string OpacityText
        {
            get { return _opacityText; }
            set
            {
                SetProperty(ref _opacityText, value);

            }
        }

        private ObservableDictionary<string, bool> _getLocationFromNumber = new ObservableDictionary<string, bool>();
        public ObservableDictionary<string, bool> GetLocationFromNumber
        {
            get { return _getLocationFromNumber; }
        }

        private string _fileNameText = "";
        public string FileNameText
        {
            get { return _fileNameText; }
            set
            {
                SetProperty(ref _fileNameText, value);
            }
        }

        private bool isFirstEnter = true;
        public bool IsFirstEnter
        {
            get => isFirstEnter;
            set => isFirstEnter = value;
        }

        private Visibility _createModFileVisible = Visibility.Collapsed;
        public Visibility CreateModFileVisible
        {
            get => _createModFileVisible;
            set => SetProperty(ref _createModFileVisible, value);
        }

        private bool _isRelativeScaleValue = true;
        public bool IsRelativeScaleValue
        {
            get { return _isRelativeScaleValue; }
            set
            {
                SetProperty(ref _isRelativeScaleValue, value);
                BackgroundInfo.IsRelativeScale = IsRelativeScaleValue;
                eventAggregator.GetEvent<SetBackgroundEvent>().Publish(new BackgroundInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BackgroundInfo
                });
            }
        }



        public DelegateCommand OpenFileCommand { get; set; }
        public DelegateCommand<object> ChangeLocationCommand { get; set; }

        public string unicode = null;
        public string Unicode = null;

        public BackgroundCreateFileContentViewModel(IEventAggregator eventAggregator, IDialogService dialogService)
        {
            this.eventAggregator = eventAggregator;
            this.dialogs = dialogService;
            Unicode = App.mainWindowViewModel.SelectedItem.Unicode;
            BackgroundInfo.BackgroundType = C_Background_Type.BG_TYPE_IMAGE;
            ChangeLocationCommand = new DelegateCommand<object>(ChangeLocation);
            InitComponent();
            BackgroundInfo.Horizalign = C_Background_Horizalign.BG_HORIZALIGN_CENTER;
            BackgroundInfo.Vertalign = C_Background_Vertalign.BG_VERTALIGN_CENTER;
            InitLocationButtonMatrix();
            OpenFileCommand = new DelegateCommand(OpenFile);
            eventAggregator.GetEvent<SaveBackgroundTemplateEvent>().Subscribe(SaveBackgroundTemplate, e => e.Unicode == Unicode);
            eventAggregator.GetEvent<ConfirmEditBackgroundTemplateItemEvent>().Subscribe(ConfirmEditBackgroundTemplateItem, e => e.Unicode == Unicode);


        }

        public string _pageRangeText { get; set; } = "0";
        public string PageRangeText
        {
            get { return _pageRangeText; }
            set
            {
                _pageRangeText = value;
                BackgroundInfo.PageRange=PageRangeText;
                eventAggregator.GetEvent<SetBackgroundEvent>().Publish(new BackgroundInfoUnicode { Unicode=Unicode,Status=BackgroundInfo});
            }
        }

        private int maxPageRange = 0;
        public int MaxPageRange
        {
            get { return maxPageRange; }
            set
            {
                SetProperty(ref maxPageRange, value);
            }
        }

        private int _pageRangeSelectIndex = 0;
        public int PageRangeSelectIndex
        {
            get { return _pageRangeSelectIndex; }
            set
            {
                SetProperty(ref _pageRangeSelectIndex, value);
                BackgroundInfo.PageRangeIndex = PageRangeSelectIndex;
                eventAggregator.GetEvent<SetBackgroundEvent>().Publish(new BackgroundInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BackgroundInfo
                });
            }
        }


        public void InitComponent()
        {
            InitOpacityList();
            InitRotationList();
            InitRelativeRatioList();
        }

        private void InitRotationList()
        {
            RotationList.Clear();
            for (int defaultRotation = -45; defaultRotation <= 45; defaultRotation += 15)
            {
                RotationList.Add(defaultRotation.ToString());
            }
        }

        private void InitOpacityList()
        {
            OpacityList.Clear();
            for (int defaultOpacity = 10; defaultOpacity <= 100; defaultOpacity += 10)
            {
                OpacityList.Add(defaultOpacity.ToString() + " %");
            }
        }

        private void InitRelativeRatioList()
        {
            RelativeRatioList.Clear();
            for (int defaultRelativeRatioList = 10; defaultRelativeRatioList <= 100; defaultRelativeRatioList += 10)
            {
                RelativeRatioList.Add(defaultRelativeRatioList.ToString() + " %");
            }
        }

        private void InitLocationButtonMatrix()
        {
            GetLocationFromNumber.Clear();
            for (var temp = 0; temp <= 22; temp++)
            {
                GetLocationFromNumber.Add(temp.ToString(), true);
                if (temp % 10 == 2)
                {
                    temp += 7;
                }
            }
            int Num = (int)BackgroundInfo.Vertalign * 10 + (int)BackgroundInfo.Horizalign;
            GetLocationFromNumber[Num.ToString()] = false;

        }

        public void InitComponentBySelectedInfo()
        {
            ConvertItemToInfo(TemplateBackgroundItem, ref BackgroundInfo);
            RotationText = BackgroundInfo.Rotation.ToString();
            OpacityText = BackgroundInfo.Opacity.ToString();
            InitLocationButtonMatrix();
            IsRelativeScaleValue = BackgroundInfo.IsRelativeScale;
            RelativeScaleText = BackgroundInfo.Scale.ToString();
            HorizontalOffsetValue = (BackgroundInfo.HorizOffset).ToString();
            VerticalOffsetValue = (BackgroundInfo.VertOffset).ToString();
            PageRangeSelectIndex = BackgroundInfo.PageRangeIndex;
            if (BackgroundInfo.PageRangeIndex == 3) { PageRangeSelectIndex = 0; }
        }

        public void ChangeLocation(object e)
        {
            string args = e as string;
            if (args != null)
            {
                BackgroundInfo.Vertalign = (C_Background_Vertalign)(int.Parse(args) / 10);
                BackgroundInfo.Horizalign = (C_Background_Horizalign)(int.Parse(args) % 10);
                eventAggregator.GetEvent<SetBackgroundEvent>().Publish(new BackgroundInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BackgroundInfo
                });
                InitLocationButtonMatrix();
            }
        }

        public void OpenFile()
        {
            System.Windows.Forms.OpenFileDialog dlg = new System.Windows.Forms.OpenFileDialog();
            dlg.Multiselect = false;
            dlg.Filter = "PDF|*.png;*.jpg;*.pdf";
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                FileNameText = dlg.SafeFileName;
                FileInfo file = new FileInfo(dlg.FileName);
                if (file.Extension == ".pdf")
                {
                    GetBitmapFromDocment(dlg.FileName);
                }
                else
                {
                    EditToolsHelper.ChooseFile(dlg.FileName, ref BackgroundInfo);
                }
                CreateModFileVisible = Visibility.Visible;
                eventAggregator.GetEvent<SetBackgroundEvent>().Publish(new BackgroundInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BackgroundInfo
                });
            }
        }

        public async void GetBitmapFromDocment(string filePath)
        {
            CPDFViewer cPDFViewer = new CPDFViewer();
            cPDFViewer.InitDocument(filePath);
            VerifyPasswordResult result = SecurityHelper.VerifyPasswordByPasswordKind(cPDFViewer.Document, EnumPasswordKind.StatusOpenPassword, dialogs);
            if (result.IsDiscryptied)
            {
                if (result.Password != null)
                {
                    cPDFViewer.Document.Release();
                    cPDFViewer.InitDocument(filePath);
                    cPDFViewer.Document.UnlockWithPassword(result.Password);
                }
                ///TODO:
                ///此处填入需要执行的代码
                CPDFPage page = cPDFViewer.Document.PageAtIndex(0);
                byte[] bmp_data = new byte[(int)page.PageSize.Width * (int)page.PageSize.Height * 4];
                await Task.Run(delegate
                {
                    page.RenderPageBitmap(0, 0, (int)page.PageSize.Width, (int)page.PageSize.Height, 0xffffffff, bmp_data, 1);
                });
                BackgroundInfo.ImageArray = bmp_data;
                BackgroundInfo.ImageWidth = (int)page.PageSize.Width;
                BackgroundInfo.ImageHeight = (int)page.PageSize.Height;
                cPDFViewer.Document.ReleasePages();
                cPDFViewer.Document.Release();
            }
        }

        public void ConvertItemToInfo(BackgroundItem backgroundItem, ref BackgroundInfo backgroundInfo)
        {
            if (backgroundItem != null)
            {
                backgroundInfo.BackgroundType = C_Background_Type.BG_TYPE_IMAGE;
                backgroundInfo.Color = backgroundItem.bgColor;
                backgroundInfo.Horizalign = backgroundItem.horizalign;
                backgroundInfo.Vertalign = backgroundItem.vertalign;
                backgroundInfo.VertOffset = backgroundItem.vertOffset;
                backgroundInfo.Horizalign = backgroundItem.horizalign;
                backgroundInfo.Opacity = backgroundItem.opacity;
                backgroundInfo.Rotation = backgroundItem.rotation;
                backgroundInfo.IsRelativeScale = backgroundItem.isRelativeScale;
                backgroundInfo.Scale = backgroundItem.scale;
                backgroundInfo.PageRangeIndex = backgroundItem.PageRangeIndex;
                backgroundInfo.PageRange = backgroundItem.pageRange;
            }
        }
        public void ConvertInfoToItem(ref BackgroundItem backgroundItem, BackgroundInfo backgroundInfo)
        {
            backgroundItem.type =  C_Background_Type.BG_TYPE_IMAGE;
            backgroundItem.imageArray = backgroundInfo.ImageArray;
            backgroundItem.imageWidth = backgroundInfo.ImageWidth;
            backgroundItem.imageHeight = backgroundInfo.ImageHeight;
            backgroundItem.horizalign = backgroundInfo.Horizalign;
            backgroundItem.vertalign = backgroundInfo.Vertalign;
            backgroundItem.vertOffset = backgroundInfo.VertOffset;
            backgroundItem.horizalign = backgroundInfo.Horizalign;
            backgroundItem.opacity = backgroundInfo.Opacity;
            backgroundItem.rotation = backgroundInfo.Rotation;
            backgroundItem.isRelativeScale = backgroundInfo.IsRelativeScale;
            backgroundItem.scale = backgroundInfo.Scale;
            backgroundItem.pageRange = PageRangeText;
            backgroundItem.PageRangeIndex = backgroundInfo.PageRangeIndex;
            //backgroundItem.pagRangeMode = backgroundInfo.PageRange;
        }

        public void SaveCurrentTemplate()
        {
            var backgroundItem = new BackgroundItem();
            ConvertInfoToItem(ref backgroundItem, BackgroundInfo);
            backgroundItem.templateName += Settings.Default.BackgroundIndex.ToString();
            try
            {
                //创建缓存文件夹
                string folderPath = Path.Combine(App.CurrentPath, "Background");
                //有可能因为其他原因存在同名文件,导致创建文件夹失败,需要先删除同名文件
                //保险措施(猜测)
                if (File.Exists(folderPath))
                {
                    File.Delete(folderPath);
                }

                DirectoryInfo tempfolder = new DirectoryInfo(folderPath);
                if (!tempfolder.Exists)
                {
                    tempfolder.Create();
                }

                //预览图缓存
                string saveName = Guid.NewGuid().ToString();
                string savePath = Path.Combine(folderPath, saveName);
                System.Windows.Size pageSize = PDFViewer.Document.GetPageSize(0);
                CPDFDocument tempDocument = CPDFDocument.CreateDocument();
                if (tempDocument != null)
                {
                    tempDocument.InsertPage(0, pageSize.Width, pageSize.Height, null);
                    var tempBackground = tempDocument.GetBackground();
                    tempBackground.SetBackgroundType(BackgroundInfo.BackgroundType);
                    tempBackground.SetImage(BackgroundInfo.ImageArray, BackgroundInfo.ImageWidth, BackgroundInfo.ImageHeight, ComPDFKit.Import.C_Scale_Type.fitCenter);
                    if (!BackgroundInfo.IsRelativeScale)
                    {
                        tempBackground.SetScale(1);
                    }
                    else
                    {
                        tempBackground.SetScale(BackgroundInfo.Scale/100);

                    }
                    tempBackground.SetRotation((float)((BackgroundInfo.Rotation / 180) * Math.PI));
                    tempBackground.SetOpacity((byte)((float)(BackgroundInfo.Opacity / 100) * 255));
                    tempBackground.SetVertalign(BackgroundInfo.Vertalign);
                    tempBackground.SetHorizalign(BackgroundInfo.Horizalign);
                    tempBackground.SetXOffset(BackgroundInfo.HorizOffset);
                    tempBackground.SetYOffset(BackgroundInfo.VertOffset);
                    tempBackground.SetPages("0");
                    tempBackground.SetAllowsPrint(true);
                    tempBackground.SetAllowsView(true);
                    tempBackground.Update();

                    //获取透明背景的图片
                    var bitmap = ToolMethod.RenderPageBitmapNoWait(tempDocument, (int)pageSize.Width, (int)pageSize.Height, 0, false, false, 0x00FFFFFF);
                    using (FileStream stream = new FileStream(savePath, FileMode.Create))
                    {
                        bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                    }

                    backgroundItem.previewImagePath = savePath;
                    tempDocument.Release();

                    Settings.Default.BackgroundTemplateList.Add(backgroundItem);
                    Settings.Default.Save();
                }
            }
            catch
            {

            }
            this.eventAggregator.GetEvent<EnterTemplateListOrCreateEvent>().Publish(new EnumTemplateListOrCreateUnicode
            {
                Unicode = Unicode,
                Status = EnumTemplateListOrCreate.StatusTemplate
            });
        }

        public void ConfirmEditBackgroundTemplateItem(EnumColorOrFileUnicode enumColorOrFileunicode)
        {
            EnumColorOrFile enumColorOrFile = enumColorOrFileunicode.Status;
            if (enumColorOrFile == EnumColorOrFile.StatusFile && FileNameText == "")
            {
                var backgroundItem = new BackgroundItem();
                ConvertInfoToItem(ref backgroundItem, BackgroundInfo);

                this.eventAggregator.GetEvent<EnterTemplateListOrCreateEvent>().Publish(new EnumTemplateListOrCreateUnicode { Unicode = Unicode, Status = EnumTemplateListOrCreate.StatusTemplate });

                try
                {
                    //创建缓存文件夹
                    string folderPath = Path.Combine(App.CurrentPath, "Background");
                    //有可能因为其他原因存在同名文件,导致创建文件夹失败,需要先删除同名文件
                    //保险措施(猜测)
                    if (File.Exists(folderPath))
                    {
                        File.Delete(folderPath);
                    }

                    DirectoryInfo tempfolder = new DirectoryInfo(folderPath);
                    if (!tempfolder.Exists)
                    {
                        tempfolder.Create();
                    }

                    //预览图缓存
                    string saveName = Guid.NewGuid().ToString();
                    string savePath = Path.Combine(folderPath, saveName);
                    System.Windows.Size pageSize = PDFViewer.Document.GetPageSize(0);
                    CPDFDocument tempDocument = CPDFDocument.CreateDocument();
                    if (tempDocument != null)
                    {
                        tempDocument.InsertPage(0, pageSize.Width, pageSize.Height, null);
                        var tempBackground = tempDocument.GetBackground();
                        tempBackground.SetBackgroundType(BackgroundInfo.BackgroundType);
                        tempBackground.SetImage(BackgroundInfo.ImageArray, BackgroundInfo.ImageWidth, BackgroundInfo.ImageHeight, ComPDFKit.Import.C_Scale_Type.fitCenter);
                        if (!BackgroundInfo.IsRelativeScale)
                        {
                            tempBackground.SetScale(1);
                        }
                        else
                        {
                            tempBackground.SetScale(BackgroundInfo.Scale/100);

                        }
                        tempBackground.SetRotation((float)((BackgroundInfo.Rotation / 180) * Math.PI));
                        tempBackground.SetOpacity((byte)((float)(BackgroundInfo.Opacity / 100) * 255));
                        tempBackground.SetVertalign(BackgroundInfo.Vertalign);
                        tempBackground.SetHorizalign(BackgroundInfo.Horizalign);
                        tempBackground.SetXOffset(BackgroundInfo.HorizOffset);
                        tempBackground.SetYOffset(BackgroundInfo.VertOffset);
                        tempBackground.SetPages("0");
                        tempBackground.SetAllowsPrint(true);
                        tempBackground.SetAllowsView(true);
                        tempBackground.Update();

                        //获取透明背景的图片
                        var bitmap = ToolMethod.RenderPageBitmapNoWait(tempDocument, (int)pageSize.Width, (int)pageSize.Height, 0, false, false, 0x00FFFFFF);
                        using (FileStream stream = new FileStream(savePath, FileMode.Create))
                        {
                            bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                        }

                        backgroundItem.previewImagePath = savePath;
                        tempDocument.Release();

                        Settings.Default.BackgroundTemplateList[TemplateBackgroundItem.listIndex] = backgroundItem;
                        Settings.Default.Save();
                    }
                }
                catch
                {

                }
                this.eventAggregator.GetEvent<EnterTemplateListOrCreateEvent>().Publish(new EnumTemplateListOrCreateUnicode
                {
                    Unicode = Unicode,
                    Status = EnumTemplateListOrCreate.StatusTemplate
                });
            }
        }


        public void SaveBackgroundTemplate(EnumColorOrFileUnicode enumColorOrFileunicode)
        {
            EnumColorOrFile enumColorOrFile = enumColorOrFileunicode.Status;
            if (enumColorOrFile == EnumColorOrFile.StatusFile && FileNameText != "")
            {
                SaveCurrentTemplate();
            }
        }
        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            navigationContext.Parameters.TryGetValue<CPDFViewer>(ParameterNames.PDFViewer, out PDFViewer);
            MaxPageRange = PDFViewer.Document.PageCount;
            EditToolsHelper.GetPageRange(PageRangeSelectIndex, PDFViewer.Document, ref BackgroundInfo.PageRange, PageRangeText);
            navigationContext.Parameters.TryGetValue<string>("UniCode", out unicode);
            if (navigationContext.Parameters.TryGetValue<BackgroundItem>("BackgroundItem", out TemplateBackgroundItem))
            {
                InitComponentBySelectedInfo();
            }
        }
    }
}