using CounterDrone.Core.Algorithms;
using CounterDrone.Core.Models;
using Xunit;

namespace CounterDrone.Core.Tests
{
    public class DamageModelTests
    {
        [Fact]
        public void InertGas_PistonEngine_TakesExtraDamage()
        {
            var model = new InertGasDamageModel();

            // 活塞发动机暴露于惰性气体
            var dmg = model.CalculateDamage(TargetType.Piston, PowerType.Piston,
                AerosolType.InertGas, cloudDensity: 0.1f, exposureTime: 2f, deltaTime: 1f);

            Assert.True(dmg > 0.1f); // 高于基础速率（0.15 × 1.5 = 0.225）
        }

        [Fact]
        public void InertGas_BelowThreshold_NoDamage()
        {
            var model = new InertGasDamageModel();

            var dmg = model.CalculateDamage(TargetType.Piston, PowerType.Piston,
                AerosolType.InertGas, cloudDensity: 0.00001f, exposureTime: 2f, deltaTime: 1f);

            Assert.Equal(0f, dmg);
        }

        [Fact]
        public void InertGas_WrongAerosolType_NoDamage()
        {
            var model = new InertGasDamageModel();

            var dmg = model.CalculateDamage(TargetType.Piston, PowerType.Piston,
                AerosolType.ActiveMaterial, cloudDensity: 0.1f, exposureTime: 2f, deltaTime: 1f);

            Assert.Equal(0f, dmg);
        }

        [Fact]
        public void ActiveMaterial_TriggersBurst()
        {
            var model = new ActiveMaterialDamageModel();

            var dmg1 = model.CalculateDamage(TargetType.FixedWing, PowerType.Jet,
                AerosolType.ActiveMaterial, cloudDensity: 0.2f, exposureTime: 1f, deltaTime: 1f);

            Assert.True(dmg1 >= 0.5f); // 爆发伤害

            var dmg2 = model.CalculateDamage(TargetType.FixedWing, PowerType.Jet,
                AerosolType.ActiveMaterial, cloudDensity: 0.2f, exposureTime: 2f, deltaTime: 1f);

            Assert.True(dmg2 < 0.1f); // 后续余伤很小
        }

        [Fact]
        public void ActiveMaterial_JetEngine_ExtraSensitivity()
        {
            var model = new ActiveMaterialDamageModel();

            var dmg = model.CalculateDamage(TargetType.FixedWing, PowerType.Jet,
                AerosolType.ActiveMaterial, cloudDensity: 0.2f, exposureTime: 0f, deltaTime: 0.1f);

            // 喷气发动机：0.6 × 1.3 = 0.78
            Assert.True(dmg > 0.7f);
        }

        [Fact]
        public void ActiveFuel_ExponentialGrowth()
        {
            var model = new ActiveFuelDamageModel();

            var dmg1 = model.CalculateDamage(TargetType.HighSpeed, PowerType.Jet,
                AerosolType.ActiveFuel, cloudDensity: 0.1f, exposureTime: 1f, deltaTime: 1f);

            var dmg2 = model.CalculateDamage(TargetType.HighSpeed, PowerType.Jet,
                AerosolType.ActiveFuel, cloudDensity: 0.1f, exposureTime: 5f, deltaTime: 1f);

            // 5 秒后的伤害应显著大于 1 秒后
            Assert.True(dmg2 > dmg1 * 2f);
        }

        [Fact]
        public void ActiveFuel_HighSpeedTarget_ExtraSensitive()
        {
            var model = new ActiveFuelDamageModel();

            var dmg = model.CalculateDamage(TargetType.HighSpeed, PowerType.Jet,
                AerosolType.ActiveFuel, cloudDensity: 0.1f, exposureTime: 1f, deltaTime: 1f);

            Assert.True(dmg > 0.02f); // 基础速率 × 灵敏度
        }

        [Fact]
        public void DamageStage_Progression()
        {
            var model = new InertGasDamageModel();

            Assert.Equal(DamageStage.Normal, model.GetDamageStage(0.1f));
            Assert.Equal(DamageStage.EngineAnomaly, model.GetDamageStage(0.3f));
            Assert.Equal(DamageStage.AttitudeLoss, model.GetDamageStage(0.7f));
            Assert.Equal(DamageStage.Destroyed, model.GetDamageStage(1.0f));
        }

        [Fact]
        public void Router_RoutesToCorrectModel()
        {
            var router = new DamageModelRouter();

            // 惰性气体
            var dmg1 = router.CalculateDamage(TargetType.Piston, PowerType.Piston,
                AerosolType.InertGas, 0.1f, 1f, 1f);
            Assert.True(dmg1 > 0f);

            // 活性材料
            var dmg2 = router.CalculateDamage(TargetType.FixedWing, PowerType.Jet,
                AerosolType.ActiveMaterial, 0.2f, 0f, 1f);
            Assert.True(dmg2 > 0f);

            // 活性燃料
            var dmg3 = router.CalculateDamage(TargetType.HighSpeed, PowerType.Jet,
                AerosolType.ActiveFuel, 0.1f, 1f, 1f);
            Assert.True(dmg3 > 0f);
        }
    }
}
