using System.Collections.Generic;
using CounterDrone.Core.Models;

namespace CounterDrone.Core.Algorithms
{
    /// <summary>威胁画像</summary>
    public class ThreatProfile
    {
        public CombatScene Environment { get; set; } = new();
        public List<TargetConfig> Targets { get; set; } = new();
        public RoutePlan Route { get; set; } = new();
        public List<Waypoint> Waypoints { get; set; } = new();
        public List<ControlZone> ControlZones { get; set; } = new();
        /// <summary>偏好平台类型（null = 算法自行决定，当前默认地基）</summary>
        public PlatformType? PreferredPlatformType { get; set; }
    }

    /// <summary>防御推荐方案</summary>
    public class DefenseRecommendation
    {
        public DefenseSolution Best { get; set; } = new();
        public DefenseSolution Critical { get; set; } = new();
    }

    /// <summary>单套防御方案</summary>
    public class DefenseSolution
    {
        public AerosolType RecommendedAerosolType { get; set; }
        public string AerosolRationale { get; set; } = string.Empty;
        public CloudDispersal RecommendedCloud { get; set; } = new();

        public List<RecommendedPlatform> Platforms { get; set; } = new();
        public List<RecommendedDetection> Detections { get; set; } = new();

        public float InterceptProbability { get; set; }
        public string SummaryRationale { get; set; } = string.Empty;

        public List<FireEvent> FireSchedule { get; set; } = new();

        /// <summary>此方案占用的平台起始索引（多编队合并用）</summary>
        public int PlatformOffset { get; set; }
    }

    /// <summary>多编队推荐结果</summary>
    public class MultiGroupRecommendation
    {
        /// <summary>每组的独立方案</summary>
        public List<DefenseSolution> GroupSolutions { get; set; } = new();
        /// <summary>合并后的总发射计划</summary>
        public List<FireEvent> MergedFireSchedule { get; set; } = new();
    }

    /// <summary>火力单元（完整的武器系统）</summary>
    public class FireUnit
    {
        public string Id { get; set; } = string.Empty;
        public PlatformType Type { get; set; }
        public Vector3 Position { get; set; }

        // ── 发射装置 ──
        /// <summary>火炮/发射器数量</summary>
        public int GunCount { get; set; } = 1;
        /// <summary>每门炮的火力通道数（同时可装填的弹药数量）</summary>
        public int ChannelsPerGun { get; set; } = 1;
        /// <summary>总火力通道数 = GunCount × ChannelsPerGun</summary>
        public int TotalChannels => GunCount * ChannelsPerGun;
        /// <summary>同一通道连续发射的最小间隔（秒）</summary>
        public float ChannelInterval { get; set; } = 1f;

        // ── 弹药 ──
        /// <summary>总载弹量</summary>
        public int TotalMunitions { get; set; }
        /// <summary>可装填的弹药类型</summary>
        public List<AerosolType> AmmoTypes { get; set; } = new();
        /// <summary>单通道射击后冷却时间（秒）</summary>
        public float Cooldown { get; set; } = 5f;
        /// <summary>更换弹种时间（秒）</summary>
        public float AmmoChangeTime { get; set; } = 30f;

        // ── 搜索跟踪 ──
        /// <summary>雷达探测距离（m），0 表示无此设备</summary>
        public float RadarRange { get; set; }
        /// <summary>光电探测距离（m）</summary>
        public float EORange { get; set; }
        /// <summary>红外探测距离（m）</summary>
        public float IRRange { get; set; }

        // ── 空基 ──
        public float CruiseSpeed { get; set; }
        public float ReleaseAltitude { get; set; }

        // ── 地基 ──
        public float MuzzleVelocity { get; set; } = 800f;
    }

    /// <summary>无人机编队（规划器输入）</summary>
    public class DroneGroup
    {
        public string GroupId { get; set; } = string.Empty;
        public TargetConfig Target { get; set; } = new();
        public RoutePlan Route { get; set; } = new();
        public List<Waypoint> Waypoints { get; set; } = new();

        /// <summary>到达防御区域中点的时间（秒），由规划器预计算</summary>
        public float ArrivalTime { get; set; }
        /// <summary>威胁指数（速度系数 × 类型系数）</summary>
        public float ThreatIndex { get; set; }
        /// <summary>综合优先级 = 威胁指数 / (到达时间 + 1)</summary>
        public float Priority => ArrivalTime > -1 ? ThreatIndex / (ArrivalTime + 1f) : ThreatIndex;

        /// <summary>预计到达航路中点的时间（秒）</summary>
        public float GetArrivalTime()
        {
            if (Waypoints.Count < 2) return 0;
            var start = new Vector3((float)Waypoints[0].PosX, (float)Waypoints[0].PosY, (float)Waypoints[0].PosZ);
            var end = new Vector3((float)Waypoints[^1].PosX, (float)Waypoints[^1].PosY, (float)Waypoints[^1].PosZ);
            var speed = (float)Target.TypicalSpeed / 3.6f;
            return start.DistanceTo(end) / speed / 2f;
        }
    }

    public class RecommendedPlatform
    {
        public PlatformType Type { get; set; }
        public Vector3 Position { get; set; }
        public int Quantity { get; set; }
        public int MunitionCount { get; set; }
        public float CoverageVolume { get; set; }
        public float Cooldown { get; set; } = 5f;
        public float MuzzleVelocity { get; set; } = 800f;
        /// <summary>空基平台巡航速度 m/s</summary>
        public float CruiseSpeed { get; set; } = 55f;
        /// <summary>空基平台投放高度 m</summary>
        public float ReleaseAltitude { get; set; }
    }

    public class RecommendedDetection
    {
        public Vector3 Position { get; set; }
        public float DetectionRadius { get; set; }
        public int Quantity { get; set; }
    }

    /// <summary>三维向量（纯 C#，不依赖 UnityEngine）</summary>
    public struct Vector3
    {
        public float X, Y, Z;
        public Vector3(float x, float y, float z) { X = x; Y = y; Z = z; }

        public static Vector3 operator +(Vector3 a, Vector3 b) => new(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
        public static Vector3 operator -(Vector3 a, Vector3 b) => new(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
        public static Vector3 operator *(Vector3 a, float s) => new(a.X * s, a.Y * s, a.Z * s);
        public float Length => (float)System.Math.Sqrt(X * X + Y * Y + Z * Z);
        public float DistanceTo(Vector3 other) => (this - other).Length;
    }

    /// <summary>粒子渲染参数</summary>
    public class ParticleParams
    {
        public float EmitRate { get; set; } = 100;
        public float Opacity { get; set; } = 1.0f;
        public string ColorHex { get; set; } = "#FFFFFF";
        public float SizeMultiplier { get; set; } = 1.0f;
    }

    /// <summary>发射计划中的单次事件（算法生成 → 引擎执行）</summary>
    public class FireEvent
    {
        public float FireTime;
        public int PlatformIndex;
        public float TargetX, TargetY, TargetZ;
        public float MuzzleVelocity;
    }

    // ═══════════════════════════════════════════════
    // DefensePlanner 类型
    // ═══════════════════════════════════════════════

    /// <summary>拦截候选：一个火力单元对一个威胁的可行性评估</summary>
    public class InterceptCandidate
    {
        public FireUnit Unit { get; set; } = null!;
        public AerosolType AmmoType { get; set; }
        public float EarliestInterceptTime { get; set; }
        public float CoverageDuration { get; set; }
        public float KillProbability { get; set; }
        public float FlightTime { get; set; }     // 弹药/平台飞行时间
        public float ShellFlightTime { get; set; } // 仅地基用
    }

    /// <summary>单元分配：一个火力单元被分配给一个威胁的配置</summary>
    public class UnitAssignment
    {
        public string FireUnitId { get; set; } = string.Empty;
        public string DroneGroupId { get; set; } = string.Empty;
        public AerosolType AmmoType { get; set; }
        public int RoundsFired { get; set; }
        public float FirstFireTime { get; set; }
        public List<FireEvent> FireEvents { get; set; } = new();
    }

    /// <summary>规划方案</summary>
    public class DefensePlan
    {
        public List<UnitAssignment> Assignments { get; set; } = new();
        public List<FireEvent> MergedSchedule { get; set; } = new();
        public float OverallProbability { get; set; }
        public int ThreatsEngaged { get; set; }
        public int ThreatsUnengaged { get; set; }
        public string Summary { get; set; } = string.Empty;
    }

    /// <summary>规划器输出</summary>
    public class PlannerResult
    {
        public DefensePlan Best { get; set; } = new();
        public DefensePlan Critical { get; set; } = new();
    }
}
