using System;
using System.Diagnostics;
using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;
using AntdUI;
using DH.Commons.Base;
using DH.Commons.Models;

namespace DH.Commons.Helper
{
    public static class ConfigHelper
    {
        private static readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions
        {
            WriteIndented = true,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            IgnoreNullValues = true
        };

        /// <summary>
        /// 配置存储根目录
        /// </summary>
        private static string ConfigsRoot => Path.Combine(
            AppDomain.CurrentDomain.BaseDirectory,
            "configs");

        /// <summary>
        /// 获取当前方案的主配置文件路径
        /// </summary>
        private static string CurrentConfigPath
        {
            get
            {
                ValidateCurrentScheme();
                return Path.Combine(
                    ConfigsRoot,
                    $"config_{SystemModel.CurrentScheme}.json");
            }
        }

        /// <summary>
        /// 获取当前方案的备份目录路径
        /// </summary>
        private static string CurrentBackupDir
        {
            get
            {
                ValidateCurrentScheme();
                return Path.Combine(
                    ConfigsRoot,
                    $"bak_{SystemModel.CurrentScheme}");
            }
        }

        /// <summary>
        /// 初始化新方案(创建空文件)
        /// </summary>
        public static void InitializeScheme(string scheme)
        {
            SystemModel.CurrentScheme = scheme;

            // 创建空配置文件
            if (!File.Exists(CurrentConfigPath))
            {
                Directory.CreateDirectory(ConfigsRoot);
                File.WriteAllText(CurrentConfigPath, "{}");
            }

            // 创建备份目录
            Directory.CreateDirectory(CurrentBackupDir);
        }

        /// <summary>
        /// 保存当前配置(自动备份)
        /// </summary>
        public static void SaveConfig()
        {
            ValidateCurrentScheme();

            // 确保配置目录存在
            Directory.CreateDirectory(ConfigsRoot);

            // 备份现有配置
            if (File.Exists(CurrentConfigPath))
            {
                var backupName = $"config_{SystemModel.CurrentScheme}_{DateTime.Now:yyyyMMddHHmmss}.json";
                var backupPath = Path.Combine(CurrentBackupDir, backupName);

                Directory.CreateDirectory(CurrentBackupDir);
                File.Copy(CurrentConfigPath, backupPath);
            }
            //重置标签文件路径和内容
            ConfigModel.DetectionList.ForEach(config =>
            {
                GenerateLabelFile(config);
            });

            // 序列化当前配置
            var json = JsonSerializer.Serialize(new
            {
                ConfigModel.CameraBaseList,
                ConfigModel.PLCBaseList,
                ConfigModel.DetectionList
            }, _jsonOptions);

            // 写入新配置
            File.WriteAllText(CurrentConfigPath, json);
        }
        private static void GenerateLabelFile(DetectionConfig config)
        {
            try
            {
                if (config.DetectionLableList == null || string.IsNullOrEmpty(config.In_lable_path))
                    return;

                // 确保目录存在
                var directory = Path.GetDirectoryName(config.In_lable_path);
                if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                // 写入文件内容
                using (var writer = new StreamWriter(config.In_lable_path, false))
                {
                    foreach (var label in config.DetectionLableList)
                    {
                        // 根据实际需求格式化输出
                        writer.WriteLine(label.LabelName.ToString()); // 假设DetectionLable重写了ToString()

                        // 或者明确指定格式:
                        // writer.WriteLine($"{label.Id},{label.Name},{label.Confidence}");
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"生成标签文件失败: {ex.Message}");
                // 可以考虑记录更详细的日志
            }
        }
        /// <summary>
        /// 加载当前方案配置
        /// </summary>
        public static void LoadConfig()
        {
            ValidateCurrentScheme();

            if (!File.Exists(CurrentConfigPath))
            {
                InitializeScheme(SystemModel.CurrentScheme);
                return;
            }

            var json = File.ReadAllText(CurrentConfigPath);
            var data = JsonSerializer.Deserialize<ConfigData>(json, _jsonOptions);

            ConfigModel.CameraBaseList = data?.Cameras ?? new List<CameraBase>();
            ConfigModel.PLCBaseList = data?.PLCs ?? new List<PLCBase>();
            ConfigModel.DetectionList = data?.Detections ?? new List<DetectionConfig>();
        }

        /// <summary>
        /// 验证当前方案有效性
        /// </summary>
        private static void ValidateCurrentScheme()
        {
            if (string.IsNullOrWhiteSpace(SystemModel.CurrentScheme))
                throw new InvalidOperationException("当前方案未设置");
        }
        /// <summary>
        /// 派生新方案(基于当前方案创建副本)
        /// </summary>
        /// <param name="newSchemeName">新方案名称</param>
        public static void DeriveScheme(string newSchemeName)
        {
            // 验证输入
            if (string.IsNullOrWhiteSpace(newSchemeName))
            {
                throw new ArgumentException("新方案名称不能为空");
            }

            // 验证当前方案是否有效
            ValidateCurrentScheme();

            // 检查新方案是否已存在
            var newConfigPath = Path.Combine(ConfigsRoot, $"config_{newSchemeName}.json");
            if (File.Exists(newConfigPath))
            {
                throw new InvalidOperationException($"方案 {newSchemeName} 已存在");
            }

            // 保存当前配置确保最新
            SaveConfig();

            try
            {
                // 复制配置文件
                File.Copy(CurrentConfigPath, newConfigPath);

                // 创建备份目录
                var newBackupDir = Path.Combine(ConfigsRoot, $"bak_{newSchemeName}");
                Directory.CreateDirectory(newBackupDir);

                // 可选:自动切换新方案
                // SystemModel.CurrentScheme = newSchemeName;
            }
            catch (IOException ex)
            {
                throw new InvalidOperationException($"方案派生失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 删除指定方案的配置文件及备份目录
        /// </summary>
        /// <param name="schemeName">要删除的方案名称</param>
        /// <exception cref="ArgumentException">当方案名称为空时抛出</exception>
        /// <exception cref="IOException">文件操作失败时抛出</exception>
        public static void DeleteSchemeConfig(string schemeName)
        {
            if (string.IsNullOrWhiteSpace(schemeName))
                throw new ArgumentException("方案名称无效");

            // 构造路径
            var configPath = Path.Combine(ConfigsRoot, $"config_{schemeName}.json");
            var backupDir = Path.Combine(ConfigsRoot, $"bak_{schemeName}");

            try
            {
                // 删除配置文件
                if (File.Exists(configPath))
                {
                    File.Delete(configPath);
                }

                // 删除备份目录(递归删除)
                if (Directory.Exists(backupDir))
                {
                    Directory.Delete(backupDir, true);
                }
            }
            catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException)
            {
                throw new IOException($"删除方案 {schemeName} 的配置文件失败: {ex.Message}", ex);
            }
        }


        /// <summary>
        /// 配置数据模型(内部类)
        /// </summary>
        private class ConfigData
        {
            [JsonPropertyName("cameraBaseList")]
            public List<CameraBase> Cameras { get; set; } = new List<CameraBase>();

            [JsonPropertyName("plcBaseList")]
            public List<PLCBase> PLCs { get; set; } = new List<PLCBase>();

            [JsonPropertyName("detectionList")]
            public List<DetectionConfig> Detections { get; set; } = new List<DetectionConfig>();
        }
    }
}