using System;
using System.Configuration;
using System.IO;
using System.Net;
using XP.Hardware.Detector.Abstractions;
using XP.Hardware.Detector.Abstractions.Enums;

namespace XP.Hardware.Detector.Config
{
    /// <summary>
    /// 配置加载器 | Configuration loader
    /// 从 App.config 读取探测器配置并验证参数有效性
    /// </summary>
    public static class ConfigLoader
    {
        /// <summary>
        /// 加载配置 | Load configuration
        /// </summary>
        /// <returns>配置结果 | Configuration result</returns>
        public static DetectorResult<DetectorConfig> LoadConfiguration()
        {
            try
            {
                // 读取探测器类型 | Read detector type
                string typeStr = ConfigurationManager.AppSettings["Detector:Type"];
                if (string.IsNullOrEmpty(typeStr))
                {
                    return DetectorResult<DetectorConfig>.Failure("配置文件中未找到 Detector:Type | Detector:Type not found in configuration");
                }

                if (!Enum.TryParse<DetectorType>(typeStr, true, out var detectorType))
                {
                    return DetectorResult<DetectorConfig>.Failure($"无效的探测器类型：{typeStr} | Invalid detector type: {typeStr}");
                }

                // 根据类型创建配置对象 | Create configuration object based on type
                DetectorConfig config = detectorType switch
                {
                    DetectorType.Varex => LoadVarexConfiguration(),
                    DetectorType.IRay => LoadIRayConfiguration(),
                    _ => throw new NotSupportedException($"不支持的探测器类型：{detectorType} | Unsupported detector type: {detectorType}")
                };

                // 加载通用配置 | Load common configuration
                config.Type = detectorType;
                config.IP = ConfigurationManager.AppSettings["Detector:IP"] ?? "127.0.0.1";
                config.Port = int.TryParse(ConfigurationManager.AppSettings["Detector:Port"], out var port) ? port : 5000;
                config.SavePath = ConfigurationManager.AppSettings["Detector:SavePath"] ?? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images");
                config.AutoSave = bool.TryParse(ConfigurationManager.AppSettings["Detector:AutoSave"], out var autoSave) && autoSave;

                // 验证配置 | Validate configuration
                var validationResult = ValidateConfiguration(config);
                if (!validationResult.IsSuccess)
                {
                    return DetectorResult<DetectorConfig>.Failure(validationResult.ErrorMessage);
                }

                return DetectorResult<DetectorConfig>.Success(config, "配置加载成功 | Configuration loaded successfully");
            }
            catch (Exception ex)
            {
                return DetectorResult<DetectorConfig>.Failure($"加载配置异常 | Load configuration exception: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 加载 Varex 配置 | Load Varex configuration
        /// </summary>
        private static VarexDetectorConfig LoadVarexConfiguration()
        {
            var config = new VarexDetectorConfig();

            // 读取 Binning 模式 | Read binning mode
            string binningStr = ConfigurationManager.AppSettings["Detector:Varex:BinningMode"];
            if (!string.IsNullOrEmpty(binningStr) && Enum.TryParse<BinningMode>(binningStr, true, out var binningMode))
            {
                config.BinningMode = binningMode;
            }

            // 读取增益模式 | Read gain mode
            string gainStr = ConfigurationManager.AppSettings["Detector:Varex:GainMode"];
            if (!string.IsNullOrEmpty(gainStr) && Enum.TryParse<GainMode>(gainStr, true, out var gainMode))
            {
                config.GainMode = gainMode;
            }

            // 读取曝光时间 | Read exposure time
            if (uint.TryParse(ConfigurationManager.AppSettings["Detector:Varex:ExposureTime"], out var exposureTime))
            {
                config.ExposureTime = exposureTime;
            }

            // 读取 ROI 参数 | Read ROI parameters
            if (uint.TryParse(ConfigurationManager.AppSettings["Detector:Varex:ROI_X"], out var roiX))
            {
                config.RoiX = roiX;
            }
            if (uint.TryParse(ConfigurationManager.AppSettings["Detector:Varex:ROI_Y"], out var roiY))
            {
                config.RoiY = roiY;
            }
            if (uint.TryParse(ConfigurationManager.AppSettings["Detector:Varex:ROI_Width"], out var roiWidth))
            {
                config.RoiWidth = roiWidth;
            }
            if (uint.TryParse(ConfigurationManager.AppSettings["Detector:Varex:ROI_Height"], out var roiHeight))
            {
                config.RoiHeight = roiHeight;
            }

            return config;
        }

        /// <summary>
        /// 加载 iRay 配置 | Load iRay configuration
        /// </summary>
        private static IRayDetectorConfig LoadIRayConfiguration()
        {
            var config = new IRayDetectorConfig();

            // 读取默认增益 | Read default gain
            if (double.TryParse(ConfigurationManager.AppSettings["Detector:IRay:DefaultGain"], out var defaultGain))
            {
                config.DefaultGain = defaultGain;
            }

            // 读取采集模式 | Read acquisition mode
            string modeStr = ConfigurationManager.AppSettings["Detector:IRay:AcquisitionMode"];
            if (!string.IsNullOrEmpty(modeStr) && Enum.TryParse<AcquisitionMode>(modeStr, true, out var acquisitionMode))
            {
                config.AcquisitionMode = acquisitionMode;
            }

            return config;
        }

        /// <summary>
        /// 保存探测器参数到 App.config | Save detector parameters to App.config
        /// </summary>
        /// <param name="binningIndex">Binning 索引 | Binning index</param>
        /// <param name="pga">PGA 灵敏度值 | PGA sensitivity value</param>
        /// <param name="frameRate">帧率 | Frame rate</param>
        /// <param name="avgFrames">帧合并数 | Average frame count</param>
        public static void SaveParameters(int binningIndex, int pga, decimal frameRate, int avgFrames)
        {
            var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            SetAppSetting(config, "Detector:BinningIndex", binningIndex.ToString());
            SetAppSetting(config, "Detector:PGA", pga.ToString());
            SetAppSetting(config, "Detector:FrameRate", frameRate.ToString(System.Globalization.CultureInfo.InvariantCulture));
            SetAppSetting(config, "Detector:AvgFrames", avgFrames.ToString());

            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");
        }

        /// <summary>
        /// 加载已保存的探测器参数 | Load saved detector parameters
        /// </summary>
        /// <returns>参数元组（binningIndex, pga, frameRate, avgFrames），加载失败返回 null | Parameter tuple, null if failed</returns>
        public static (int binningIndex, int pga, decimal frameRate, int avgFrames)? LoadSavedParameters()
        {
            try
            {
                string binStr = ConfigurationManager.AppSettings["Detector:BinningIndex"];
                string pgaStr = ConfigurationManager.AppSettings["Detector:PGA"];
                string frStr = ConfigurationManager.AppSettings["Detector:FrameRate"];
                string avgStr = ConfigurationManager.AppSettings["Detector:AvgFrames"];

                if (string.IsNullOrEmpty(binStr) || string.IsNullOrEmpty(pgaStr) ||
                    string.IsNullOrEmpty(frStr) || string.IsNullOrEmpty(avgStr))
                {
                    return null;
                }

                if (int.TryParse(binStr, out var binning) &&
                    int.TryParse(pgaStr, out var pgaVal) &&
                    decimal.TryParse(frStr, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out var fr) &&
                    int.TryParse(avgStr, out var avg))
                {
                    return (binning, pgaVal, fr, avg);
                }
            }
            catch
            {
                // 忽略加载异常 | Ignore load exception
            }
            return null;
        }

        /// <summary>
        /// 设置 AppSettings 键值 | Set AppSettings key-value
        /// </summary>
        private static void SetAppSetting(Configuration config, string key, string value)
        {
            if (config.AppSettings.Settings[key] != null)
            {
                config.AppSettings.Settings[key].Value = value;
            }
            else
            {
                config.AppSettings.Settings.Add(key, value);
            }
        }

        /// <summary>
        /// 验证配置参数 | Validate configuration parameters
        /// </summary>
        private static DetectorResult ValidateConfiguration(DetectorConfig config)
        {
            // 验证 IP 地址 | Validate IP address
            if (!IPAddress.TryParse(config.IP, out _))
            {
                return DetectorResult.Failure($"无效的 IP 地址：{config.IP} | Invalid IP address: {config.IP}");
            }

            // 验证端口范围 | Validate port range
            if (config.Port < 1 || config.Port > 65535)
            {
                return DetectorResult.Failure($"无效的端口号：{config.Port}，必须在 1-65535 之间 | Invalid port: {config.Port}, must be between 1-65535");
            }

            // 验证存储路径 | Validate save path
            if (string.IsNullOrWhiteSpace(config.SavePath))
            {
                return DetectorResult.Failure("存储路径不能为空 | Save path cannot be empty");
            }

            try
            {
                // 尝试创建目录以验证路径有效性 | Try to create directory to validate path
                if (!Directory.Exists(config.SavePath))
                {
                    Directory.CreateDirectory(config.SavePath);
                }
            }
            catch (Exception ex)
            {
                return DetectorResult.Failure($"无效的存储路径：{config.SavePath}，错误：{ex.Message} | Invalid save path: {config.SavePath}, error: {ex.Message}");
            }

            return DetectorResult.Success("配置验证通过 | Configuration validation passed");
        }
    }
}
