using Common;
using ADP.ViewModels;
using ADP.ViewModels.Dialogs;
using ADP.Views;
using ADP.Views;
using ADP.Views.Dialogs;
using Logger;
using Notifications.Wpf.Core;
using ORM;
using Service.Implement;
using Service.Interface;
using System.Configuration;
using System.Data;
using System.Reflection;
using System.Windows;
using UIShare.PubEvent;
using static System.Runtime.InteropServices.JavaScript.JSType;
using UIShare.GlobalVariable;
using UIShare;
using System;
using DeviceCommand.Devices;
using DeviceCommand.Base;
using AutoMapper;
using Microsoft.Extensions.Logging.Abstractions;
using ADP.Profiles;
using 加密狗;

namespace ADP
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : PrismApplication
    {
        protected override Window CreateShell()
        {
            //UI线程未捕获异常处理事件
            this.DispatcherUnhandledException += OnDispatcherUnhandledException;
            //Task线程内未捕获异常处理事件
            TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
            ////多线程异常
            AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
            return Container.Resolve<ShellView>();
        }
        private void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            LoggerHelper.Error(e.Exception.Message, e.Exception.StackTrace);
        }

        private void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            LoggerHelper.Error(e.Exception.Message, e.Exception.StackTrace);
        }

        private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            //记录dump文件
            Exception ex = e.ExceptionObject as Exception;
            MiniDump.TryDump($"dumps\\Error_{DateTime.Now:yyyy-MM-dd HH-mm-ss-ms}.dmp", MiniDump.Option.WithFullMemory, ex);
        }
        protected override void OnInitialized()
        {
            // 配置全局日志分发器：按 CurrentScope 路由到对应 LogArea
            var globalInfo = Container.Resolve<GlobalInfo>();
            LoggerHelper.Progress = new ScopeLogDispatcher(globalInfo);

            //初始化数据库
            DatabaseConfig.SetTenant(10001);
            DatabaseConfig.InitSqlite();
            DatabaseConfig.CreateDatabaseAndCheckConnection(createDatabase: true, checkConnection: true);
            SqlSugarContext.InitDatabase();
            //显示登录窗口
            var login = Container.Resolve<LoginModuleView>();
            var re = Container.Resolve<IRegionManager>();
            RegionManager.SetRegionManager(login, re);
            RegionManager.SetRegionManager(Application.Current.MainWindow, re);
            login.Show();
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                base.OnStartup(e);
                return;
            }

            string strUserSn = "ACA89B2C1194650D4E93D97BE189FFCC";
            string strApiKey = "C6D01BCD442347822876F8232245DE9422643C167B8C61CE4DF6049990E7395588675A8FC6AA4BF7AD353D669C993236BEA83F77551753885A47AF34185CC3A7";

            Byte[] buffer = new Byte[256];
            buffer = System.Text.Encoding.Default.GetBytes(strUserSn);
            uint retcode;
            retcode = 加密狗驱动类.验证加密狗SN(buffer);
            if (retcode != 0)
            {
                MessageBox.Show(string.Format("设置UserSN失败 error code: 0x{0:x}", retcode));
                return;
            }

            uint count = 0;
            retcode = 加密狗API类.VikeyFind(ref count);
            if (retcode != 0 || count == 0)
            {
                MessageBox.Show("未找到加密狗");
                return;
            }

            buffer = System.Text.Encoding.Default.GetBytes(strApiKey);
            retcode = 加密狗驱动类.验证加密狗APIkey(0, buffer);
            if (retcode != 0)
            {
                MessageBox.Show(string.Format("设置api密钥失败 error code: 0x{0:x}", retcode));
                return;
            }

            var remaining = 加密狗驱动类.检查剩余时间(0);
            if (remaining <= TimeSpan.Zero)
            {
                MessageBox.Show("加密狗已到期或未能读取时间，请联系供应商。", "加密狗验证失败", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            base.OnStartup(e);
        }
        protected override void RegisterRequiredTypes(IContainerRegistry containerRegistry)
        {
            base.RegisterRequiredTypes(containerRegistry);
            //注册全局变量
            containerRegistry.RegisterScoped<SystemConfig>();
            containerRegistry.RegisterScoped<StepRunning>();
            containerRegistry.RegisterScoped<ScopedContext>();
            containerRegistry.RegisterScoped<DeviceManager>();
            containerRegistry.RegisterSingleton<GlobalInfo>();
            containerRegistry.RegisterSingleton<HardwareDataBroadcaster>();
            containerRegistry.RegisterSingleton<CANSignalBroadcaster>();
            //注册AutoMapper
            var config = new MapperConfiguration(
                 cfg => cfg.AddProfile<AutoMapperProfile>(),
                 NullLoggerFactory.Instance
             );
            containerRegistry.RegisterSingleton<IMapper>(() => config.CreateMapper());
        }
        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //注册弹窗
            containerRegistry.RegisterDialog<MessageBoxView, MessageBoxViewModel>("MessageBox");
            // 注册通知管理器
            INotificationManager NotificationManager = new NotificationManager();
            containerRegistry.RegisterInstance<INotificationManager>(NotificationManager);
            // 注册仓储
            containerRegistry.RegisterScoped(typeof(SqlSugarRepository<>));
            //注册服务
            containerRegistry.Register<IMonitorValueService, MonitorValueService>();
            containerRegistry.Register<ITestReportService, TestReportService>();
        }
        //指定模块加载方式(需要手动将模块生成的dll放入Modules文件夹中)
        protected override IModuleCatalog CreateModuleCatalog()
        {
            //指定模块加载方式为从文件夹中以反射发现并加载module(推荐用法)
            return new DirectoryModuleCatalog() { ModulePath = @".\Modules" };
        }
    }
}
