using ComeCapture;
using Common.system;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Principal;
using System.Threading.Tasks;
using System.Windows;
using XHWK.Model;
using XHWK.WKTool.Helpers;
using XHWK.WKTool.Skin;

namespace XHWK.WKTool
{
    public partial class App
    {
        #region 全局变量

        #region 更新需改动

        /// <summary>
        /// 是否为测试版
        /// </summary>
        public static bool isDebug = FileToolsCommon.GetConfigValue("IsDebug") != "0";

        /// <summary>
        /// 参数是否加密
        /// </summary>
        public static bool IsParameterEncryption = FileToolsCommon.GetConfigValue("IsParameterEncryption") != "0";

        #endregion 更新需改动

        #region 接口地址

        /// <summary>
        /// 是否为校外接口
        /// </summary>
        public static bool IsOutsideSchool = FileToolsCommon.GetConfigValue("IsOutsideSchool") == "1";

        /// <summary>
        /// 服务地址
        /// </summary>
        public static Model_ServiceAddress ServiceAddress;

        /// <summary>
        /// 接口地址
        /// </summary>
        public static string apiUrl = isDebug ? "http://schoolapitest.xhkjedu.com" : FileToolsCommon.GetConfigValue("APIRequestAddress");

        /// <summary>
        /// 图片地址
        /// </summary>
        public static string uploadUrl = isDebug ? "http://schoolfiletest.xhkjedu.com/" : FileToolsCommon.GetConfigValue("FileRequestAddress");

        /// <summary>
        /// 展示文件
        /// </summary>
        public static string showImageUrl = isDebug ? "http://schoolstatictest.xhkjedu.com/static/" : FileToolsCommon.GetConfigValue("SchoolfileRequestAddress") + "/static/";

        /// <summary>
        /// 认证接口地址
        /// </summary>
        public static string certapiUrl = isDebug ? "http://scapitest.xhkjedu.com" : FileToolsCommon.GetConfigValue("CertapiRequestAddress");

        #endregion 接口地址

        #region 配置项

        /// <summary>
        /// 是否输出测试记录日志
        /// </summary>
        public static bool IsOutputInfoLog = FileToolsCommon.GetConfigValue("IsOutputInfoLog") != "0";

        /// <summary>
        /// 是否隐藏录屏工具栏
        /// </summary>
        public static bool IsHideSRTool = FileToolsCommon.GetConfigValue("IsHideSRTool") != "0";

        /// <summary>
        /// 皮肤样式 0白 1蓝 2黑色
        /// </summary>
        public static string SkinStyle = FileToolsCommon.GetConfigValue("SkinStyle");

        /// <summary>
        /// 数据存放目录
        /// </summary>
        public static string DataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\XHMicroLesson\\";

        /// <summary>
        /// 摄像头位置
        /// </summary>
        public static string CameraPosition = string.Empty;

        /// <summary>
        /// 摄像头名
        /// </summary>
        public static string CameraName = "";

        /// <summary>
        /// 麦克风名
        /// </summary>
        public static string MicrophoneName = "";

        #endregion 配置项

        #region 记录数据

        /// <summary>
        /// 全局页面数据变量
        /// </summary>
        public static readonly Model_Page PageContextData = new Model.Model_Page();

        /// <summary>
        /// 录屏工具
        /// </summary>
        public static FFMpeg FFmpeg = new FFMpeg();

        /// <summary>
        /// 后台线程帮助类
        /// </summary>
        public static BackgroundWorkerHelper BackgroundWorkerHelper => BackgroundWorkerHelper.GetInstance();

        /// <summary>
        /// 签名
        /// </summary>
        public static string Signature = "";

        public static string secretKey = "nanhuakaizhangjianwangni";

        /// <summary>
        /// 用户信息
        /// </summary>
        public static Model_UserInfo UserInfo;

        /// <summary>
        /// 接口返回消息
        /// </summary>
        public static string ServerMsg = string.Empty;

        /// <summary>
        /// 登录状态 false 未登录 true已登录
        /// </summary>
        public static bool IsLoginType = false;

        /// <summary>
        /// 截图地址
        /// </summary>
        public static string ImgPath = string.Empty;

        /// <summary>
        /// 教材列表
        /// </summary>
        public static List<Model_TsubjectbookList> TsubjectbookList = null;

        /// <summary>
        /// 章节列表
        /// </summary>
        public static List<Model_DirectorList> DirectorList = null;

        /// <summary>
        /// 上传个人空间 入参
        /// </summary>
        public static Model_ResourceAddTwo ResourceAddTwo = null;

        /// <summary>
        /// 是否正在上传
        /// </summary>
        public static bool IsUpLoad = false;

        #endregion 记录数据

        #region 微课数据记录

        /// <summary>
        /// 用户微课列表模型
        /// </summary>
        public static List<Model_WKData> WKDataList;

        /// <summary>
        /// 微课模型
        /// </summary>
        public static Model_WKData WKData;

        /// <summary>
        /// 微课视频列表
        /// </summary>
        public static List<Model_Video> VideoList;

        /// <summary>
        /// 画板模型
        /// </summary>
        public static List<Model_DrawData> PageDrawList = new List<Model_DrawData>();

        #endregion 微课数据记录

        #region 点阵笔

        /// <summary>
        /// 笔序号
        /// </summary>
        public static string PenSerial;

        /// <summary>
        /// 笔状态，是否已连接
        /// </summary>
        public static bool PenStatus = false;

        /// <summary>
        /// 手写板状态，是否已连接
        /// </summary>
        public static bool BoardStatus = false;

        #endregion 点阵笔

        #region 腾千里手写笔

        ///// <summary>
        ///// 铺码服务请求
        ///// </summary>
        //public static DAL_TmatrixCode dAL_TmatrixCode;
        /// <summary>
        /// 腾千里手写笔事件
        /// </summary>
        public static PenEvents TQLPenevents;

        /// <summary>
        /// 腾千里手写笔是否已连接
        /// </summary>
        public static bool TQLPenStatus = false;

        #region 打印

        public static bool gbGenerateBGWithVImage = false;
        public static bool gbGenerateVImage = false;
        public static bool gbGenerateBGWithoutVImage = false;
        public static bool gbGenerateBGWithImage = false;
        public static bool gbGenPageSet = false;
        public static int[] gPointType = new int[5];
        public static int[] gPointDPI = new int[5];
        public static string gTMXElementFileName;
        public static string gNewProjectDirectory;
        public static bool gbElementFileExist { get; set; }

        #endregion 打印

        #endregion 腾千里手写笔

        #region 页面

        /// <summary>
        /// 主页面
        /// </summary>
        public static MainWindow W_XHMicroLessonSystemWindow = null;

        /// <summary>
        /// 倒计时窗口
        /// </summary>
        public static CountdownWindow W_CountdownWindow = null;

        /// <summary>
        /// 录像工具栏
        /// </summary>
        public static ScreenRecordingToolbarWindow W_ScreenRecordingToolbarWindow = null;

        /// <summary>
        /// 登录
        /// </summary>
        public static LoginWindow W_LoginWindow = null;

        /// <summary>
        /// 截图
        /// </summary>
        public static JieTuWindow W_JieTuWindow = null;

        /// <summary>
        /// 批注
        /// </summary>
        public static PracticeWindow W_PracticeWindow = null;

        /// <summary>
        /// 提示窗口
        /// </summary>
        public static PromptWindow W_PromptWindow = null;

        /// <summary>
        /// loding页面
        /// </summary>
        public static LoadDialog myloading;

        /// <summary>
        /// 上传页面
        /// </summary>
        public static UploadWindow W_UploadWindow = null;

        /// <summary>
        /// 最小化工具栏
        /// </summary>
        public static MinToolbar W_MinToolbar = null;

        /// <summary>
        /// 视频剪辑
        /// </summary>
        public static VideoClipWindow W_VideoClipWindow = null;

        #endregion 页面

        #endregion 全局变量

        public App()
        {
            Console.WriteLine(@"初始化APP");
            LogHelper.InitLog4Net();
            myloading = new LoadDialog();
            StopSameProcess();
            Killffmpeg();
            try
            {
                UserInfo = new Model_UserInfo();
                WKDataList = new List<Model_WKData>();
                VideoList = new List<Model_Video>();

                #region 强制以管理员方式运行 修改人：赵耀 修改时间：2020年9月7日

                WindowsIdentity identity = WindowsIdentity.GetCurrent();
                WindowsPrincipal principal = new WindowsPrincipal(identity);

                #endregion 强制以管理员方式运行 修改人：赵耀 修改时间：2020年9月7日

                try
                {
                    if (Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + "Temp")) //清除临时文件
                    {
                        Directory.Delete(AppDomain.CurrentDomain.BaseDirectory + "Temp", true);
                    }
                }
                catch (Exception)
                {
                    // ignored
                }
                if (principal.IsInRole(WindowsBuiltInRole.Administrator))
                {
                    SkinConfig.InitSkin();
                }
                else
                {
                    //创建启动对象
                    System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo
                    {
                        UseShellExecute = true,
                        WorkingDirectory = Environment.CurrentDirectory,
                        FileName = Assembly.GetExecutingAssembly().Location,
                        //设置启动动作,确保以管理员身份运行
                        Verb = "runas"
                    };
                    try
                    {
                        System.Diagnostics.Process.Start(startInfo);
                    }
                    catch
                    {
                        return;
                    }
                    //退出
                    //Current.Shutdown();
                    Environment.Exit(0);
                }
            }
            catch (Exception ex)
            {
                string errMessage = "【进程】(Main):进程意外关闭。 " + ex.Message;
                LogHelper.WriteErrLog(errMessage, ex);
            }
        }

        #region 杀死已存在的进程

        /// <summary>
        /// 结束已运行的程序
        /// </summary>
        private static void StopSameProcess()
        {
            Process current = Process.GetCurrentProcess();
            Process[] processList = Process.GetProcesses();
            foreach (Process process in processList)
            {
                if (process.ProcessName.ToUpper() == "星火微课")
                {
                    if (process.Id != current.Id) //忽略当前进程
                    {
                        try
                        {
                            process.Kill(); //结束进程
                        }
                        catch (Exception)
                        {
                            // ignored
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 杀死正在运行的ffmpeg
        /// </summary>
        public static void Killffmpeg()
        {
            Process[] killProcessArray = Process.GetProcessesByName("ffmpeg");
            foreach (Process killProcess in killProcessArray)
            {
                killProcess.Kill();
            }
        }

        #endregion 杀死已存在的进程

        private void RegisterEvents()
        {
            //Task线程内未捕获异常处理事件
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; //Task异常

            //UI线程未捕获异常处理事件（UI主线程）
            DispatcherUnhandledException += App_DispatcherUnhandledException;

            //非UI线程未捕获异常处理事件(例如自己创建的一个子线程)
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        }

        private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            try
            {
                var exception = e.Exception as Exception;
                if (exception != null)
                {
                    HandleException(exception);
                }
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
            finally
            {
                e.SetObserved();
            }
        }

        //非UI线程未捕获异常处理事件(例如自己创建的一个子线程)
        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            try
            {
                var exception = e.ExceptionObject as Exception;
                if (exception != null)
                {
                    HandleException(exception);
                }
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
        }

        //UI线程未捕获异常处理事件（UI主线程）
        private static void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            try
            {
                HandleException(e.Exception);
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
            finally
            {
                e.Handled = true;
            }
        }

        private static void HandleException(Exception ex)
        {
            //记录日志
            LogHelper.WriteErrLog("未捕获异常：" + ex.Message, ex);
            Current.Shutdown();
        }

        #region 数据保存和读取

        /// <summary>
        /// 保存微课信息
        /// </summary>
        public static void SaveWkData()
        {
            try
            {
                VideoList = VideoList.Where((x, i) => VideoList.FindIndex(z => z.FileGuid == x.FileGuid) == i).ToList();
                WKData.VideoList = VideoList;
                if (WKDataList != null)
                {
                    WKDataList.RemoveAll(x => x.WkPath == WKData.WkPath);
                }
                else
                {
                    WKDataList = new List<Model_WKData>();
                }
                WKDataList.Add(WKData);
                string wkDateXmlStr = XmlUtilHelper.XmlSerialize(WKDataList);
                string savePath = FileToolsCommon.GetFileAbsolutePath("/Data/");
                FileToolsCommon.CreateDirectory(savePath);
                string saveName = savePath + "WkDate.d";
                FileToolsCommon.DeleteFile(saveName);
                FileToolsCommon.WriteText(saveName, wkDateXmlStr);
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog("【微课数据保存】（SaveWkData）保存失败：" + ex.Message, ex);
            }
        }

        /// <summary>
        /// 读取微课信息
        /// </summary>
        public static void ReadWkData(string wkPath)
        {
            try
            {
                string savePath = FileToolsCommon.GetFileAbsolutePath("/Data/");
                FileToolsCommon.CreateDirectory(savePath);
                string saveName = savePath + "WkDate.d";
                //文件若存在则读取
                if (FileToolsCommon.IsExistFile(saveName))
                {
                    string wkDateXmlStr = FileToolsCommon.FileToString(saveName);
                    WKDataList = XmlUtilHelper.DESerializer<List<Model_WKData>>(wkDateXmlStr);
                    foreach (Model_WKData wklist in WKDataList)
                    {
                        //移除找不到视频的微课数据
                        wklist.VideoList.RemoveAll(x => !FileToolsCommon.IsExistFile(x.VideoPath));
                    }
                    if (WKDataList.Exists(x => x.WkPath == wkPath))
                    {
                        WKData = WKDataList.Find(x => x.WkPath == wkPath);
                        VideoList = new List<Model_Video>();
                        WKData.VideoList = WKData.VideoList.Where((x, i) => WKData.VideoList.FindIndex(z => z.FileGuid == x.FileGuid) == i).ToList();
                        VideoList = WKData.VideoList;
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog("【微课数据读取】（ReadWkData）读取失败：" + ex.Message, ex);
            }
        }

        /// <summary>
        /// 保存画板数据
        /// </summary>
        public static void SaveDraw()
        {
            try
            {
                if (PageDrawList == null)
                {
                    return;
                }
                if (PageDrawList.Count < 1)
                {
                    return;
                }
                FileToolsCommon.CreateDirectory(WKData.WkPath);
                string savePath = WKData.WkPath + "PageData.xml";
                FileToolsCommon.DeleteFile(savePath);
                string pageDataXmlStr = XmlUtilHelper.XmlSerialize(PageDrawList);
                FileToolsCommon.WriteText(savePath, pageDataXmlStr);
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog("【画板数据保存】（SaveDraw）保存失败：" + ex.Message, ex);
            }
        }

        /// <summary>
        /// 读取文件
        /// </summary>
        public static void ReadDrawData()
        {
            try
            {
                PageDrawList = new List<Model_DrawData>();
                string savePath = WKData.WkPath + "PageData.xml";
                if (FileToolsCommon.IsExistFile(savePath))
                {
                    string pageDataXmlStr = FileToolsCommon.FileToString(savePath);
                    PageDrawList = XmlUtilHelper.DESerializer<List<Model_DrawData>>(pageDataXmlStr);
                }
                else
                {
                    PageDrawList = new List<Model_DrawData>();
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog("【画板数据读取】(ReadDraw)读取失败：" + ex.Message, ex);
            }
        }

        #endregion 数据保存和读取

        #region 服务地址数据

        /// <summary>
        /// 服务地址存储到本地
        /// </summary>
        public static void SaveServiceAddressData()
        {
            try
            {
                if (ServiceAddress == null)
                {
                    return;
                }
                string dateXmlStr = XmlUtilHelper.XmlSerialize(ServiceAddress);
                string savePath = DataPath;
                FileToolsCommon.CreateDirectory(savePath);
                string saveName = savePath + (isDebug ? "ServiceAddress_debug.xml" : "ServiceAddress_release.xml");
                Console.WriteLine(@"保存路径为:");
                FileToolsCommon.DeleteFile(saveName);
                FileToolsCommon.WriteText(saveName, dateXmlStr);
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog("【服务地址存储】（SaveServiceAddressData）保存失败：" + ex.Message, ex);
            }
        }

        /// <summary>
        /// 从本地读取服务地址
        /// </summary>
        public static void ReadServiceAddressData()
        {
            try
            {
                string savePath = DataPath;
                FileToolsCommon.CreateDirectory(savePath);
                string saveName = savePath + (isDebug ? "ServiceAddress_debug.xml" : "ServiceAddress_release.xml");
                //文件若存在则读取
                if (FileToolsCommon.IsExistFile(saveName))
                {
                    string dateXmlStr = FileToolsCommon.FileToString(saveName);
                    ServiceAddress = XmlUtilHelper.DESerializer<Model_ServiceAddress>(dateXmlStr);
                    SwitchAddress();
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog("【服务地址读取】（ReadServiceAddressData）读取失败：" + ex.Message, ex);
            }
        }

        /// <summary>
        /// 切换校内外网
        /// </summary>
        public static void SwitchAddress()
        {
            try
            {
                apiUrl = IsOutsideSchool ? ServiceAddress.wapi : ServiceAddress.napi;
                uploadUrl = (IsOutsideSchool ? ServiceAddress.wfile : ServiceAddress.nfile) + "/";
                showImageUrl = (IsOutsideSchool ? ServiceAddress.wdown : ServiceAddress.ndown) + "/static/";
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog("【服务地址切换】（SwitchAddress）服务复制切换失败，请求地址为空！", ex);
            }
        }

        #endregion 服务地址数据

        /// <summary>
        /// 内存释放压缩
        /// </summary>
        /// <param name="e">
        /// </param>
        protected override void OnStartup(StartupEventArgs e)
        {
            RegisterEvents();
            base.OnStartup(e);
        }
    }
}
