using System;
using Newtonsoft.Json;
using System.Threading;
using Microsoft.Office.Interop.Word;
using System.Windows.Forms;
using System.IO;
using AIProofread.Controls;
using UtilLib;
using AIProofread.Model;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Text;
//using CustomTaskPane = Microsoft.Office.Core.CustomTaskPane;
//using CustomTaskPane = Microsoft.Office.Tools.CustomTaskPane;
//using NPOI.SS.Formula.Functions;

namespace AIProofread
{

    public partial class ThisAddIn
    {

        public static SynchronizationContext FmainThreadContext;

        public string AddinName = " ";
        /// <summary>
        /// 最小宽度
        /// </summary>
        public static int MinWidth = 0;
        /// <summary>
        /// 启动路径
        /// </summary>
        public string applicationStartupPath;

        /// <summary>
        /// 校对面板
        /// </summary>
        public ProofreadMainControl proofreadPanel;
        /// <summary>
        /// 工具栏
        /// </summary>
        public Ribbon1 ribbon;
        /// <summary>
        /// 当前word application
        /// </summary>
        public static Microsoft.Office.Interop.Word.Application CurrentWordApplication;

        ///// <summary>
        ///// 智能标记集合
        ///// </summary>
        //internal SmartTagCollection VstoSmartTags;

        /// <summary>
        /// 所有文档信息
        /// </summary>
        public DocumentList documentList = new DocumentList();
        /// <summary>
        /// 当前文档信息
        /// </summary>
        public DocumentInfo ActiveDocument { get; set; }
        /// <summary>
        /// 智能常识检测对话框  = new FormCommonsenseDetection()
        /// </summary>
        public FormCommonsenseDetection formCommonsenseDetection;
        public bool IsWPS { get; set; }

        public List<FormLogin> LoginFormList = new List<FormLogin>();
        public static bool AppRunning = true;
        private System.Timers.Timer _timer;

        //public override void BeginInit()
        //{
        //    base.BeginInit();
        //    CurrentWordApplication = Application;
        //    CurrentWordApplication.DocumentChange += CurrentWordApplication_DocumentChange;
        //}

        public void ShowDetection()
        {
            if (formCommonsenseDetection == null || formCommonsenseDetection.IsDisposed)
            {
                formCommonsenseDetection = new FormCommonsenseDetection();
            }
            //formCommonsenseDetection.ShowInTaskbar = true;
            formCommonsenseDetection.Show();
            // 显示在最前面
            formCommonsenseDetection.Activate();
        }
        public void HideDetection()
        {
            formCommonsenseDetection.Close();
            formCommonsenseDetection = null;
        }

        private void ProcessApplicationException(object sender, UnhandledExceptionEventArgs e)
        {
            Logger.Log("UnhandledException", e.ExceptionObject as Exception);
        }

        private void ProcessApplicationFormException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            Logger.Log("ProcessApplicationFormException", e.Exception);
        }

        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            try
            {
                InitDeviceId();
                AppInitialize();
                //formCommonsenseDetection.ShowInTaskbar = false;
                //formCommonsenseDetection.Show();

                Logger.Log("ThisAddIn_Startup IS_WPS --> " + IsWPS);
                // 捕获全局异常
                AppDomain.CurrentDomain.UnhandledException += ProcessApplicationException;
                System.Windows.Forms.Application.ThreadException += ProcessApplicationFormException;

                // 处理文档事件
                Application.DocumentOpen += Application_DocumentOpen;
                Application.DocumentBeforeClose += Application_DocumentBeforeClose;

                Application.WindowActivate += Application_WindowActivate;
                //Application.WindowDeactivate += Application_WindowDeactivate;
                Application.DocumentBeforeSave += Application_DocumentBeforeSave;
                
                (Application as ApplicationEvents4_Event).NewDocument += Application_NewDocument;
                Application.DocumentChange += Application_DocumentChange;
                // 选区发生变化事件
                this.Application.WindowSelectionChange += Application_WindowSelectionChange;
                //CheckPluginUpgradeInfo();
                // CheckDocumentClosedTick();

                // 定时检测文档是否关闭
                _timer = new System.Timers.Timer(10000);
                _timer.Elapsed += CheckDocumentClosed;
                _timer.AutoReset = true;
                _timer.Enabled = true;
            }
            catch (Exception ex1)
            {
                Logger.Log("Startup Error" + ex1.ToString());
            }
        }

        // 异步获取设备唯一标识
        public void InitDeviceId()
        {
            System.Threading.Tasks.Task.Run(() =>
            {
                try
                {
                    var deviceId = Tools.GetDeviceId();
                    if (string.IsNullOrEmpty(deviceId))
                    {
                        deviceId = Tools.GetDeviceId();
                    }
                    if (!string.IsNullOrEmpty(deviceId))
                    {
                        Config.DeviceId = deviceId;
                        Logger.Log("设备唯一标识：" + deviceId);
                    }
                }
                catch (Exception ex)
                {
                    Logger.Log("InitDeviceId Error:" + ex.ToString());
                }
            });
        }


        public void CheckDocumentClosed(object sender, System.Timers.ElapsedEventArgs e)
        {
            var existsList = new List<string>();
            try
            {
                var docList = CurrentWordApplication.Documents;
                if (documentList.Count == 0 || docList.Count == existsList.Count) return;
                existsList.Clear();
                foreach (Document item in docList)
                {
                    existsList.Add(item.FullName);
                }

                // 检测文档是否关闭
                for (int i = documentList.documentList.Count - 1; i >= 0; i--)
                {
                    var item = documentList.documentList[i];
                    // 可能出现另存问题 所以需要更新文件名称
                    var oldName = item.fileName;
                    var currentName = item.CurrentDocument.FullName;
                    if(oldName != currentName)
                    {
                        item.fileName = currentName;
                    }
                    if (!existsList.Contains(currentName))
                    {
                        Logger.Log("检测到文档关闭，已移除：" + currentName);
                        try
                        {
                            item.RunInMainThread(() =>
                            {
                                item.Dispose();
                            });
                        }
                        catch (Exception ext)
                        {
                            Logger.Log(ext);
                        }

                        try
                        {
                            documentList.Remove(item);
                        }
                        catch (Exception ext)
                        {
                            Logger.Log(ext);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
            }
            //await System.Threading.Tasks.Task.Run(() =>
            //    {
            //        
            //        while (AppRunning)
            //        {
            //            Thread.Sleep(10000); // 暂停10s


            //        }
            //    });
        }

        async void CheckPluginUpgradeInfo()
        {
            await System.Threading.Tasks.Task.Run(() =>
            {
                try
                {
                    // 检测升级信息
                    Bridge.bridge.CheckPluginUpgrade();
                }
                catch (Exception ex)
                {
                    Logger.Log("检测升级信息异常: " + ex.ToString());
                }
            });
        }

        private void Application_DocumentBeforeSave(Document originDocument, ref bool SaveAsUI, ref bool Cancel)
        {
            Logger.Log("DocumentSave", originDocument.Name + "\r\n");
            if (CurrentWordApplication.Documents.Count == 0)
            {
                return;
            }

            if (ActiveDocument == null) return;
            // TODO 完成缓存保存

        }

        //public DocumentInfo ActiveDocument()=> documentList.GetActiveDocument();

        private void AppInitialize()
        {
            CurrentWordApplication = Application;
            // 初始化配置
            InitAppByConfig();
            // 主线程
            FmainThreadContext = SynchronizationContext.Current;

            // 启动地址
            applicationStartupPath = System.Windows.Forms.Application.StartupPath;
            // 判断是否是WPS
            if (applicationStartupPath.Contains("WPS"))
            {
                Config.IS_WPS = true;
                IsWPS = true;

                try
                {
                    Globals.Ribbons.Ribbon1.InitWPS();
                }
                catch (Exception ex)
                {
                    Logger.Log("Init WPS Error " + ex.Message);
                }
            }
            string verTextFile = Config.APP_BASE_DIR + Path.GetFileName("app_version.txt");
            try
            {
                File.WriteAllText(verTextFile, Config.APP_VERSION);
            }
            catch (Exception ex)
            {
                Logger.Log("Write App Version Error " + ex.Message);
            }
        }

        private void InitAppByConfig()
        {
            try
            {
                if (File.Exists(Config.CONFIG_FILE))
                {
                    string content = File.ReadAllText(Config.CONFIG_FILE);
                    Logger.Log("INIT", "Found app.json " + content);
                    if (content == null || content.Length == 0) return;
                    AppConfig config = JsonConvert.DeserializeObject<AppConfig>(content);

                    // 插件网址
                    if (!string.IsNullOrEmpty(config.AppUrl))
                    {
                        Config.WEB_PATH = config.AppUrl;
                    }
                    // 运行环境
                    if (!string.IsNullOrEmpty(config.Environment))
                    {
                        Config.APP_ENV = config.Environment == "dev" ? AppEnvironment.Dev : (
                                config.Environment == "test" ? AppEnvironment.Test : AppEnvironment.Prod
                            );
                    }
                    Config.RUN_IN_DEBUG = config.AppRunInDebug;
                    if (Config.APP_ENV != AppEnvironment.Prod && this.ribbon != null)
                    {
                        this.ribbon.ShowDebug();
                    }
                }
            }
            catch (Exception) { }
        }

        private void Application_DocumentChange()
        {
            // 检测是否存在打开的文档
            if (CurrentWordApplication.Documents.Count == 0)
            {
                return;
            }
            //var document = CurrentWordApplication.ActiveDocument;
            // 设置当前文档
            ActiveDocument = documentList.SetActiveDocument(CurrentWordApplication.ActiveDocument);
            ActiveDocument.CheckBtnStatus();
            CheckDocumentClosed(null, null);
            Logger.Log("Application_DocumentChange -- " + ActiveDocument.fileName);
        }

        public void SetActiveDocument(Document doc)
        {
            ActiveDocument = documentList.SetActiveDocument(doc);
        }

        private void Application_WindowDeactivate(Document doc, Window Wn)
        {
            //Logger.Log("Application_WindowDeactivate -- " + doc.FullName + " visible:");
            //HidePanel(Doc);
            // 处理wps直接资源管理器新开文档面板闪烁问题
            //if (IsWPS) { 
            //    this.currentDocumentTaskPane.Visible = false;
            //}
        }

        /// <summary>
        /// 激活文档
        /// </summary>
        /// <param name="activeDoc"></param>
        /// <param name="Wn"></param>
        private void Application_WindowActivate(Document activeDoc, Window Wn)
        {
            ActiveDocument = documentList.SetActiveDocument(activeDoc);
            Logger.Log("Application_WindowActivate -- " + ActiveDocument.fileName);
            //// 当前文档添加书签集合
            //if (!allMarks.ContainsKey(activeDoc))
            //{
            //    allMarks[activeDoc] = new Dictionary<int, ProofreadItem>();
            //}
            ////ShowPanel(Doc);
            //// 创建面板
            //if (!taskPanels.ContainsKey(activeDoc))
            //{
            //    ShowPanel(activeDoc, false);
            //    panelsVisibleStatus.Add(activeDoc, false);
            //}
            //// 设置当前面板为新创建的面板
            //this.currentDocumentTaskPane = taskPanels[activeDoc];
            //if (IsWPS)
            //{
            //    HideOtherPanel(activeDoc);
            //}
            //if (panelsVisibleStatus.ContainsKey(activeDoc) && panelsVisibleStatus[activeDoc])
            //{
            //    taskPanels[activeDoc].Visible = true;
            //}
        }

        /// <summary>
        /// 关闭文档
        /// </summary>
        /// <param name="currentDoc"></param>
        /// <param name="Cancel"></param>
        private void Application_DocumentBeforeClose(Document currentDoc, ref bool Cancel)
        {
            var doc = documentList.Get(currentDoc);
            if (doc != null)
            {
                doc.HidePane();
            }
            Logger.Log("DocumentBeforeClose", currentDoc.FullName);
            //if (allMarks.ContainsKey(currentDoc))
            //{
            //    allMarks.Remove(currentDoc);
            //}

            //DisposePanel(currentDoc);
        }

        //public void ActiveCurrentDocumentMarks(Document document)
        //{
        //    // 判断是否存在 没有的话初始化
        //    var currentDoc = document ?? Application.ActiveDocument ;
        //    if (!allMarks.ContainsKey(currentDoc))
        //    {
        //        allMarks[currentDoc] = new Dictionary<int, ProofreadItem>();
        //    }
        //    Bridge.marks = allMarks[currentDoc];
        //}

        private void Application_NewDocument(Document doc)
        {
            Logger.Log("NewDocument" + doc.Name);
        }

        private void Application_DocumentOpen(Document doc)
        {
            Logger.Log("DocumentOpen " + doc.Name);
        }


        public int GetMinWidth()
        {
            return MinWidth;
        }

        public void Send(SendOrPostCallback d)
        {
            FmainThreadContext.Send(d, null);
        }

        //private void ProofreadPanel_SizeChanged(object sender, EventArgs e)
        //{
        //    // 处理最小宽度
        //    if (customTaskPane != null && customTaskPane.Width < MinWidth && customTaskPane.Visible)
        //    {
        //        SendKeys.Send("{ESC}");
        //        customTaskPane.Width = MinWidth;
        //    }
        //}

        private void Application_WindowSelectionChange(Selection s)
        {
            ribbon.ParseSelectionChange(s);

            if (s.Bookmarks != null)
            {
                if (s.Range.Start == s.Range.End) // 说明是点击呀
                {
                    //var count = s.Bookmarks.Count;
                    if (s.Bookmarks.Count >= 1) // 只有这一个
                    {
                        foreach (Bookmark item in s.Bookmarks)
                        {
                            int proofreadId = Config.GetBookmarkIdByName(item.Name);
                            if (proofreadId > 0)
                            {
                                // 只选择第一个书签
                                // TODO: 优化
                                //Bridge.bridge.SelectMarkById(proofreadId, 0);
                                ActiveDocument?.SelectMarkById(proofreadId, true);
                                return;
                            }
                        }
                    }
                }
            }
            //Bridge.bridge.SelectMarkById(-1, 0);
        }

        public int MyProperty { get; set; }

        public void SendMessageToWeb(string msg, object data)
        {
            // 先显示panel
            //var panel = this.ShowPanel(Application.ActiveDocument, true);
            //SendMessageToWeb(panel.Control, msg, data);
            ActiveDocument?.SendMessageToWeb(msg, data);
        }

        // 显示面板
        public void ShowPanel()
        {
            ActiveDocument?.ShowPane();
        }

        // 隐藏面板
        public void HidePanel()
        {
            ActiveDocument?.HidePane();
        }

        /// <summary>
        ///  隐藏所有面板
        /// </summary>
        public void HideAllPanel()
        {
            this.documentList.HideAllPane();
        }

        /// <summary>
        /// 显示登录窗口
        /// </summary>
        /// <param name="action"></param>
        public void ShowLoginForm(string action)
        {
            // 关闭之前的窗口
            //if(LoginFormList.Count > 0){
            //    LoginFormList.ForEach(f => f.Close());
            //}
            //LoginFormList.Add(frm);
            ActiveDocument?.ShowLogin(action);
        }

        /// <summary>
        /// 清理所有面板
        /// </summary>
        //void ClearPanels()
        //{
        //    taskPanels.Values.ToList().ForEach(p =>
        //    {
        //        try
        //        {
        //            p.Dispose();
        //        }
        //        catch (Exception ex)
        //        {
        //            Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
        //            Logger.Log(ex.Message + "\n" + ex.StackTrace);
        //        }
        //    });
        //    taskPanels.Clear();
        //}

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
            // PanelModule.DisposeCTP();
            //this.proofreadPanel.Dispose();
            // 取消捕获全局异常事件
            AppDomain.CurrentDomain.UnhandledException -= ProcessApplicationException;
            System.Windows.Forms.Application.ThreadException -= ProcessApplicationFormException;
            Logger.Log("shutdown");
            documentList.Clear();
            if (_timer != null)
            {
                _timer.Stop();
            }
        }

        public void SyncLogout()
        {
            ribbon.ProcessLogout();
            //taskPanels.Values.ToList().ForEach(p =>
            //{
            //    try
            //    {
            //        // 同步登录失败信息
            //        SendMessageToWeb(p.Control, "async-logout", null);
            //    }
            //    catch (Exception ex)
            //    {
            //        Logger.Log("async-logout:", ex);
            //    }
            //});

        }

        public void SetDocumentId(Document document, int id)
        {
            var doc = documentList.Get(document);
            if (doc != null) doc.Id = id;
        }

        public DocumentInfo GetDocumentById(int id)
        {
            return id <= 0 ? ActiveDocument : documentList.GetById(id);
        }


        /// <summary>
        /// 清除所有标记
        /// </summary>
        public void ClearAllProofreadMark()
        {
            ActiveDocument?.ClearAllProofreadMark();
            //Globals.ThisAddIn.SendMessageToWeb("clear-tips", null);
        }

        public void ShowDialog(string message, string confirmText, string confirmAction)
        {
            ActiveDocument?.ShowDialog(message, confirmText, confirmAction);
        }
        public void ShowMessage(string message, int closeDelay)
        {
            ActiveDocument?.ShowMessage(message, closeDelay);
        }


        //public string LoadCacheByPath()
        //{

        //}

        //public void SaveCache(string cache)
        //{

        //}


        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }

        public void InitProofreadCacheList(List<CorrectContext> list, Dictionary<int, ProofreadRangeInfo> dics)
        {
            ActiveDocument?.InitProofreadCache(list, dics);
        }

        #endregion


    }
}
