using Microsoft.Win32;
using SWRIS.Core;
using SWRIS.Extensions;
using SWRIS.Models;
using SWRIS.Properties;
using SWRIS.Services;
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.SelfHost;
using System.Windows;
using System.Windows.Threading;

namespace SWRIS
{
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
        public static ConfigModel Config { get; set; }
        public static TcpServerFrame TcpServer { get; set; }
        public static CalibrationCore Calibration { get; set; }
        public static DataCenterModel DataCenter { get; set; }
        public static HistoryCleanupService HistoryCleanup { get; set; }

        public App()
        {
            //首先注册开始和退出事件
            if (!Settings.Default.IsDebug)
            {
                Startup += new StartupEventHandler(App_Startup);
                if (!HslCommunication.Authorization.SetAuthorizationCode("946778b1-967c-4e05-beab-7f47bb248b71"))
                {
                    LogHelper.Info("HSL授权失败");
                    return;
                }
            }
            //PDF初始化配置
            QuestPDF.Settings.License = QuestPDF.Infrastructure.LicenseType.Community;
            QuestPDF.Settings.CheckIfAllTextGlyphsAreAvailable = false;
        }
        private void InitSoftAuthorize()
        {
            if (!SoftAuth.IsAuthorizeSuccess())
            {
                SoftAuthDialog authDialog = new SoftAuthDialog();
                var result = authDialog.ShowDialog();
                if (result != true)
                {
                    Environment.Exit(0);
                }
            }
        }
        private static SingleInstanceManager _singleInstanceManager;
        public static void SwitchToExistingInstance(string processName)
        {
            _singleInstanceManager?.SwitchToExistingInstance(processName);
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            #region 阻止系统睡眠，阻止屏幕关闭。
            SystemSleep.PreventForCurrentThread();
            #endregion

            #region 避免程序多次启动
            _singleInstanceManager = new SingleInstanceManager("SWRIS");
            // 检查是否已有实例运行
            if (_singleInstanceManager.IsAlreadyRunning())
            {
                // 切换到已有实例
                _singleInstanceManager.SwitchToExistingInstance();
                Shutdown();
                return;
            }

            #endregion

            Config = ConfigHelper.Read();
            if (Config == null)
            {
                LogHelper.Error("读取配置文件失败");
                Environment.Exit(0);
            }
            if (!Tools.CheckIpAddressExists(Config.IpAddress))
            {
                MessageBox.Show($"当前在用网卡的IP地址中没有发现[{Config.IpAddress}]，请检查网络配置", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                Environment.Exit(0);
            }
            if (Tools.CheckPortInUse(Config.Port))
            {
                MessageBox.Show("当前配置的端口已被占用，请更换端口或关闭占用该端口的程序", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                Environment.Exit(0);
            }

            if (Settings.Default.IsDebug)
            {
                SetAutoStart(false);
            }
            else
            {
                InitSoftAuthorize();
                SetAutoStart(true);
                // 创建桌面快捷方式
                Tools.CreateShortcut(Assembly.GetExecutingAssembly().Location, Config.AppName);
            }
            // 显示启动画面
            var splashScreen = new SplashScreen("Resources/loading.png");
            splashScreen.Show(false, true);
            Task.Run(async () =>
            {
                SqLiteBaseRepository.CreateDatabase();

                //初始化TcpServer
                TcpServer = new TcpServerFrame(Config.IpAddress, Config.Port);

                //初始化标定模块
                Calibration = new CalibrationCore(Config.Calibration);

                //初始化数据中心能模块
                DataCenter = new DataCenterModel(Config.Equipments, Config.Calibration.Limits);

                //初始化清理计划模块
                HistoryCleanup = new HistoryCleanupService();
                HistoryCleanup.StartScheduledCleanup();

                // 数据加载完成后，在UI线程更新
                await Current.Dispatcher.InvokeAsync(() =>
                {
                    splashScreen.Close(TimeSpan.FromMilliseconds(200));
                    var mainWindow = new MainWindow
                    {
                        Height = SystemParameters.PrimaryScreenHeight,
                        Width = SystemParameters.PrimaryScreenWidth
                    };
                    mainWindow.Activate();
                    mainWindow.Show();
                });
            });
            base.OnStartup(e);
        }
        public static bool UpdateEquipment(EquipmentModel equipment)
        {
            if (equipment == null) return false;

            var existingEquipment = Config.Equipments.FirstOrDefault(e => e.IpAddress == equipment.IpAddress);
            if (existingEquipment == null) return false;

            // 更新设备信息
            Mapping.AssignFrom(existingEquipment, equipment);

            return true;
        }
        private void StartHttpServer()
        {
            //添加防火墙8002端口允许出站规则
            FirewallHelper.CreateTCPOutRule(Assembly.GetEntryAssembly().Location, remotePorts: "8002");
            var config = new HttpSelfHostConfiguration($"http://{Tools.GetIpAddress()}:{8002}");
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(name: "DefaultApi",
                                       routeTemplate: "api/{controller}/{action}",
                                       defaults: new { id = RouteParameter.Optional });
            new HttpSelfHostServer(config).OpenAsync();
        }

        private void App_Startup(object sender, StartupEventArgs e)
        {
            //UI线程未捕获异常处理事件
            DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
            //Task线程内未捕获异常处理事件
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
            //非UI线程未捕获异常处理事件
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        }

        void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            try
            {
                LogHelper.Error("UI线程异常:" + e.Exception.Message, e.Exception);
            }
            catch (Exception ex)
            {
                LogHelper.Error("UI线程异常trycatch:" + ex.Message, ex);
            }
            finally
            {
                e.Handled = true;
            }
        }
        void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            try
            {
                var exception = e.ExceptionObject as Exception;
                if (exception != null)
                {
                    LogHelper.Error("非UI线程发生致命错误", exception);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("非UI线程发生致命错误trycatch", ex);
            }
            finally
            {
                //此时程序出现严重异常，将强制结束退出
                Current.Shutdown();
                Process.Start(ResourceAssembly.Location);//重启软件
            }
        }

        void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            try
            {
                var exception = e.Exception as Exception;
                if (exception != null)
                {
                    LogHelper.Error("Task线程异常：" + exception.Message, exception);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("Task线程异常trycatch：" + ex.Message, ex);
            }
            finally
            {
                e.SetObserved();
            }
        }
        /// <summary>  
        /// 修改程序在注册表中的键值  
        /// </summary>  
        /// <param name="isAuto">true:开机启动,false:不开机自启</param> 
        public static void SetAutoStart(bool isAuto, bool showInfo = true)
        {
            string appName = Config.AppName;
            try
            {
                using (RegistryKey rLocal = Registry.CurrentUser)
                using (RegistryKey rRun = rLocal.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true))
                {
                    if (rRun == null) return;

                    if (isAuto)
                    {
                        string currentPath = Process.GetCurrentProcess().MainModule.FileName;
                        object existingValue = rRun.GetValue(appName);

                        // 只有当值不存在或路径不同时才更新
                        if (existingValue == null || !currentPath.Equals(existingValue.ToString(), StringComparison.OrdinalIgnoreCase))
                        {
                            rRun.SetValue(appName, currentPath);
                        }
                    }
                    else
                    {
                        // 如果存在则删除
                        if (rRun.GetValue(appName) != null)
                        {
                            rRun.DeleteValue(appName, false);
                        }
                    }
                }
            }
            catch (UnauthorizedAccessException)
            {
                if (showInfo)
                {
                    MessageBox.Show("需要管理员权限才能修改开机启动设置", "权限不足");
                }
            }
            catch (Exception ex)
            {
                if (showInfo)
                {
                    MessageBox.Show($"修改开机启动设置时出错: {ex.Message}", "错误");
                }
            }
        }
        public static async void RestartApplication()
        {
            try
            {
                _singleInstanceManager?.Dispose();
                string currentExecutablePath = Process.GetCurrentProcess().MainModule.FileName;
                // 启动新进程
                Process.Start(currentExecutablePath);

                // 安全关闭
                Current?.Dispatcher.Invoke(() =>
                {
                    Current.Shutdown();
                });
            }
            catch (Exception ex)
            {
                // 记录错误日志
                MessageBox.Show($"重启失败: {ex.Message}");
            }
        }
        protected override void OnExit(ExitEventArgs e)
        {
            TcpServer?.Dispose();
            Calibration?.Dispose();
            HistoryCleanup?.Dispose();
            _singleInstanceManager?.Dispose();
            // 恢复此线程曾经阻止的系统休眠和屏幕关闭。
            SystemSleep.RestoreForCurrentThread();
            base.OnExit(e);
        }
    }
}
