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;

        // 地基平台
        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 ?? 3;
            Cooldown = (float)config.Cooldown;
            MuzzleVelocity = (float)(config.MuzzleVelocity ?? 800f);
            CruiseSpeed = (float)(config.CruiseSpeed ?? 55f);
            ReleaseAltitude = (float)(config.ReleaseAltitude ?? 1000f);

            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 || _flightDistance < 0.01f)
            {
                PosX = _targetX;
                PosY = _targetY;
                PosZ = _targetZ;
                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 targetY, float targetZ)
        {
            if (PlatformType != Models.PlatformType.AirBased) return;
            _targetX = targetX;
            _targetY = targetY;
            _targetZ = targetZ;
            float dx = targetX - PosX;
            float dy = targetY - PosY;
            float dz = targetZ - PosZ;
            _flightDistance = (float)Math.Sqrt(dx * dx + dy * dy + dz * dz);
            _flownDistance = 0;
            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);
            }
        }
    }
}
