using Kivii;
using Kivii.Linq;
using Kivii.Pdf;
using Njust.Pdf.Analysis.Entities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Njust.Pdf.Analysis.Jobs
{
    public class AnalyseJob : IJob
    {
        public string Name
        {
            get
            {
                return "使用PDFBox对PDF进行全文抓取";
            }
        }

        public string Description
        {
            get
            {
                return "使用PDFBox对PDF进行全文抓取";
            }
        }

        public IJobContext TaskContext { get; set; }

        public void Dispose()
        {
        }

        public bool Execution()
        {
            return textPdfBox();
        }
        private bool textPdfBox()
        {
            int succeed = 0, total = 0;
            var conn = KiviiContext.GetOpenedDbConnection<AnalyseAll>();
            try
            {
                var query = conn.From<AnalyseAll>();
                query.Take(5);
                query.Skip(0);
                query.Where(o => o.IsAnlysis == false);//如果异常了，会重试
                query.OrderBy(o => o.CreateTime).ThenBy(o => o.Kvid);
                var entities = conn.Select(query);
                if (entities.IsNullOrEmpty())
                {
                    TaskContext.Message = "无数据需要处理";
                    return true;
                }
                total = entities.Count;

                var queryPdfEntityFile = conn.From<EntityDbFile<Analyse>>();
                queryPdfEntityFile.Where(o => o.ParentKvid == Guid.Empty & o.DbFolderPath == "/Pdf/Analysis" & o.Extension.ToLower() == ".pdf" & Sql.In(o.OwnerKvid, entities.ConvertAll(p => p.Kvid)));
                var pdfEntityFiles = conn.Select(queryPdfEntityFile);
                foreach (var item in entities)
                {
                    try
                    {
                        var pdfFile = pdfEntityFiles.FirstOrDefault(o => o.OwnerKvid == item.Kvid);
                        if (pdfFile == null) throw new Exception($"未找Pdf文件:{item.Title},HashCode:{item.HashCode}");
                        var physicalStorageFilePath = pdfFile.GetPhysicalPath();
                        if (!File.Exists(physicalStorageFilePath)) throw new Exception($"未找Pdf文件:{item.Title},HashCode:{item.HashCode}");
                        Console.WriteLine("-------------------------Pre-------------------------");
                        Console.WriteLine($"-------------------------{physicalStorageFilePath}-------------------------");
                        var text = Kivii.PdfBox.Instance.ReadText(physicalStorageFilePath);
                        Console.WriteLine("-------------------------Ok-------------------------");
                        item.Allbody = text;
                        item.AddOnlyProperties(o => o.Allbody);
                        item.AnlysisTime = DateTime.Now;
                        item.AddOnlyProperties(o => o.AnlysisTime);
                        item.AnlysisUserName = KiviiContext.CurrentMember.FullName;
                        item.AddOnlyProperties(o => o.AnlysisUserName);
                        item.IsAnlysis = true;
                        item.AddOnlyProperties(o => o.IsAnlysis);
                        Console.WriteLine("-------------------------PreUpdateOnly-------------------------");
                        conn.UpdateOnly(item);
                        Console.WriteLine("-------------------------UpdateOnly-------------------------");
                        succeed++;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("-------------------------Ex-------------------------");
                        TaskContext.Message = $"处理消息异常:共处理{succeed}/{total},Kvid:{item.Kvid},Ex:{ex.Message}";
                        item.Status += 1;
                        item.AddOnlyProperties(o => o.Status);
                        conn.UpdateOnly(item);
                        Console.WriteLine("-------------------------ExUpdate-------------------------");

                        return false;
                    }
                }
            }
            catch (Exception ex)
            {
                TaskContext.Message = $"处理消息异常:共处理{succeed}/{total},Ex:{ex.Message}";
                return false;
            }
            TaskContext.Message = $"完成:共处理{succeed}/{total}";
            return true;
        }
    }

    public class AnalyseImageJob : IJob
    {
        public string Name
        {
            get
            {
                return "抓取PDF中的图片";
            }
        }

        public string Description
        {
            get
            {
                return "抓取PDF中的图片";
            }
        }

        public IJobContext TaskContext { get; set; }

        public void Dispose()
        {
        }

        public bool Execution()
        {
            return pdfImage();
        }
        private bool pdfImage()
        {
            int succeed = 0, total = 0;
            var conn = KiviiContext.GetOpenedDbConnection<AnalyseAll>();
            try
            {
                var query = conn.From<AnalyseAll>();
                query.Take(2);
                query.Skip(0);
                query.Where(o => o.Status < 4);//如果异常了，会重试
                query.OrderBy(o => o.CreateTime).ThenBy(o => o.Kvid);
                var entities = conn.Select(query);
                if (entities.IsNullOrEmpty())
                {
                    TaskContext.Message = "无数据需要处理";
                    return true;
                }
                total = entities.Count;

                var queryPdfEntityFile = conn.From<EntityDbFile<Analyse>>();
                queryPdfEntityFile.Where(o => o.ParentKvid == Guid.Empty & o.DbFolderPath == "/Pdf/Analysis" & o.Extension.ToLower() == ".pdf" & Sql.In(o.OwnerKvid, entities.ConvertAll(p => p.Kvid)));
                var pdfEntityFiles = conn.Select(queryPdfEntityFile);
                foreach (var item in entities)
                {
                    try
                    {
                        var pdfFile = pdfEntityFiles.FirstOrDefault(o => o.OwnerKvid == item.Kvid);
                        if (pdfFile == null) throw new Exception($"未找Pdf文件:{item.Title},HashCode:{item.HashCode}");
                        var physicalStorageFilePath = pdfFile.GetPhysicalPath();
                        if (!File.Exists(physicalStorageFilePath)) throw new Exception($"未找Pdf文件:{item.Title},HashCode:{item.HashCode}");
                        
                        #region 图片
                        var imgPath = $"/Storages/Pdf/Analysis/Images/{item.Kvid}";
                        var reader = new PdfReader(physicalStorageFilePath);
                        var fileName = pdfFile.Name.Replace(pdfFile.Extension, "");
                        for (var i = 0; i < reader.XrefSize; i++)
                        {
                            var pdfObj = reader.GetPdfObject(i);
                            if (pdfObj == null || !pdfObj.IsStream()) continue;
                            var pdfStream = (PdfStream)pdfObj;
                            var subType = pdfStream.Get(PdfName.SUBTYPE);
                            if (subType == null || subType.ToString() != PdfName.IMAGE.ToString()) continue;
                            var bytes = PdfReader.GetStreamBytesRaw((PRStream)pdfStream);
                            if (bytes == null) continue;
                            try
                            {
                                var ms = new MemoryStream(bytes);
                                ms.Position = 0;
                                KiviiContext.VirtualFiles.WriteFile($"{imgPath}/{fileName}_{i}.jpg", ms);

                                //var img = System.Drawing.Image.FromStream(ms);
                                //img.Save(Path.Combine(tbxExportImagesPath.Text, $"{i}.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
                            }
                            catch
                            { }
                        }
                        #endregion
                        item.Status = int.MaxValue;
                        item.AddOnlyProperties(o => o.Status);
                        conn.UpdateOnly(item);
                        succeed++;

                    }
                    catch (Exception ex)
                    {
                        TaskContext.Message = $"处理消息异常:共处理{succeed}/{total},Kvid:{item.Kvid},Ex:{ex.Message}";
                        item.Status += 1;
                        item.AddOnlyProperties(o => o.Status);
                        conn.UpdateOnly(item);

                        return false;
                    }
                }
            }
            catch (Exception ex)
            {
                TaskContext.Message = $"处理消息异常:共处理{succeed}/{total},Ex:{ex.Message}";
                return false;
            }
            TaskContext.Message = $"完成:共处理{succeed}/{total}";
            return true;
        }
    }
}
