using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;
using CounterDrone.Core.Models;

namespace CounterDrone.Core.Algorithms
{
    /// <summary>防御规划器配置 — 全局策略参数，从 planner_config.json 加载。
    /// 代码零默认值，所有字段必须从配置文件读取；文件缺失或字段缺失即抛异常。</summary>
    public class PlannerConfig
    {
        /// <summary>云团重叠比例（0=相切，0.2=重叠 20%）。间距 = 2R × (1 − 重叠比例)。</summary>
        public float CloudOverlapRatio { get; set; }

        /// <summary>临界方案概率阈值（DeriveCritical 用）</summary>
        public float CriticalProbabilityThreshold { get; set; }

        /// <summary>拦截概率上限（封顶值）</summary>
        public float MaxInterceptProbability { get; set; }

        /// <summary>威胁类型系数表（TargetType → 系数）</summary>
        public Dictionary<TargetType, float> TypeCoefficient { get; set; } = new();

        /// <summary>弹药匹配表（PowerType → AerosolType）</summary>
        public Dictionary<PowerType, AerosolType> AmmoMatch { get; set; } = new();

        /// <summary>无探测设备时的默认探测精度 m（回退值，上帝视角但有标称误差）</summary>
        public float DefaultDetectionAccuracy { get; set; }

        /// <summary>云团有效膨胀系数（0~1）。planner 取 Phase 2 膨胀时间的此比例作为有效云团年龄。默认 0.9</summary>
        public float ExpansionFactor { get; set; } = 0.9f;

        /// <summary>拦截窗口安全余量（s）。计算所需探测弧长时在膨胀时间基础上额外预留。默认 1</summary>
        public float TimingSafetyMargin { get; set; } = 1f;

        /// <summary>火力单元反应时间（s）。探测到目标后装填+瞄准的时间。默认 5</summary>
        public float ReactionTime { get; set; } = 5f;

        private const string ConfigFileName = "planner_config.json";

        /// <summary>从 dataRoot 加载配置。文件缺失或字段非法即抛异常。</summary>
        public static PlannerConfig Load(string dataRoot)
        {
            if (string.IsNullOrEmpty(dataRoot))
                throw new ArgumentException("dataRoot 不能为空", nameof(dataRoot));
            string path = Path.Combine(dataRoot, ConfigFileName);
            if (!File.Exists(path))
                throw new FileNotFoundException($"planner 配置文件不存在: {path}");

            string json = File.ReadAllText(path);
            var config = JsonSerializer.Deserialize<PlannerConfig>(json, JsonOptions)
                ?? throw new InvalidDataException($"planner 配置解析失败: {path}");
            config.Validate();
            return config;
        }

        /// <summary>从 IPathProvider 加载（便捷重载）</summary>
        public static PlannerConfig Load(IPathProvider paths)
            => Load(paths?.GetDataRoot() ?? throw new ArgumentNullException(nameof(paths)));

        private void Validate()
        {
            if (CloudOverlapRatio < 0f || CloudOverlapRatio >= 1f)
                throw new InvalidDataException($"CloudOverlapRatio 必须在 [0, 1)，实际 {CloudOverlapRatio}");
            if (CriticalProbabilityThreshold <= 0f || CriticalProbabilityThreshold >= 1f)
                throw new InvalidDataException($"CriticalProbabilityThreshold 必须在 (0, 1)，实际 {CriticalProbabilityThreshold}");
            if (MaxInterceptProbability <= 0f || MaxInterceptProbability > 1f)
                throw new InvalidDataException($"MaxInterceptProbability 必须在 (0, 1]，实际 {MaxInterceptProbability}");
            if (TypeCoefficient == null || TypeCoefficient.Count == 0)
                throw new InvalidDataException("TypeCoefficient 不能为空");
            if (AmmoMatch == null || AmmoMatch.Count == 0)
                throw new InvalidDataException("AmmoMatch 不能为空");
            if (DefaultDetectionAccuracy < 0f)
                throw new InvalidDataException($"DefaultDetectionAccuracy 必须 >= 0，实际 {DefaultDetectionAccuracy}");
            if (ExpansionFactor <= 0f || ExpansionFactor > 1f)
                throw new InvalidDataException($"ExpansionFactor 必须在 (0, 1]，实际 {ExpansionFactor}");
            if (TimingSafetyMargin < 0f)
                throw new InvalidDataException($"TimingSafetyMargin 必须 >= 0，实际 {TimingSafetyMargin}");
        }

        private static readonly JsonSerializerOptions JsonOptions = new()
        {
            Converters = { new JsonStringEnumConverter() },
            PropertyNameCaseInsensitive = true,
        };
    }
}
