using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using AIProofread.Controls;
using AIProofread.core;
using AIProofread.Util;
using Microsoft.Office.Interop.Word;
using Newtonsoft.Json;
using UtilLib;
using CustomTaskPane = Microsoft.Office.Tools.CustomTaskPane;

namespace AIProofread.Model
{
    /// <summary>
    /// 文档信息 包含文档相关数据、面板及对文档的相关操作
    /// </summary>
    public class DocumentInfo
    {
        public static readonly int MIN_WIDTH = 420;
        private static char[] ArticleSpecialChars = new char[4] { '\a', '\r', '\v', '\f' };

        private static object missing = System.Reflection.Missing.Value;
        /// <summary>
        /// 是否已经校对
        /// </summary>
        public bool hasProofreaded = false;
        /// <summary>
        /// 是否已经处理了校对结果
        /// </summary>
        public bool hasProcessMark = false;

        /// <summary>
        /// 
        /// </summary>
        public Dictionary<int, ProofreadItem> marks = new Dictionary<int, ProofreadItem>();

        /// <summary>
        /// 最小宽度
        /// </summary>
        public static int MinWidth = 0;
        /// <summary>
        /// 校对选区集合
        /// </summary>
        private List<Range> ranges = new List<Range>();

        /// <summary>
        /// 当前选中对现象编号
        /// </summary>
        private int selectProofreadId;

        //private Document currentDocument;
        /// <summary>
        /// 当前对应文档
        /// </summary>
        public Document CurrentDocument { get; set; }

        /// <summary>
        /// 文件名称
        /// </summary>
        public string fileName;

        private string uniqueId;
        public string UniqueId { get { return uniqueId; } }

        public string ProofreadCachePath
        {
            get
            {
                return CurrentDocument.FullName + "-proofread.json";
            }
        }

        public bool IsActive { get; internal set; }
        public bool PaneVisible { get; set; }
        public int Id { get; set; }

        public CustomTaskPane TaskPane { get; set; }
        public WdProtectionType ProtectionType { get { return CurrentDocument.ProtectionType; } }

        /// <summary>
        /// 是否已校对
        /// </summary>
        public bool Proofread { get; set; }
        /// <summary>
        /// 是否校对中
        /// </summary>
        public bool Proofreading { get; set; }

        // 初始化
        public DocumentInfo(Document doc)
        {
            this.CurrentDocument = doc;
            Initialize();
        }

        /// <summary>
        /// 显示面板
        /// </summary>
        public void ShowPane()
        {
            if (null != TaskPane)
            {
                TaskPane.Visible = PaneVisible = true;
            }
        }

        public void RunInMainThread(Action action)
        {
            if (null != TaskPane)
            {
                TaskPane.Control.BeginInvoke(action);
            }
        }

        public void ShowDialog(string message, string confirmText, string confirmAction)
        {
            TaskPane.Control.BeginInvoke(new Action(() =>
            {
                //MessageBox.Show(message, "提示");
                FormMessage.ShowMessage(message, confirmText, confirmAction);
            }));
        }
        public FormMessage ShowMessage(string message, int closeDelay, bool showCloseBtn = true)
        {
            var msgForm = FormMessage.ShowMessage(message, closeDelay);
            if (closeDelay > 0)
            {

                if (!showCloseBtn)
                {
                    msgForm.HideCloseBtn();
                }
                // n毫秒后自动关闭
                System.Threading.Tasks.Task.Delay(closeDelay).ContinueWith(t =>
                {
                    if (msgForm.IsDisposed) return;
                    TaskPane.Control.BeginInvoke(new Action(() =>
                    {
                        msgForm.Close();
                    }));
                });
            }
            return msgForm;
        }

        public void ShowLogin(string action)
        {
            TaskPane.Control.BeginInvoke(new Action(() =>
            {
                FormLogin frm = new FormLogin(action);
                Globals.ThisAddIn.LoginFormList.Add(frm);
                frm.ShowDialog();
            }));
        }

        private void ShowDocumentStatus(string tag)
        {
           // Logger.Log($"{fileName} {tag} PaneVisible is {PaneVisible} Poofread is {Proofread} Proofreading is {Proofreading}");
        }

        /// <summary>
        /// 隐藏面板
        /// </summary>
        public void HidePane()
        {
            ShowDocumentStatus(" HidePane");
            if (null != TaskPane) TaskPane.Visible = PaneVisible = false;
        }

        /// <summary>
        /// 激活
        /// </summary>
        public void Active()
        {
            ShowDocumentStatus(" Active");
            IsActive = true;
            if (Config.IS_WPS && null != TaskPane && PaneVisible)
            {
                TaskPane.Visible = true;
            }
        }

        public void Deactive()
        {
            ShowDocumentStatus(" Deactive");
            IsActive = false;
            if (Config.IS_WPS)
            {
                if (PaneVisible)
                {
                    // 异步等待一段时间 重新设置为true，防止面板关闭时，触发事件
                    ThreadPool.QueueUserWorkItem(state =>
                    {
                        Thread.Sleep(1000);
                        PaneVisible = true;
                    });
                }
                if (null != TaskPane && PaneVisible)
                {
                    TaskPane.Visible = false;
                }
            }


        }

        public void Dispose()
        {
            try
            {
                // 释放com
                try
                {
                    Marshal.ReleaseComObject(CurrentDocument);
                }
                catch (Exception) { }
                if(TaskPane.Control.IsDisposed) return;
                ProofreadMainControl control = (ProofreadMainControl)TaskPane.Control;
                control.ResetWeb();

                HidePane();
                TaskPane?.Dispose();
            }
            catch (Exception e)
            {
                Logger.Log("Error", e);
            }
        }

        // 计算uniqueId
        private void ComputeUniqueId()
        {
            string filename = CurrentDocument.FullName;
            if (!string.IsNullOrEmpty(uniqueId) || string.IsNullOrEmpty(filename))
            {
                return;
            }
            // 通过文档路径生成唯一id
            uniqueId = filename.GetHashCode().ToString();
        }

        /// <summary>
        /// 添加变量控制重复调用
        /// </summary>
        private bool isResizing = false;
        private void Control_SizeChanged(object sender, EventArgs e)
        {
            if (isResizing) return;
            if (TaskPane != null && TaskPane.Visible && TaskPane.Width < MinWidth)
            {
                isResizing = true;
                SendKeys.Send("{ESC}");
                TaskPane.Width = MinWidth;
                isResizing = false;
            }
        }

        // 创建pane 并初始化
        public void CreateTaskPane()
        {
            var control = new ProofreadMainControl();
            if (MinWidth < 10)
            {
                MinWidth = MIN_WIDTH * control.LabelWidth() / 42;
            }
            // 创建pane
            TaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(control, " ");
            // 默认隐藏
            TaskPane.Visible = false;
            // 设置宽度
            control.Width = MinWidth;
            TaskPane.Width = MinWidth;

            // 监听尺寸变化 防止最小尺寸小于设置值
            control.SizeChanged += Control_SizeChanged;
            TaskPane.VisibleChanged += TaskPane_VisibleChanged;
        }


        public void CheckBtnStatus()
        {
            //
            if (Globals.ThisAddIn.ribbon != null)
            {
                Globals.ThisAddIn.ribbon.BtnShowPanel.Enabled = !PaneVisible && Proofread;
                Globals.ThisAddIn.ribbon.SetCommonBtnStatus(!Proofreading);
            }
        }

        private void TaskPane_VisibleChanged(object sender, EventArgs e)
        {
            // 如果已经隐藏 则记录隐藏用于(WPS)多面板的切换的处理
            PaneVisible = TaskPane.Visible;
            CheckBtnStatus();
            //Globals.ThisAddIn.ribbon.BtnShowPanel.Enabled = !TaskPane.Visible && Proofread;
        }

        public void Initialize()
        {
            this.fileName = CurrentDocument.FullName;
            ranges.Clear();
            ComputeUniqueId();
            if (TaskPane == null) CreateTaskPane();

        }

        //处理文档选区时 判断当前选区是否有校对项 有则选择该范围
        public void ProcessSelectionChange(Selection s)
        {
            // 判断选区内是否有书签
            if (s.Bookmarks != null && s.Bookmarks.Count > 0)
            {
                // 判断是否时点击 点击的起始和结束位置相同
                if (s.Range.Start == s.Range.End)
                {
                    // 
                    var count = s.Bookmarks.Count;
                    // 原则只有一个书签
                    //foreach (Microsoft.Office.Interop.Word.Bookmark item in s.Bookmarks)
                    //{
                    //    int proofreadId = Config.GetBookmarkIdByName(item.Name);
                    //    if (proofreadId > 0)
                    //    {
                    //        //Bridge.bridge.SelectMarkById(proofreadId, 0);
                    //        return;
                    //    }
                    //}
                }
            }
        }

        // 获取当前文档文本
        public string GetAllText()
        {
            return CurrentDocument.Range().Text;
        }

        /// <summary>
        /// 获取当前选中文本
        /// </summary>
        /// <returns></returns>
        public string GetSelectedText()
        {
            // 获取当前文档的选区
            var selection = Globals.ThisAddIn.Application.Selection;
            return selection.Text;
        }

        /// <summary>
        /// 获取指定选区的文本
        /// </summary>
        /// <param name="range"></param>
        /// <returns></returns>
        public string GetRangeText(Range range)
        {
            string text = range?.Text;
            return string.IsNullOrEmpty(text) ? "" : text;
        }
        /// <summary>
        /// 获取指定选区的文本
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public string GetRangeText(int start, int end)
        {
            if (start >= end) return null;
            return GetRangeText(CurrentDocument.Range(start, end));
        }

        public Range Range(int start, int end)
        {
            if (start >= end) return null;
            return CurrentDocument.Range(start, end);
        }

        /// <summary>
        /// 保存校对缓存结果
        /// </summary>
        private void SaveProofreadCache(string cacheData)
        {
            // 判断文档是否已经保存

            if (!CurrentDocument.Saved)
            {
                // 保存文档
                if (!CurrentDocument.Saved)
                {
                    // 提示保存文档
                    var result = MessageBox.Show("当前文档尚未保存，是否保存？", "提示", MessageBoxButtons.YesNo);
                    if (result == DialogResult.Yes)
                    {
                        CurrentDocument.Save();
                    }
                    else
                    {
                        return;
                    }
                }
            }
        }



        // 定位所有的校对项
        public void LocateAllProofreadItems(List<CorrectContext> list)
        {
            // 获取所有的校对项
            //List<Range> proofreadItems = GetProofreadItems();
            var prevOffset = 0;
            foreach (var item in list)
            {
                if (item.CorrectItems != null && item.CorrectItems.Count > 0)
                {
                    foreach (var correct in item.CorrectItems)
                    {
                        var range = LocateProofreadItem(correct, item, ref prevOffset);
                        if (range == null) continue;

                    }
                }
            }

        }

        /// <summary>
        /// 查找偏移量
        /// </summary>
        private static readonly int INSERT_FIND_OFFSET = 5;
        /// <summary>
        /// 定位校对项
        /// </summary>
        /// <param name="correct">校对项</param>
        /// <param name="ctx">校对上下文</param>
        /// <param name="prevOffset">上一步的</param>
        /// <returns></returns>
        private Range LocateProofreadItem(CorrectItem correct, CorrectContext ctx, ref int prevOffset)
        {
            var document = CurrentDocument;
            // 校对项的段落号超过文档的段落数，直接返回
            if (ctx.ParagraphNumber > document.Paragraphs.Count) return null;
            // 获取当前段落
            var paragraph = document.Paragraphs[ctx.ParagraphNumber];
            if (paragraph == null) return null;


            var paraRange = paragraph.Range;
            var paraText = paraRange.Text;
            var paraStart = paraRange.Start;

            //var offset = paraStart + ctx.SentenceOffset;
            //var cutLength = Math.Min(c.InsertLen, paraText.Length - offset);
            var sentence = paraRange.Sentences[ctx.SentenceNumber]; //paraText.Substring(ctx.SentenceOffset, ctx.InsertLength);
            ctx.SentenceOffset = sentence.Start;
            var offset = paraStart + ctx.SentenceOffset;
            if (sentence.Text == ctx.Insert)
            { // 比对原始内容与校对原文是否一致
                var range = document.Range(offset + correct.Start, offset + correct.End);
                // 
                if (range.Text == correct.Origin) return range;
            }

            var originText = ctx.Insert;
            // 如果是新增 则查找定位
            if (correct.Tag == "i")
            {
                // 找前缀
                var prefix1 = correct.Start > 2 ? (
                    correct.Start > INSERT_FIND_OFFSET
                        ? originText.Substring(correct.Start - INSERT_FIND_OFFSET, INSERT_FIND_OFFSET)
                        : originText.Substring(0, correct.Start)
                    ) : null;
                // 找后缀
                var suffix1 = prefix1 == null ? (
                    correct.End + INSERT_FIND_OFFSET < originText.Length
                    ? originText.Substring(correct.Start, INSERT_FIND_OFFSET)
                : originText.Substring(correct.Start, originText.Length - correct.Start)
                    ) : null;
                // 偏移量
                var start1 = prefix1 != null || suffix1 != null
                    ? paraText.IndexOf(prefix1 ?? suffix1, prevOffset)
                    : -1;
                if (start1 != -1)
                {
                    var findOffset = paraStart + start1 + (prefix1 != null ? prefix1.Length : 0);
                    return document.Range(findOffset, findOffset);
                }
            }

            // 执行查找
            int wordStart = correct.Start;
            int wordEnd = correct.End;

            // 找前缀
            var prefix = wordStart > 2 ? (
                wordStart > INSERT_FIND_OFFSET
                    ? originText.Substring(wordStart - INSERT_FIND_OFFSET, INSERT_FIND_OFFSET)
                    : originText.Substring(0, wordStart)
                ) : null;

            // 找后缀
            var suffix = prefix == null ? (
                wordEnd + INSERT_FIND_OFFSET < originText.Length
                ? originText.Substring(wordStart, INSERT_FIND_OFFSET)
                : originText.Substring(wordStart, originText.Length - wordStart)
                ) : null;
            var start = prefix != null || suffix != null
                        ? paraText.IndexOf(prefix ?? suffix, prevOffset) // item.start + 
                        : -1;
            if (start != -1)
            {
                var findOffset = paraRange.Start + start + (prefix != null ? prefix.Length : 0);
                var range = document.Range(findOffset, findOffset + wordEnd - wordStart);
                if (range.Text == correct.Origin) { return range; }
            }
            // 直接定位查找
            start = paraText.IndexOf(correct.Origin, prevOffset);
            if (start == -1) return null;
            // 定位整体开始位置
            start = paraStart + start;
            return document.Range(start, start + correct.Origin.Length);

        }

        public void SendMessageToWeb(string msg, object data)
        {
            var json = JsonConvert.SerializeObject(new WebMessage(msg, data));
            ProofreadMainControl control = (ProofreadMainControl)TaskPane.Control;
            try
            {
                if (control.web.CoreWebView2 == null)
                {
                    Thread.Sleep(1000);
                }
                control.web.CoreWebView2.PostWebMessageAsJson(json);
            }
            catch (Exception ex)
            {
                Logger.Log("SendMessage", "send message to web error \n" + ex.Message + "\n" + msg + data.ToString());
            }
        }

        public void ClearAllProofreadMark()
        {
            try
            {
                selectProofreadId = -1;
                foreach (var item in marks.Values)
                {
                    if (item.mark != null)
                    {
                        if (item.content.Tag == "i" && item.content.IsAccept == AcceptStatus.Default)
                        {
                            item.mark.Text = "";
                        }
                        item.ResetMarkStyle();
                    }
                }
                DocumentUtil.ClearProofreadMarks();
            }
            catch (Exception ex)
            {
                Logger.Log("ClearAllProofreadMark", ex);
            }
            // 清空marks
            marks.Clear();
        }


        public void SelectMarkById(int proofreadId)
        {
            SelectMarkById(proofreadId, true);
        }
        /// <summary>
        /// 选中标签
        /// </summary>
        /// <param name="proofreadId"></param>
        public void SelectMarkById(int proofreadId, bool noticeToWeb)
        {
            if (proofreadId == selectProofreadId) return;
            // 取消上一个标签移除
            if (selectProofreadId != -1 && marks.ContainsKey(selectProofreadId))
            {
                var m = marks[selectProofreadId];
                if (m != null && CurrentDocument.Bookmarks.Exists(m.Name))
                {
                    marks[selectProofreadId].UnSelect();
                }
                else
                {
                    marks.Remove(selectProofreadId);
                }
            }
            selectProofreadId = proofreadId;

            if (proofreadId != -1 && marks.ContainsKey(proofreadId))
            {
                var mark = marks[proofreadId].mark;
                if (mark == null) return;
                // 已经不存在该标签了
                if (mark != null && !CurrentDocument.Bookmarks.Exists(mark.Name))
                {
                    marks.Remove(proofreadId);
                    return;
                }
                //object lineNum = (int)mark.Range.Information[WdInformation.wdFirstCharacterLineNumber] - 1;
                //object goToLine = WdGoToItem.wdGoToLine;
                //object goNext = WdGoToDirection.wdGoToNext;
                //Globals.ThisAddIn.Application.ActiveWindow.Selection.GoTo(ref goToLine, ref goNext, ref lineNum);
                //
                //object bookmark = WdGoToItem.wdGoToBookmark;
                //object bookmarkName = mark.Name;
                var targetRange = mark.Range;
                // 选中
                targetRange.Select();
                Globals.ThisAddIn.Application.ActiveWindow.ScrollIntoView(targetRange);//.Selection.GoTo(ref bookmark, ref missing, ref missing, ref bookmarkName);
                
                // 
                //mark.DisableCharacterSpaceGrid = false;
                // 先滚动到可视区域
                //doc.ActiveWindow.ScrollIntoView(mark.Range);
                marks[proofreadId].Select();
                //Globals.ThisAddIn.SendMessageToWeb("select", proofreadId);
            }
            if (noticeToWeb)
            {
                Globals.ThisAddIn.SendMessageToWeb("select-proofread", proofreadId);
            }
        }


        public void InitProofread(List<CorrectContext> list)
        {
            hasProofreaded = true;
            int prevOffset = 0;

            List<int> disabledList = new List<int>();
            List<InsertMarkData> insertMarks = new List<InsertMarkData>();
            foreach (var correct in list)
            {
                if(Logger.LoggerForm != null)
                {
                    Logger.Log(string.Format("correct content:{0}", correct.Insert));
                }
                int currentOffset = correct.SentenceOffset;
                if (correct.CorrectItems != null && correct.CorrectItems.Count > 0)
                {
                    prevOffset = 0;
                    int index = 0;
                    foreach (var item in correct.CorrectItems)
                    {
                        if (marks.ContainsKey(item.Id)) continue;
                        // Logger.Log(string.Format("mark type {0} data {1}->{2}", item.Tag, item.Origin, item.Text));
                        int _prev = prevOffset;
                        bool isDisabled = false;
                        // 判断查找内容是否在原始数据中，否则直跳过
                        if(item.Tag != "i" && item.Origin.Trim().Length > 0)
                        {
                            isDisabled = correct.Insert.IndexOf(item.Origin) == -1;
                        }
                        // 查找对应区域并再该区域添加书签
                        var mark = isDisabled ? null : DocumentUtil.FindRangeAndCreateBookmark(item, correct, CurrentDocument, ref prevOffset);
                        // 防止调用方法中没有更新
                        if (_prev >= prevOffset)
                        {
                            prevOffset = currentOffset + item.Start;
                        }

                        if (item.Tag != "i") index++;
                        if (mark != null)
                        {
                            marks.Add(item.Id, new ProofreadItem(item, correct.Insert, mark, Id));
                            try
                            {
                                if (item.Tag == "i")
                                {
                                    insertMarks.Add(new InsertMarkData()
                                    {
                                        Mark = mark,
                                        InsertLength = item.Text.Length
                                    });
                                }
                                else
                                {
                                    SetMarkStyle(mark);
                                }
                            }
                            catch (Exception e)
                            {
                                Logger.Log(string.Format("mark color error {0}", e.Message));
                            }
                        }
                        else
                        {
                            disabledList.Add(item.Id);
                            var msg = new Dictionary<string, object>{
                                    {"message","没有找到标记对象" },
                                    { "origin",item },
                                    { "origin_correct",correct },
                                    { "new_text",correct.NewText },
                                    { "paragraph_num",correct.ParagraphNumber },
                                };
                            Logger.Log(JsonConvert.SerializeObject(msg));
                        }
                    }
                }
            }
            // 为了避免影响其他文本定位，操作完成后才使用空格填充
            try
            {
                foreach (var item in insertMarks)
                {
                    item.Mark.Text = ToolUtil.GetBlankText(item.InsertLength);
                    SetMarkStyle(item.Mark);
                }
            }
            catch (Exception) { }
            insertMarks.Clear();
            //foreach (var item in marks)
            //{
            //    if (item.Value.mark != null)
            //    {
            //        if (item.Value.content.Tag == "i")
            //        {
            //            item.Value.mark.Text = ToolUtil.GetBlankText(item.Value.content.Text.Length);
            //        }
            //        if (item.Value.content.Color != null)
            //        {
            //            try
            //            {
            //                var color = (WdColor)ColorTranslator.ToOle(Colors.FromHex(item.Value.content.Color));
            //                // 给选区添加背景颜色
            //                item.Value.mark.Shading.BackgroundPatternColor = color;
            //            }
            //            catch (Exception)
            //            {
            //                //item.Value.mark.Shading.BackgroundPatternColor = WdColor.wdColorLightOrange;
            //            }
            //        }
            //    }
            //}

            // 隐藏面板对应校对项
            MainPanelWebMessage.DisabledProofreadItem(disabledList);
        }

        private void SetMarkStyle(Microsoft.Office.Tools.Word.Bookmark mark)
        {
            // 颜色转码
            var color = (WdColor)ColorTranslator.ToOle(Colors.FromHex(Config.TextBackgroundColor));
            // 给选区添加背景颜色
            mark.Shading.BackgroundPatternColor = color;
        }


        public void InitProofreadCache(List<CorrectContext> list,Dictionary<int, ProofreadRangeInfo> itemInfoDic)
        {
            marks.Clear();

            foreach (var correct in list)
            {
                correct.CorrectItems.ForEach(item =>
                {
                    var mark = DocumentUtil.FindBookMarkByCorrect(item);
                    if (mark != null)
                    {
                        var pi = new ProofreadItem(item, correct.Insert, mark, Id);
                        // 是否存在样式信息
                        if (itemInfoDic!= null && itemInfoDic.ContainsKey(item.Id))
                        {
                            // 获取样式信息并还原
                            var info = itemInfoDic[item.Id];
                            try
                            {
                                pi.originColor = info.Color;
                                pi.originBackgroundColor = info.Background;
                                pi.originSize = info.Size;
                            }
                            catch (Exception ex) { Logger.Log(ex); }
                        }
                        marks.Add(item.Id, pi);
                    }
                });
                //marks.Add(item.Id, new ProofreadItem(item.CorrectItems[0], null, Id));
            }
        }

        private void FindMarkByCorrectItem()
        {

        }

        public DocumentContent GetAllParagraphs()
        {
            string rangeText = CurrentDocument.Content.Text;
            string trimText = HostHelper.ReplaceSpecialChars(rangeText, isReplaceMultSpaceLine: true);

            string[] separator = new string[5] { "\r\a", "\a", "\r", "\v", "\f" };
            string[] array4 = rangeText.Split(separator, StringSplitOptions.None);
            string[] array5 = trimText.Split('\n');

            List<string> list = new List<string>();
            var paragraphs = CurrentDocument.Paragraphs;
            int total = paragraphs.Count;
            for (int i = 1; i <= total; i++)
            {
                list.Add(GetParagraphText(paragraphs[i]));
            }

            return new DocumentContent()
            {
                OriginCut = array4,
                TrimCut = array5,
                Paragraphs = list.ToArray(),
            };
        }

        private string GetParagraphText(Paragraph paragraph)
        {
            // 需要
            return GetRangeText(paragraph.Range);
        }

        /// <summary>
        /// 获取文档段落总数
        /// </summary>
        /// <returns></returns>
        public int GetTotalParagraphNumber()
        {
            return CurrentDocument.Paragraphs.Count;
        }

        /// <summary>
        /// 读取文档原始文件并转换成base64
        /// </summary>
        /// <returns></returns>
        public string GetOriginFileData()
        {
            FileStream fs = new FileStream(CurrentDocument.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
            byte[] bytes = new byte[fs.Length];
            fs.Read(bytes, 0, bytes.Length);
            return Convert.ToBase64String(bytes);
        }

        /// <summary>
        /// 采纳校对项
        /// </summary>
        /// <param name="proofreadId"></param>
        /// <param name="status"></param>
        internal void ProcessMark(int proofreadId, int status)
        {
            // 是否存在书签
            if (proofreadId > 0 && marks.ContainsKey(proofreadId))
            {
                hasProcessMark = true;
                // 采纳
                marks[proofreadId].Process(status);
            }
        }

        internal bool Saved()
        {
            if (CurrentDocument.Saved)
            {
                return true;
            }
            if (!hasProofreaded && !CurrentDocument.Saved) // 没有校对前需要提示保存
            {
                return false;
            }
            if (hasProofreaded && hasProcessMark && !CurrentDocument.Saved)
            {
                return false;
            }
            return true;
        }

        public void Save()
        {
            try
            {
                CurrentDocument.Save();
            }catch (Exception ex)
            {
                Logger.Log(ex);
            }
        }
        public void FocusToPanel()
        {
            TaskPane.Visible = true;
            TaskPane.Control.Focus();
        }

        public void Close()
        {
            try
            {
                // 清除标记内存数据
                marks.Clear();
                // 清除区域相关数据
                ranges.Clear();
                // TaskPane.Dispose();
                this.Dispose();
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
            }
        }

        public void ExportResult(string modelType)
        {
            TaskPane.Control.BeginInvoke(new Action(() =>
            {
                DocumentUtil.ExportProofreadResult(modelType);
            }));
        }

        public void ShowUpgrade(string data, bool force)
        {
            TaskPane.Control.BeginInvoke(new Action(() =>
            {
                var upgradeData = JsonConvert.DeserializeObject<UpgradeData>(data);
                var needUpgrade = upgradeData.NeedUpgrade(Config.APP_VERSION);
                //force = force && !Config.UpgradeForcedNotice;

                if (force)
                {
                    // 已经强制更新但被忽略过则不再提示
                    if (Config.UpgradeForcedNotice) return;

                    var result = MessageBox.Show(upgradeData.Message, "是否确认更新", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question);
                    if (result == DialogResult.No)
                    {
                        Config.UpgradeForcedNotice = true;
                        Globals.ThisAddIn.ribbon.SetBtnStatus("disable-by-upgrade", false);
                        return;
                    }
                }

                if (upgradeData.Ext == 1)
                {
                    if (!needUpgrade)
                    {
                        ShowDialog("当前版本为最新版本，无需升级", "", "");
                    }
                    else
                    {
                        if (!force)
                        {
                            // 非强制则再问一次
                            var ret = MessageBox.Show(upgradeData.Message, "是否确认更新", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question);
                            if (ret == DialogResult.No)
                            {
                                Globals.ThisAddIn.ribbon.SetBtnStatus("disable-by-upgrade", false);
                                return;
                            }
                        }

                        Bridge.bridge.OpenUrlWithOsBrowser(upgradeData.DownloadUrl);

                    }
                }
                else
                {
                    Bridge.StartUpgradeProcess();
                }
            }));
        }

        public void ShowSetting()
        {

            TaskPane.Control.BeginInvoke(new Action(() =>
            {
                FormSetting frm = new FormSetting();
                frm.Show();
            }));
        }
        public void ShowWebView(string url, int width, int height, bool dialog)
        {
            TaskPane.Control.BeginInvoke(new Action(() =>
            {
                FormWebView view = new FormWebView(url, width, height);
                if (dialog)
                {
                    view.StartPosition = FormStartPosition.CenterScreen;
                    view.ShowDialog();
                }
                else
                {
                    view.StartPosition = FormStartPosition.CenterParent;
                    view.Show();
                }
            }));
        }

        public Dictionary<int, ProofreadRangeInfo> GetProofreadOriginData()
        {
            Dictionary<int,ProofreadRangeInfo> dic = new Dictionary<int, ProofreadRangeInfo>();
            // 变量文档所有marks 记录mark对应range的背景、大小、颜色
            foreach (var item in marks)
            {
                if (item.Value.mark != null)
                {
                    // 添加到数据
                    dic.Add(item.Key, new ProofreadRangeInfo()
                    {
                        Background = item.Value.originBackgroundColor,
                        Color = item.Value.originColor,
                        Size = item.Value.originSize
                    });
                }
            }
            return dic;
        }

        internal void CheckPanel()
        {
            Logger.Log(CurrentDocument.FullName + $" TaskPane visible {PaneVisible} has " + (TaskPane == null ? "null" : "exists"));
            if (TaskPane == null) CreateTaskPane();
        }
    }
}
