using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComPDFKit_Conversion.Converter;
using System.Diagnostics;
using System.IO;
using Microsoft.AppCenter.Crashes.Ingestion.Models;
using static Dropbox.Api.Sharing.ListFileMembersIndividualResult;
using ComPDFKit_Conversion.Options;
using PDF_Master.CustomControl;
using Exception = System.Exception;
using ImageMagick;
using System.IO.Compression;
using System.Windows;
using System.Net.Mime;
using System.Windows.Controls;
using PDF_Master.Properties;

namespace PDF_Master.Helper
{
    public static class ConverterHelper
    {
        public static CPDFConverterWord wordConverter = null;
        public static CPDFConverterExcel excelConverter = null;
        public static CPDFConverterPPT pptConverter = null;
        public static CPDFConverterTxt txtConverter = null;
        public static CPDFConverterCsv csvConverter = null;
        public static CPDFConverterImg imgConverter = null;
        public static CPDFConverterRTF rtfConverter = null;
        public static CPDFConverterHTML htmlConverter = null;
        public static async Task<bool> WordConvert(string inputpath, string outputpath, OnProgress getProgress, List<int> pageIndexLists, string pawssword, CPDFConvertWordOptions wordOptions = null, bool IsCustomFileName = true)
        {
            bool result = false;
            try
            {
                int[] pageArray = pageIndexLists.ToArray();
                wordConverter = new CPDFConverterWord(inputpath, pawssword);
                string outputFolder = outputpath.Remove(outputpath.LastIndexOf("\\"));
                string outputFileName = Path.GetFileNameWithoutExtension(outputpath);
                ConvertError error = ConvertError.ERR_UNKNOWN;
                string filename = GetFileNameAddSuffix(outputFolder, outputFileName, ".docx");
                result = await Task.Run(() => wordConverter.Convert(outputFolder, ref outputFileName, wordOptions, pageArray, ref error, getProgress));
                if (result)
                {
                    if (!String.IsNullOrEmpty(outputFileName) && File.Exists(outputFileName.Replace("/", "\\")))
                    {
                        CommonHelper.ShowFileBrowser(outputFileName.Replace("/", "\\"));
                    }
                }
            }

            catch
            {

            }
            return result;
        }

        public static async Task<bool> PPTConvert(string inputpath, string outputpath, OnProgress getProgress, List<int> pageIndexLists, string pawssword, CPDFConvertPPTOptions pptOptions = null, bool IsCustomFileName = true)
        {
            bool result = false;
            try
            {
                int[] pageArray = pageIndexLists.ToArray();

                pptConverter = new CPDFConverterPPT(inputpath, pawssword);
                string outputFolder = outputpath.Remove(outputpath.LastIndexOf("\\"));
                string outputFileName = Path.GetFileNameWithoutExtension(outputpath);
                ConvertError error = ConvertError.ERR_UNKNOWN;

                string filename = GetFileNameAddSuffix(outputFolder, outputFileName, ".ppt");

                result = await Task.Run(() => pptConverter.Convert(outputFolder, ref outputFileName, pptOptions, pageArray, ref error, getProgress));
                if (result)
                {
                    if (!String.IsNullOrEmpty(outputFileName) && File.Exists(outputFileName.Replace("/", "\\")))
                    {
                        CommonHelper.ShowFileBrowser(outputFileName.Replace("/", "\\"));
                    }
                }
            }
            catch
            {

            }
            return result;
        }

        public static async Task<bool> ExcelConvert(string inputpath, string outputpath, OnProgress getProgress, List<int> pageIndexLists, string pawssword, CPDFConvertExcelOptions ExcelOption, bool IsCustomFileName = true)
        {
            bool result = false;
            try
            {
                excelConverter = new CPDFConverterExcel(inputpath, pawssword);
                int[] pageArray = pageIndexLists.ToArray();

                string outputFolder = outputpath.Remove(outputpath.LastIndexOf("\\"));
                string outputFileName = Path.GetFileNameWithoutExtension(outputpath);
                ConvertError error = ConvertError.ERR_UNKNOWN;
                result = await Task.Run(() => excelConverter.Convert(outputFolder, ref outputFileName, ExcelOption, pageArray, ref error, getProgress));
                if (result)
                {
                    if (!String.IsNullOrEmpty(outputFileName) && File.Exists(outputFileName.Replace("/", "\\")))
                    {
                        CommonHelper.ShowFileBrowser(outputFileName.Replace("/", "\\"));
                    }
                    else if (outputFileName == "NoTable")
                    {
                        AlertsMessage alertsMessage = new AlertsMessage();
                        alertsMessage.ShowDialog("", " No Table", App.ServiceLoader.GetString("Text_ok"));
                    }

                }


            }
            catch
            {

            }
            return result;
        }

        //public static async Task<bool> TableConvert(string inputpath, string outputpath, OnProgress getProgress, List<int> pageIndexLists, string pawssword)
        //{
        //    bool result = false;
        //    try
        //    {
        //        int[] pageArray = pageIndexLists.ToArray();
        //        tableConverter = new CPDFConverterTable(inputpath, pawssword);
        //        string outputFolder = outputpath;
        //        string outputFileName = Path.GetFileNameWithoutExtension(inputpath);
        //        ConvertError error = ConvertError.ERR_UNKNOWN;
        //        string filename = GetFileNameAddSuffix(outputFolder, outputFileName, ".xlsx");
        //        result = await Task.Run(() => tableConverter.Convert(outputFolder, ref outputFileName, pageArray, ref error, getProgress));

        //    }
        //    catch (Exception ex)
        //    {

        //    }
        //    return result;
        //}

        public static async Task<bool> CSVConvert(string inputpath, string outputpath, OnProgress getProgress, List<int> pageIndexLists, string pawssword, CPDFConvertCsvOptions csvOptions = null, bool IsCustomFileName = true)
        {
            bool result = false;
            try
            {
                int[] pageArray = pageIndexLists.ToArray();

                csvConverter = new CPDFConverterCsv(inputpath, pawssword);
                string outputFolder = "";
                string outputFileName = "";
                if (IsCustomFileName)
                {
                    outputFolder = outputpath.Remove(outputpath.LastIndexOf("\\"));
                    outputFileName = Path.GetFileNameWithoutExtension(outputpath);
                }
                else
                {
                    outputFolder = outputpath;
                    outputFileName = Path.GetFileNameWithoutExtension(inputpath);
                }

                ConvertError error = ConvertError.ERR_UNKNOWN;
                string filename = GetFileNameAddSuffix(outputFolder, outputFileName, ".csv");
                result = await Task.Run(() => csvConverter.Convert(outputFolder, ref outputFileName, csvOptions, pageArray, ref error, getProgress));
                if (result)
                {


                    if (File.Exists(outputFileName))
                    {
                        if (IsCustomFileName)
                        {
                            if (!String.IsNullOrEmpty(outputFileName) && File.Exists(outputFileName.Replace("/", "\\")))
                            {
                                CommonHelper.ShowFileBrowser(outputFileName.Replace("/", "\\"));
                            }
                        }
                        else
                        {
                            string FileName = CommonHelper.CreateFolder(outputFileName.Replace(".zip", ""));
                            ZipFile.ExtractToDirectory(outputFileName, FileName);
                            File.Delete(outputFileName);
                            CommonHelper.ShowFileBrowser(FileName.Replace("/", "\\"));
                        }

                    }
                    else
                    {
                        AlertsMessage alertsMessage = new AlertsMessage();
                        alertsMessage.ShowDialog("", " No Table", App.ServiceLoader.GetString("Text_ok"));
                    }

                }
            }
            catch
            {

            }
            return result;
        }

        public static async Task<bool> TxtConvert(string inputpath, string outputpath, OnProgress getProgress, List<int> pageIndexLists, string pawssword, CPDFConvertTxtOptions txtOptions = null, bool IsCustomFileName = true)
        {
            bool result = false;
            try
            {
                int[] pageArray = pageIndexLists.ToArray();

                txtConverter = new CPDFConverterTxt(inputpath, pawssword);
                string outputFolder = outputpath.Remove(outputpath.LastIndexOf("\\"));
                string outputFileName = Path.GetFileNameWithoutExtension(outputpath);
                ConvertError error = ConvertError.ERR_UNKNOWN;
                string filename = GetFileNameAddSuffix(outputFolder, outputFileName, ".txt");
                result = await Task.Run(() => txtConverter.Convert(outputFolder, ref outputFileName, txtOptions, pageArray, ref error, getProgress));
                if (result)
                {
                    if (!String.IsNullOrEmpty(outputFileName) && File.Exists(outputFileName.Replace("/", "\\")))
                    {
                        CommonHelper.ShowFileBrowser(outputFileName.Replace("/", "\\"));
                    }
                }
            }
            catch
            {

            }
            return result;
        }

        public static void ImageMagickPDFToImage(string imageType, string filePath, string outputFolder, string outputFileName, ref string FileName, double density = 150)
        {
            FileName = CommonHelper.CreateFolder(outputFolder + "\\" + outputFileName);
            ZipFile.ExtractToDirectory(filePath, FileName);
            var files = Directory.GetFiles(FileName, "*.png");
            int i = 0;
            var images = new MagickImageCollection();
            foreach (var file in files)
            {
                //pdf整体转为gif,将.gifoff改为.gif
                Trace.WriteLine(file);
                if (imageType == ".gifoff")
                {
                    images.Add(file);
                    images[i].AnimationDelay = 100; // in this example delay is 1000ms/1sec
                    images[i].Flip();
                }

                using (var image = new MagickImage(file))
                {
                    if (imageType != ".gifoff")
                    {
                        //Save frame as jpg
                        //image.Format = MagickFormat.Jp2;
                        //水平垂直DPI
                        image.Density = new Density(density);
                        image.Write(file.Remove(file.LastIndexOf(".png"), 4) + imageType);
                    }
                    // 删除该文件
                    System.IO.File.Delete(file);
                }
            }
            if (imageType == ".gifoff")
            {
                // Optionally reduce colors
                var settings = new QuantizeSettings();
                settings.Colors = 256;
                images.Quantize(settings);
                // Optionally optimize the images (images should have the same size).
                images.Optimize();

                // Save gif
                int fileIndex = 1;
                if (File.Exists(outputFolder + "\\" + outputFileName + ".gif"))
                {
                    while (fileIndex >= 1)
                    {
                        if (!File.Exists(outputFolder + "\\" + outputFileName + "_" + fileIndex + ".gif"))
                        {
                            images.Write(outputFolder + "\\" + outputFileName + ".gif");
                            fileIndex = -1;
                        }
                        fileIndex++;
                    }
                }
                else { images.Write(outputFolder + "\\" + outputFileName + ".gif"); }

            }
            //else {
            //    int fileIndex = 1;

            //    if (File.Exists(outputFolder + "\\" + outputFileName + ".zip"))
            //    {
            //        while (fileIndex>=1) {
            //            if (!File.Exists(outputFolder + "\\" + outputFileName + "_" + fileIndex + ".zip"))
            //            {
            //                ZipFile.CreateFromDirectory(outputFolder + "\\" + outputFileName, outputFolder + "\\" + outputFileName + "_" + fileIndex + ".zip");
            //                fileIndex=-1;
            //            }
            //            fileIndex++;
            //        }
            //    }
            //    else { ZipFile.CreateFromDirectory(outputFolder + "\\" + outputFileName, outputFolder + "\\" + outputFileName + ".zip"); }

            //}
            //DirectoryInfo di = new DirectoryInfo(outputFolder + "\\" + outputFileName);
            //di.Delete(true);


        }

        public static async Task<bool> ImgConvert(string inputpath, string outputpath, OnProgress getProgress, List<int> pageIndexLists, string pawssword, string imageType = ".png", CPDFConvertImgOptions imgOptions = null)
        {
            string FileName = "";
            bool result = false;
            try
            {
                int[] pageArray = pageIndexLists.ToArray();

                imgConverter = new CPDFConverterImg(inputpath, pawssword);
                string outputFolder = outputpath;
                string outputFileName = Path.GetFileNameWithoutExtension(inputpath);
                ConvertError error = ConvertError.ERR_UNKNOWN;
                if (imageType == ".png" || imageType == ".jpg")
                {
                    result = await Task.Run(() => imgConverter.Convert(outputFolder, ref outputFileName, imgOptions, pageArray, ref error, getProgress));
                    FileName = CommonHelper.CreateFolder(outputFileName.Replace(".zip", ""));
                    ZipFile.ExtractToDirectory(outputFileName, FileName);
                    FileInfo file = new FileInfo(outputFileName);
                    if (file.Exists) { file.Delete(); }
                }
                else
                { //创建缓存文件夹

                    string folderPath = Path.Combine(App.CurrentPath, "ConverterImg");
                    //有可能因为其他原因存在同名文件,导致创建文件夹失败,需要先删除同名文件
                    //保险措施(猜测)
                    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);
                    result = await Task.Run(() => imgConverter.Convert(folderPath, ref saveName, imgOptions, pageArray, ref error, getProgress));
                    ImageMagickPDFToImage(imageType, saveName, outputFolder, outputFileName, ref FileName, imgOptions.ImageDpi);
                    DirectoryInfo di = new DirectoryInfo(folderPath);
                    di.Delete(true);
                }

                if (result)
                {
                    //Process.Start(FileName.Replace("/", "\\"));
                    CommonHelper.ShowFileBrowser(FileName.Replace("/", "\\"));
                }
            }
            catch
            {

            }
            return result;
        }

        public static async Task<bool> RTFConvert(string inputpath, string outputpath, OnProgress getProgress, List<int> pageIndexLists, string pawssword, CPDFConvertRTFOptions rtfOptions = null, bool IsCustomFileName = true)
        {
            bool result = false;
            try
            {
                int[] pageArray = pageIndexLists.ToArray();
                rtfConverter = new CPDFConverterRTF(inputpath, pawssword);
                string outputFolder = outputpath.Remove(outputpath.LastIndexOf("\\"));
                string outputFileName = Path.GetFileNameWithoutExtension(outputpath);
                ConvertError error = ConvertError.ERR_UNKNOWN;
                result = await Task.Run(() => rtfConverter.Convert(outputFolder, ref outputFileName, rtfOptions, pageArray, ref error, getProgress));
                if (result)
                {
                    if (!String.IsNullOrEmpty(outputFileName) && File.Exists(outputFileName.Replace("/", "\\")))
                    {
                        CommonHelper.ShowFileBrowser(outputFileName.Replace("/", "\\"));
                    }
                }
            }
            catch
            {

            }
            return result;
        }

        public static async Task<bool> HTMLConvert(string inputpath, string outputpath, OnProgress getProgress, List<int> pageIndexLists, string pawssword, CPDFConvertHTMLOptions HtmlOption, bool IsCustomFileName = true)
        {
            bool result = false;
            try
            {
                htmlConverter = new CPDFConverterHTML(inputpath, pawssword);
                int[] pageArray = pageIndexLists.ToArray();

                string outputFolder = outputpath.Remove(outputpath.LastIndexOf("\\"));
                string outputFileName = Path.GetFileNameWithoutExtension(outputpath);
                ConvertError error = ConvertError.ERR_UNKNOWN;
                result = await Task.Run(() => htmlConverter.Convert(outputFolder, ref outputFileName, HtmlOption, pageArray, ref error, getProgress));
                if (result)
                {
                    if (!String.IsNullOrEmpty(outputFileName) && File.Exists(outputFileName.Replace("/", "\\")))
                    {
                        CommonHelper.ShowFileBrowser(outputFileName.Replace("/", "\\"));
                    }
                }
            }
            catch
            {

            }
            return result;
        }
        public static void Clear(string ConvertType)
        {

            switch (ConvertType)
            {
                case "Word":
                    if (wordConverter != null)
                    {
                        wordConverter.Cancel();
                    }
                    break;

                case "Excel":
                    if (excelConverter != null)
                    {
                        excelConverter.Cancel();
                    }
                    break;

                case "PPT":
                    if (pptConverter != null)
                    {
                        pptConverter.Cancel();
                    }
                    break;

                case "Text":
                    if (txtConverter != null)
                    {
                        txtConverter.Cancel();
                    }
                    break;

                case "CSV":
                    if (csvConverter != null)
                    {
                        csvConverter.Cancel();
                    }
                    break;

                case "RTF":
                    if (rtfConverter != null)
                    {
                        rtfConverter.Cancel();
                    }
                    break;

                case "HTML":
                    if (htmlConverter != null)
                    {
                        htmlConverter.Cancel();
                    }
                    break;

                case "Img":
                    if (imgConverter != null)
                    {
                        imgConverter?.Cancel();
                    }
                    break;

                default:
                    break;
            }
        }
        private static void StartFile(string path)
        {
            //Process.Start(path);
        }
        public static string GetFileNameAddSuffix(string path, string filename, string suffix)
        {
            int i = 1;
            string outname = filename;
            while (File.Exists(path + @"\" + outname + suffix))
            {
                outname = filename + $"({i.ToString()})";
                i++;
            }
            return outname;
        }

        public static Microsoft.Office.Interop.Word.Application word;

        public static Microsoft.Office.Interop.Excel.Application excele;

        public static Microsoft.Office.Interop.PowerPoint.Application ppt;

        public static string ConvertOfficeToPDF(string sourcepath, Microsoft.Office.Interop.Word.WdPaperSize paperSize = Microsoft.Office.Interop.Word.WdPaperSize.wdPaperA4, double margin = 0)
        {

            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).ToLower();
            switch (ex)
            {
                case ".doc":
                case ".docx":
                case "docm":
                case ".dot":
                case ".dotx":
                case ".dotm":
                case ".txt":
                case ".html":
                    if (word == null)
                    {
                        word = new Microsoft.Office.Interop.Word.Application();
                    }

                    word.Visible = false;
                    word.ShowWindowsInTaskbar = true;
                    Microsoft.Office.Interop.Word.Document document = word.Documents.Open(sourcepath);
                    var page = document.PageSetup;
                    page.PaperSize = paperSize;
                    if (margin > 0)
                    {
                        page.LeftMargin = page.TopMargin = page.RightMargin = page.BottomMargin = (float)margin;
                    }
                    document?.ExportAsFixedFormat(targetPath, Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF);
                    document?.Close(false);
                    if (word != null)
                    {
                        word.NormalTemplate.Saved = true;
                        //word.Quit();
                    }
                    break;

                case ".xls":
                case ".xlsx":
                case ".xlsm":
                case ".xlsb":
                case ".xlam":
                case ".xltx":
                case ".xlt":
                    if (excele == null)
                    {
                        excele = new Microsoft.Office.Interop.Excel.Application();
                    }
                    Microsoft.Office.Interop.Excel.Workbook workbook = null;

                    excele.Visible = false;
                    try
                    {
                        workbook = excele.Workbooks.Open(sourcepath);
                    }
                    catch
                    {
                        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":
                    if (ppt == null)
                    {
                        ppt = new Microsoft.Office.Interop.PowerPoint.Application();
                    }
                    Microsoft.Office.Interop.PowerPoint.Presentation presentation = null;

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

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

        /// <summary>
        /// 转档解锁跳转
        /// </summary>
        public static void convertUnlock()
        {      
                Process.Start(new ProcessStartInfo("http://test-pdf-pro.kdan.cn:3021/windows/store/master-subscription?email=" + Settings.Default.UserDate.Email));
        }

    }
}