using Lierda.WPFHelper;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Serilog.Debugging;
using SlnMesnac.Config;
using SlnMesnac.Extensions;
using SlnMesnac.Rfid;
using SlnMesnac.Serilog;
using SlnMesnac.WPF.Attribute;
using SlnMesnac.WPF.Model;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows;
using TouchSocket.Sockets;

namespace SlnMesnac.WPF
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private Mutex _instanceMutex = null;
        private LierdaCracker cracker = new LierdaCracker();
        public static IServiceProvider ServiceProvider { get; private set; }

        // 实例唯一标识符
        private static string _instanceId;

        // 实例数据目录
        private static string _instanceDataPath;

        public new static App Current => (App)Application.Current;

        // 获取当前实例ID（静态属性）
        public static string InstanceId => _instanceId;

        // 获取当前实例的数据路径
        public static string InstanceDataPath => _instanceDataPath;

        public SerilogHelper serilog;
        // Startup事件
        protected override async void OnStartup(StartupEventArgs e)
        {
            try
            {
                this.DispatcherUnhandledException += App_DispatcherUnhandledException;  //全局异常处理
                #region 多实例初始化
                // 从命令行参数获取实例ID（如果指定了）
                string customInstanceId = GetInstanceIdFromArgs(e.Args);

                // 生成实例ID
                _instanceId = !string.IsNullOrEmpty(customInstanceId)
                    ? customInstanceId
                    : GenerateInstanceId();

                // 初始化实例数据目录
                InitializeInstanceDataPath();

                // 创建基于实例ID的互斥体名称，确保每个实例独立
                string mutexName = $"Global\\{Process.GetCurrentProcess().ProcessName}_{_instanceId}";
                bool createdNew;
                _instanceMutex = new Mutex(true, mutexName, out createdNew);

                if (!createdNew)
                {
                    // 如果mutex已存在，说明相同实例ID的程序已经在运行
                    MessageBox.Show($"实例 {_instanceId} 已在运行中，无法重复启动！",
                        "启动失败", MessageBoxButton.OK, MessageBoxImage.Warning);
                    Environment.Exit(0);
                    return;
                }
                #endregion

                cracker.Cracker(100); //设置GC回收间隔

                base.OnStartup(e);

                // 设置ServiceCollection
                var services = new ServiceCollection();
                ConfigureServices(services); // 配置服务

                // 创建ServiceProvider
                ServiceProvider = services.BuildServiceProvider();



                // 获取AppConfig并更新实例特定的配置
                //var appConfig = ServiceProvider.GetService<AppConfig>();
                //if (appConfig != null)
                //{
                //    // 更新日志路径为实例专用路径
                //    appConfig.logPath = Path.Combine(_instanceDataPath, "Logs");
                //    Directory.CreateDirectory(appConfig.logPath);

                //    // 更新其他可能需要实例化的路径
                //    appConfig.InstanceId = _instanceId;
                //    appConfig.InstanceDataPath = _instanceDataPath;

                //    // 根据实例ID调整数据库连接（如果需要）
                //    // AdjustDatabaseConnectionForInstance(appConfig);
                //}

                // 配置Serilog和其他扩展
                ServiceProvider.UseSerilogExtensions();
                // 显示主窗口
                var loginWindow = ServiceProvider.GetRequiredService<MainWindow>();
                loginWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;

                // 在窗口标题显示实例信息
                loginWindow.Title = $"{loginWindow.Title} [{_instanceId}]";
                loginWindow.Show();

                serilog = ServiceProvider.GetRequiredService<SerilogHelper>();

                serilog.Info($"应用程序启动 - 实例ID: {_instanceId}, 进程ID: {Process.GetCurrentProcess().Id}");
                //serilog.Info($"日志目录: {appConfig?.logPath}");
                //serilog.Data($"数据目录: {_instanceDataPath}");
                //serilog.Error($"日志目录: {appConfig?.logPath}");
            }
            catch (Exception exception)
            {
                serilog.Info($"启动异常："+ exception.ToString());
                Console.WriteLine(exception);
            }
        }


        /// <summary>
        /// 从命令行参数获取实例ID
        /// </summary>
        private string GetInstanceIdFromArgs(string[] args)
        {
            if (args == null || args.Length == 0)
                return null;

            // 支持两种参数格式：/instance:ID 或 -instance=ID
            foreach (var arg in args)
            {
                if (arg.StartsWith("/instance:") || arg.StartsWith("-instance="))
                {
                    return arg.Contains(':')
                        ? arg.Substring(arg.IndexOf(':') + 1)
                        : arg.Substring(arg.IndexOf('=') + 1);
                }
            }

            return null;
        }

        /// <summary>
        /// 生成实例ID
        /// </summary>
        private string GenerateInstanceId()
        {
            string timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
            string random = new Random().Next(1000, 9999).ToString();
            return $"{timestamp}_{random}";
        }

        /// <summary>
        /// 初始化实例数据路径
        /// </summary>
        private void InitializeInstanceDataPath()
        {
            string appName = Assembly.GetExecutingAssembly().GetName().Name;

            string baseDataRoot = GetDataRootPath();

            _instanceDataPath = Path.Combine(baseDataRoot, appName, "Instances", _instanceId);

            Directory.CreateDirectory(_instanceDataPath);
            //Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Data"));
            Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Logs"));
            //Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Config"));
            //Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Cache"));
            //Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Temp"));

            //SaveInstanceInfo();

            CleanupOldInstances();
        }

        /// <summary>
        /// 获取数据存储根路径
        /// </summary>
        //private string GetDataRootPath()
        //{
        //    string envPath = Environment.GetEnvironmentVariable("SLNMESNAC_DATA_ROOT");
        //    if (!string.IsNullOrEmpty(envPath) && Directory.Exists(envPath))
        //        return envPath;

        //    return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
        //}

        private string GetDataRootPath()
        {
            // 使用当前系统目录 + InstanceData 路径
            string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;
            string instanceDataPath = Path.Combine(currentDirectory, "InstanceData");

            // 如果无法访问当前目录，使用应用程序数据目录作为后备
            try
            {
                // 尝试访问当前目录，确保我们有权限
                if (!Directory.Exists(instanceDataPath))
                {
                    Directory.CreateDirectory(instanceDataPath);
                }
                return instanceDataPath;
            }
            catch
            {
                // 如果没有权限，使用用户应用程序数据目录
                string fallbackPath = Path.Combine(
                    Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                    Assembly.GetExecutingAssembly().GetName().Name,
                    "InstanceData"
                );
                Directory.CreateDirectory(fallbackPath);
                return fallbackPath;
            }
        }

        /// <summary>
        /// 保存实例信息文件
        /// </summary>
        private void SaveInstanceInfo()
        {
            try
            {
                var process = Process.GetCurrentProcess();
                var info = new
                {
                    InstanceId = _instanceId,
                    StartTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                    ProcessId = process.Id,
                    ProcessName = process.ProcessName,
                    MachineName = Environment.MachineName,
                    UserName = Environment.UserName,
                    WorkingDirectory = Environment.CurrentDirectory
                };

                //string infoFile = Path.Combine(_instanceDataPath, "instance.info");
                //File.WriteAllText(infoFile,
                //    $"Instance ID: {info.InstanceId}\r\n" +
                //    $"Start Time: {info.StartTime}\r\n" +
                //    $"Process ID: {info.ProcessId}\r\n" +
                //    $"Process Name: {info.ProcessName}\r\n" +
                //    $"Machine: {info.MachineName}\r\n" +
                //    $"User: {info.UserName}\r\n" +
                //    $"Working Dir: {info.WorkingDirectory}");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"保存实例信息失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 清理过期的实例数据
        /// </summary>
        private void CleanupOldInstances(int keepDays = 3)
        {
            try
            {
                string appName = Assembly.GetExecutingAssembly().GetName().Name;
                string instancesRoot = Path.Combine(
                    GetDataRootPath(),
                    appName,
                    "Instances"
                );

                if (!Directory.Exists(instancesRoot))
                    return;

                DateTime cutoffTime = DateTime.Now.AddDays(-keepDays);
                var instanceDirs = Directory.GetDirectories(instancesRoot);

                foreach (var dir in instanceDirs)
                {
                    try
                    {
                        var dirInfo = new DirectoryInfo(dir);
                        var infoFile = Path.Combine(dir, "instance.info");

                        if (File.Exists(infoFile))
                        {
                            // 读取启动时间
                            var content = File.ReadAllText(infoFile);
                            var startTimeLine = content.Split('\n')
                                .FirstOrDefault(line => line.StartsWith("Start Time:"));

                            if (!string.IsNullOrEmpty(startTimeLine))
                            {
                                string timeStr = startTimeLine.Substring(11).Trim();
                                if (DateTime.TryParse(timeStr, out DateTime startTime))
                                {
                                    if (startTime < cutoffTime)
                                    {
                                        Directory.Delete(dir, true);
                                        Debug.WriteLine($"已清理过期实例: {dirInfo.Name}");
                                    }
                                }
                            }
                        }
                        else if (dirInfo.CreationTime < cutoffTime)
                        {
                            // 如果没有信息文件，使用目录创建时间
                            Directory.Delete(dir, true);
                            Debug.WriteLine($"已清理过期实例: {dirInfo.Name}");
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine($"清理实例 {dir} 失败: {ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"清理实例数据失败: {ex.Message}");
            }
        }

        /// <summary>
        /// ConfigureServices
        /// </summary>
        private void ConfigureServices(IServiceCollection services)
        {
            // 注册AppConfig
            services.AddSingleton(provider =>
            {
                var configurationBuilder = new ConfigurationBuilder()
                    .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
                    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

                // 添加实例特定的配置文件（如果存在）
                string instanceConfig = Path.Combine(_instanceDataPath, "Config", "appsettings.instance.json");
                if (File.Exists(instanceConfig))
                {
                    configurationBuilder.AddJsonFile(instanceConfig, optional: true, reloadOnChange: true);
                }

                IConfiguration configuration = configurationBuilder.Build();
                var appConfig = configuration.GetSection("AppConfig").Get<AppConfig>();

                // 设置实例特定的属性
                if (appConfig != null)
                {
                    appConfig.InstanceId = _instanceId;
                    appConfig.InstanceDataPath = _instanceDataPath;
                }

                return appConfig;
            });

            services.AddSingleton<SerilogHelper>();

            // 加载程序集
            Assembly[] assemblies = {
                Assembly.LoadFrom("SlnMesnac.Repository.dll"),
                Assembly.LoadFrom("SlnMesnac.Rfid.dll"),
                Assembly.LoadFrom("SlnMesnac.Common.dll"),
            };

            // 扫描并注册程序集中的服务
            services.Scan(scan => scan.FromAssemblies(assemblies)
                                .AddClasses()
                                .AsImplementedInterfaces()
                                .AsSelf()
                                .WithTransientLifetime());

            // 注册TcpService - 需要确保每个实例使用不同的端口
            services.AddSingleton(provider =>
            {
                var tcpService = new TcpService();
                // 根据实例ID调整端口配置
                // 例如：tcpService.Port = GetInstanceSpecificPort(_instanceId);
                return tcpService;
            });

            services.AddLogging(x => x.AddSerilog());


            // 扫描并注册带有特性的窗口和服务
            services.Scan(scan => scan
                .FromAssemblyOf<MainWindow>()
                .AddClasses(classes => classes.WithAttribute<RegisterAsSingletonAttribute>())
                .AsSelf()
                .WithSingletonLifetime());

            //services.Scan(scan => scan
            //    .FromAssemblyOf<MainWindow>()
            //    .AddClasses(classes => classes.WithAttribute<RegisterAsTransientAttribute>())
            //    .AsSelf()
            //    .WithTransientLifetime());



            services.AddRfidFactorySetup();
        }

        // Exit事件
        protected override void OnExit(ExitEventArgs e)
        {
            base.OnExit(e);

            Log.Information($"实例 {_instanceId} 退出，退出时间：{DateTime.Now:yyyy-MM-dd HH:mm:ss}");

            // 释放互斥体
            try
            {
                _instanceMutex?.ReleaseMutex();
                _instanceMutex?.Dispose();
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"释放互斥体失败: {ex.Message}");
            }
        }

        private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            string errorMsg = $"[实例 {_instanceId}] 发生未处理异常: {e.Exception.Message}, {e.Exception.StackTrace}";
            Log.Error(e.Exception, $"实例 {_instanceId} 全局异常: {e.Exception.Message}");
            MessageBox.Show(errorMsg, "应用程序错误", MessageBoxButton.OK, MessageBoxImage.Error);
            // 保存异常信息到实例日志目录
            try
            {
                string errorLogFile = Path.Combine(_instanceDataPath, "Logs", $"crash_{DateTime.Now:yyyyMMdd_HHmmss}.log");
                File.WriteAllText(errorLogFile,
                    $"实例ID: {_instanceId}\r\n" +
                    $"异常时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}\r\n" +
                    $"异常信息: {e.Exception.Message}\r\n" +
                    $"堆栈跟踪:\r\n{e.Exception.StackTrace}");
            }
            catch
            {
                // 忽略文件保存失败
            }

            e.Handled = true;
        }

        // 静态辅助方法

        /// <summary>
        /// 启动一个新的应用程序实例
        /// </summary>
        public static void StartNewInstance(string instanceId = null)
        {
            try
            {
                string exePath = Process.GetCurrentProcess().MainModule?.FileName;
                if (!string.IsNullOrEmpty(exePath))
                {
                    string arguments = string.Empty;
                    if (!string.IsNullOrEmpty(instanceId))
                    {
                        arguments = $"/instance:{instanceId}";
                    }

                    ProcessStartInfo startInfo = new ProcessStartInfo
                    {
                        FileName = exePath,
                        Arguments = arguments,
                        UseShellExecute = true
                    };

                    Process.Start(startInfo);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"启动新实例失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// 获取所有实例的目录
        /// </summary>
        public static string[] GetAllInstanceDirectories()
        {
            string appName = Assembly.GetExecutingAssembly().GetName().Name;
            string instancesRoot = Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                appName,
                "Instances"
            );

            return Directory.Exists(instancesRoot)
                ? Directory.GetDirectories(instancesRoot)
                : Array.Empty<string>();
        }

        /// <summary>
        /// 获取所有运行中的实例信息
        /// </summary>
        public static InstanceInfo[] GetAllRunningInstances()
        {
            var instanceDirs = GetAllInstanceDirectories();
            var instances = new System.Collections.Generic.List<InstanceInfo>();

            foreach (var dir in instanceDirs)
            {
                try
                {
                    string infoFile = Path.Combine(dir, "instance.info");
                    if (File.Exists(infoFile))
                    {
                        var content = File.ReadAllLines(infoFile);
                        var instanceId = Path.GetFileName(dir);

                        var info = new InstanceInfo
                        {
                            Id = instanceId,
                            DataPath = dir,
                            CreationTime = Directory.GetCreationTime(dir)
                        };

                        instances.Add(info);
                    }
                }
                catch
                {
                    // 忽略无法读取的实例
                }
            }

            return instances.ToArray();
        }

        /// <summary>
        /// 实例信息类
        /// </summary>
        public class InstanceInfo
        {
            public string Id { get; set; }
            public string DataPath { get; set; }
            public DateTime CreationTime { get; set; }
        }


    }
}
