using System;
using CounterDrone.Core.Algorithms;
using CounterDrone.Core.Models;

namespace CounterDrone.Core.Simulation
{
    public enum PlatformState { Idle, FlyingToTarget, ReadyToRelease }

    public class PlatformEntity
    {
        public string Id { get; }
        public EquipmentRole Role { get; }
        public PlatformType? PlatformType { get; }
        public float PosX { get; private set; }
        public float PosY { get; private set; }
        public float PosZ { get; private set; }
        public AerosolType? AerosolType { get; }
        public int MunitionCount { get; private set; }
        public float Cooldown { get; }
        public float CooldownRemaining { get; private set; }
        public PlatformState State { get; private set; } = PlatformState.Idle;

        // 空基平台
        public float CruiseSpeed { get; }
        public float PatrolX { get; }
        public float PatrolY { get; }
        public float PatrolZ { get; }
        public float ReleaseAltitude { get; }
        private float _targetX, _targetY, _targetZ;
        private float _flightDistance;
        private float _flownDistance;
        private float _driftDistance;
        /// <summary>空基平台精确投放时刻（计算值）</summary>
        public float ExactReleaseTime => _exactReleaseTime;
        private float _exactReleaseTime;

        // 地基平台
        public float MuzzleVelocity { get; }

        /// <summary>Ready 包含：冷却就绪 + 有弹药 + 非飞行中</summary>
        public bool Ready => CooldownRemaining <= 0 && MunitionCount > 0 && State != PlatformState.FlyingToTarget;

        public PlatformEntity(string id, EquipmentDeployment config)
        {
            Id = id;
            Role = (EquipmentRole)config.EquipmentRole;
            PlatformType = config.PlatformType.HasValue ? (PlatformType?)config.PlatformType.Value : null;
            PosX = (float)config.PositionX;
            PosY = (float)config.PositionY;
            PosZ = (float)config.PositionZ;
            AerosolType = config.AerosolType.HasValue ? (AerosolType?)config.AerosolType.Value : null;
            MunitionCount = config.MunitionCount ?? 1;
            Cooldown = (float)config.Cooldown;
            MuzzleVelocity = (float)(config.MuzzleVelocity ?? 0f);
            CruiseSpeed = (float)(config.CruiseSpeed ?? 0f);
            ReleaseAltitude = (float)(config.ReleaseAltitude ?? 0f);

            PatrolX = PosX;
            PatrolY = PosY;
            PatrolZ = PosZ;
        }

        public void Update(float deltaTime)
        {
            if (CooldownRemaining > 0)
                CooldownRemaining -= deltaTime;

            if (State != PlatformState.FlyingToTarget) return;

            float step = CruiseSpeed * deltaTime;
            _flownDistance += step;

            if (_flownDistance >= _flightDistance - _driftDistance - 0.01f || _flightDistance < 0.01f)
            {
                // 在投放点（非终点），保留插值位置
                float rt = _flightDistance > 0.01f ? Math.Min(1f, _flownDistance / _flightDistance) : 1f;
                PosX = PatrolX + (_targetX - PatrolX) * rt;
                PosY = PatrolY + (_targetY - PatrolY) * rt;
                PosZ = PatrolZ + (_targetZ - PatrolZ) * rt;
                State = PlatformState.ReadyToRelease;
                return;
            }

            float t = _flownDistance / _flightDistance;
            PosX = PatrolX + (_targetX - PatrolX) * t;
            PosY = PatrolY + (_targetY - PatrolY) * t;
            PosZ = PatrolZ + (_targetZ - PatrolZ) * t;
        }

        /// <summary>下令空基平台飞往投放点</summary>
        public void CommandFlyTo(float targetX, float releaseAlt, float targetZ, float fireTime, float disperseHeight)
        {
            if (PlatformType != Models.PlatformType.AirBased) return;
            _targetX = targetX;
            _targetY = releaseAlt;
            _targetZ = targetZ;
            float distToCloud = Kinematics.Distance3D(PosX, PosY, PosZ, targetX, releaseAlt, targetZ);
            float fallTime = Kinematics.AirDropFallTime(releaseAlt, disperseHeight);
            float driftDist = CruiseSpeed * fallTime;
            _flightDistance = distToCloud;
            _flownDistance = 0;
            _driftDistance = driftDist;
            float flightDist = Math.Max(0f, distToCloud - driftDist);
            float flightTime = CruiseSpeed > 0 ? flightDist / CruiseSpeed : 0f;
            _exactReleaseTime = fireTime + flightTime;
            State = PlatformState.FlyingToTarget;
        }

        /// <summary>地基：直接发射；空基：投弹后冷却</summary>
        public void Release()
        {
            MunitionCount--;
            CooldownRemaining = Cooldown;
            State = PlatformState.Idle;
        }

        /// <summary>空基平台到达投放点后可投弹</summary>
        public bool CanRelease => State == PlatformState.ReadyToRelease && CooldownRemaining <= 0 && MunitionCount > 0;

        /// <summary>当前速度矢量（空基平台：飞行方向 × 巡航速度；地基：零矢量）</summary>
        public (float Vx, float Vy, float Vz) CurrentVelocity
        {
            get
            {
                if (PlatformType != Models.PlatformType.AirBased) return (0, 0, 0);
                return Kinematics.DirectionVelocity(PatrolX, PatrolY, PatrolZ, _targetX, _targetY, _targetZ, CruiseSpeed);
            }
        }
    }
}
