using HtmlAgilityPack;
using Microsoft.Office.Interop.Word;
using OfficeAppHelp.Help;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Range = Microsoft.Office.Interop.Word.Range;

namespace QuestionSwapDoc.SwapQuestionModel
{
    /// <summary>
    /// 试题项的一个范围
    /// </summary>
    public class QueItemRange
    {
        public QueItemRange()
        {
            Start = null;
            End = null;
        }
        public QueItemRange(int? start, int? end)
        {
            Start = start;
            End = end;
        }


        /// <summary>
        /// 开始
        /// </summary>
        public int? Start { get; set; }
        /// <summary>
        /// 结束
        /// </summary>
        public int? End { get; set; }
        /// <summary>
        /// 是否为空的或者无效的范围
        /// </summary>
        public bool IsNull { get => Start == null || Start < 0 || End == null || End <= 0; }
        /// <summary>
        /// html文本
        /// </summary>
        public string HtmlText { get; set; }
        /// <summary>
        /// xml文件
        /// </summary>
        public string XmlFile { get; set; }


        /// <summary>
        /// 得到范围
        /// </summary>
        /// <param name="Doc"></param>
        /// <returns></returns>
        public Range GetRange(Document Doc)
        {
            if (IsNull)
                return null;

            return Doc.Range(Start, End);
        }

        /// <summary>
        /// 填充范围内容
        /// </summary>
        /// <param name="Doc"></param>
        /// <param name="xmlDirectory">xml文件放置文件夹</param>
        /// <param name="linkDirectory">解析的所有html文件里面的连接文件将放在这里（如图片）</param>
        /// <param name="imgLinkLeftPath">前缀</param>
        public void Fill(Document Doc, string xmlDirectory = "", string linkDirectory = "", string imgLinkLeftPath = "")
        {
            Range range = GetRange(Doc);
            if (range == null)
                return;

            //生成xml
            if (!string.IsNullOrWhiteSpace(xmlDirectory))
            {
                string randomPath = Path.GetRandomFileName().Replace(".", "");
                string xmlPath = Path.Combine(xmlDirectory, randomPath + ".docx");
                range.ExportFragment(xmlPath, WdSaveFormat.wdFormatXMLDocument);
                XmlFile = xmlPath;
            }

            HtmlText = FillHtml(range, linkDirectory, imgLinkLeftPath);
        }
        /// <summary>
        /// 填充范围内容（Html）
        /// </summary>
        /// <param name="linkDirectory">解析的所有html文件里面的连接文件将放在这里（如图片）</param>
        /// <param name="imgLinkLeftPath">前缀</param>
        public static string FillHtml(Range range, string linkDirectory = "", string imgLinkLeftPath = "")
        {
            //生成html
            if (!string.IsNullOrWhiteSpace(linkDirectory))
            {
                string randomPath = Path.GetRandomFileName().Replace(".", "");
                string htmlPath = Path.Combine(linkDirectory, randomPath + ".html");
                range.ExportFragment(htmlPath, WdSaveFormat.wdFormatHTML);

                //注册字符编码
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                var htmlText = File.ReadAllText(htmlPath, Encoding.GetEncoding("GB2312"));

                //html解析器
                HtmlDocument htmlDocument = new HtmlDocument();
                htmlDocument.LoadHtml(htmlText);

                //删除html节点中的属性
                htmlDocument.DocumentNode.SelectSingleNode("//html")?.Attributes.RemoveAll();
                //head节点中只保留style节点
                var stylehtml = htmlDocument.DocumentNode.SelectSingleNode("//head")?.Descendants("style")?.FirstOrDefault();
                if (stylehtml != null)
                {
                    htmlDocument.DocumentNode.SelectSingleNode("//head")?.RemoveAll();
                    htmlDocument.DocumentNode.SelectSingleNode("//head")?.InsertAfter(stylehtml, null);
                }
                //删除注释
                htmlDocument.DocumentNode.SelectNodes("//comment()")?.ToList()?.ForEach(o => o.Remove());

                var imgs = htmlDocument.DocumentNode.SelectNodes("//img");
                if (imgs != null)
                {
                    foreach (var item in imgs)
                    {
                        var imgSrc = item.Attributes["src"];
                        var imgPath = Path.Combine(linkDirectory, imgSrc.Value);
                        if (File.Exists(imgPath))
                        {
                            //图片使用链接：
                            var md5 = FileHelp.GetFileMD5(imgPath);
                            var newFilName = md5 + Path.GetExtension(imgPath);
                            var newImgPath = Path.Combine(linkDirectory, newFilName);
                            //避免重复的文件/图片
                            if (!File.Exists(newImgPath))
                                File.Copy(imgPath, newImgPath);

                            var newImgSrc = Path.Combine(imgLinkLeftPath, newFilName);
                            imgSrc.Value = newImgSrc;

                            ////图片使用base64：
                            //var b64 = $"data:image/{Path.GetExtension(imgPath).Replace(".", "")};base64,{Convert.ToBase64String(File.ReadAllBytes(imgPath))}";
                            //imgSrc.Value = b64;
                        }
                    }
                }


                //删除html和生成的图片
                File.Delete(htmlPath);
                var dirFile = Path.Combine(linkDirectory, randomPath + ".files");
                if (Directory.Exists(dirFile))
                    Directory.Delete(dirFile, true);

                //压缩html
                return htmlDocument.DocumentNode.OuterHtml.Replace("\n", "").Replace("\r", "");
            }
            return string.Empty;
        }
        /// <summary>
        /// 填充范围内容（选择题）
        /// </summary>
        /// <param name="Doc"></param>
        public void FillXx(Document Doc)
        {
            Range range = GetRange(Doc);
            if (range == null)
                return;

            HtmlText = string.Join(",", range.Text.GetUpperLetter().OrderBy(o => o));
        }
        /// <summary>
        /// 填充范围内容（判断题）
        /// </summary>
        /// <param name="Doc"></param>
        /// <param name="itemT">正确的集合</param>
        /// <param name="itemF">错误的集合</param>
        public void FillPd(Document Doc, string[] itemT, string[] itemF)
        {
            Range range = GetRange(Doc);
            if (range == null)
                return;

            var te = range.Text.Trim();
            if (itemT.Contains(te))
                HtmlText = true.ToString();
            else if (itemF.Contains(te))
                HtmlText = false.ToString();

        }

    }
}
