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

namespace CounterDrone.Core
{
    /// <summary>
    /// 预设想定种子 — 从 DefaultData 预设组装完整想定，写入数据库供前端测试。
    /// 首次运行时自动种子，同名想定跳过（幂等）。
    /// </summary>
    public static class DefaultScenarios
    {
        public static void Seed(IScenarioService scenario, DefaultData d)
        {
            // 检测旧格式任务（名称含 [Demo]，但 SQL LIKE 中 [] 是通配符，搜索 "Demo"）
            var existing = scenario.SearchScenarios("Demo", null, null, 1, 100);
            if (existing.TotalCount > 0)
            {
                // 版本升级：删除旧 Demo 任务，重新创建
                foreach (var t in existing.Items)
                    scenario.DeleteScenario(t.Id);
            }

            SeedNoDefense(scenario, d);
            SeedZoneIntrusion(scenario, d);
            SeedPistonWindy(scenario, d);
            SeedJetActiveMaterial(scenario, d);
            SeedAirBasedWindy(scenario, d);
            Seed3DronesAirBased(scenario, d);
        }

        private static List<Waypoint> R(string routeId, double speed, DefaultData d)
            => d.Routes.First(r => r.Id == routeId).ToWaypoints(speed);

        private static void SeedNoDefense(IScenarioService s, DefaultData d)
        {
            var t = s.CreateScenario("[Demo] 无防御-无人机抵达目标", "");
            s.SaveScene(t.Id, d.Environments.First(w => w.Id == "sunny-calm").ToCombatScene());
            s.SaveScenarioDrone(t.Id, d.Drones.First(p => p.Id == "shahed").ToScenarioDrone());
            s.SaveRoute(t.Id, "default", d.Formations.First(f => f.Id == "single").ToRoutePlan(), R("3km-h400", 600, d));
            s.SaveCloudDispersal(t.Id, new CloudDispersal());
            s.SaveDeployment(t.Id, new List<ScenarioUnit>());
            s.UpdateStep(t.Id, 5);
        }

        private static void SeedZoneIntrusion(IScenarioService s, DefaultData d)
        {
            var t = s.CreateScenario("[Demo] 管控区域侵入", "");
            s.SaveScene(t.Id, d.Environments.First(w => w.Id == "sunny-calm").ToCombatScene());
            s.SaveScenarioDrone(t.Id, d.Drones.First(p => p.Id == "electric-scout").ToScenarioDrone());
            s.SaveRoute(t.Id, "default", d.Formations.First(f => f.Id == "single").ToRoutePlan(), R("3km-h300", 300, d));
            s.SaveCloudDispersal(t.Id, new CloudDispersal());
            s.SaveDeployment(t.Id, new List<ScenarioUnit>());
            s.SaveControlZones(t.Id, new List<ControlZone>
            {
                new ControlZone
                {
                    Name = "禁飞区",
                    VerticesJson = "[{\"X\":1200,\"Y\":0,\"Z\":-200},{\"X\":1800,\"Y\":0,\"Z\":-200},{\"X\":1800,\"Y\":0,\"Z\":200},{\"X\":1200,\"Y\":0,\"Z\":200}]",
                    MinAltitude = 0, MaxAltitude = 1000,
                },
            });
            s.UpdateStep(t.Id, 5);
        }

        private static void SeedPistonWindy(IScenarioService s, DefaultData d)
        {
            var t = s.CreateScenario("[Demo] 活塞拦截-西风5ms", "");
            var scene = d.Environments.First(w => w.Id == "sunny-calm").ToCombatScene();
            scene.WindSpeed = 5;
            scene.WindDirection = (int)WindDirection.W;
            s.SaveScene(t.Id, scene);
            s.SaveScenarioDrone(t.Id, d.Drones.First(p => p.Id == "shahed").ToScenarioDrone());
            s.SaveRoute(t.Id, "default", d.Formations.First(f => f.Id == "single").ToRoutePlan(),
                new List<Waypoint> {
                    new() { PosX = 6600, PosY = 500, PosZ = 0, Speed = 200 },
                    new() { PosX = 0, PosY = 500, PosZ = 0, Speed = 200 },
                });
            s.SaveDeployment(t.Id, new List<ScenarioUnit>
            {
                d.FireUnits.First(f => f.Id == "ground-light").ToScenarioUnit(AerosolType.InertGas, 1, 0, 0, 50),
            });
            s.AddDetection(t.Id, d.Sensors.First(sn => sn.Id == "radar-sr").ToScenarioUnit(0, 0, 50));
            s.SaveCloudDispersal(t.Id, new CloudDispersal { AerosolType = (int)AerosolType.InertGas, DisperseHeight = 500 });
            s.UpdateStep(t.Id, 5);
        }

        private static void SeedJetActiveMaterial(IScenarioService s, DefaultData d)
        {
            var t = s.CreateScenario("[Demo] 喷气式拦截-活性材料", "");
            s.SaveScene(t.Id, d.Environments.First(w => w.Id == "sunny-calm").ToCombatScene());
            s.SaveScenarioDrone(t.Id, d.Drones.First(p => p.Id == "cruise-missile").ToScenarioDrone());
            s.SaveRoute(t.Id, "default", d.Formations.First(f => f.Id == "single").ToRoutePlan(),
                new List<Waypoint> {
                    new() { PosX = 18000, PosY = 500, PosZ = 0, Speed = 200 },
                    new() { PosX = 0, PosY = 500, PosZ = 0, Speed = 200 },
                });
            s.SaveDeployment(t.Id, new List<ScenarioUnit>
            {
                d.FireUnits.First(f => f.Id == "ground-standard").ToScenarioUnit(AerosolType.ActiveMaterial, 1, 0, 0, 50),
            });
            s.AddDetection(t.Id, d.Sensors.First(sn => sn.Id == "radar-mr").ToScenarioUnit(0, 0, 50));
            s.SaveCloudDispersal(t.Id, new CloudDispersal { AerosolType = (int)AerosolType.ActiveMaterial, DisperseHeight = 500 });
            s.UpdateStep(t.Id, 5);
        }

        private static void SeedAirBasedWindy(IScenarioService s, DefaultData d)
        {
            var t = s.CreateScenario("[Demo] 空基拦截-东风5ms", "");
            var scene = d.Environments.First(w => w.Id == "sunny-calm").ToCombatScene();
            scene.WindSpeed = 5;
            scene.WindDirection = (int)WindDirection.E;
            s.SaveScene(t.Id, scene);
            s.SaveScenarioDrone(t.Id, d.Drones.First(p => p.Id == "shahed").ToScenarioDrone());
            s.SaveRoute(t.Id, "default", d.Formations.First(f => f.Id == "single").ToRoutePlan(),
                new List<Waypoint> {
                    new() { PosX = 9500, PosY = 500, PosZ = 0, Speed = 200 },
                    new() { PosX = 0, PosY = 500, PosZ = 0, Speed = 200 },
                });
            s.SaveDeployment(t.Id, new List<ScenarioUnit>
            {
                d.FireUnits.First(f => f.Id == "air-standard").ToScenarioUnit(AerosolType.InertGas, 3, 5000, 1000, 0),
            });
            s.AddDetection(t.Id, d.Sensors.First(sn => sn.Id == "eo-station").ToScenarioUnit(5000, 1000, 0));
            s.SaveCloudDispersal(t.Id, new CloudDispersal { AerosolType = (int)AerosolType.InertGas, DisperseHeight = 500 });
            s.UpdateStep(t.Id, 5);
        }

        private static void Seed3DronesAirBased(IScenarioService s, DefaultData d)
        {
            var t = s.CreateScenario("[Demo] 3架空基编队拦截", "");
            var scene = d.Environments.First(w => w.Id == "sunny-calm").ToCombatScene();
            scene.WindSpeed = 5;
            scene.WindDirection = (int)WindDirection.E;
            s.SaveScene(t.Id, scene);
            var target = d.Drones.First(p => p.Id == "shahed").ToScenarioDrone();
            target.Quantity = 3;
            s.SaveScenarioDrone(t.Id, target);
            s.SaveRoute(t.Id, "default", d.Formations.First(f => f.Id == "line-3").ToRoutePlan(),
                new List<Waypoint> {
                    new() { PosX = 10000, PosY = 500, PosZ = 0, Speed = 200 },
                    new() { PosX = 0, PosY = 500, PosZ = 0, Speed = 200 },
                });
            s.SaveDeployment(t.Id, new List<ScenarioUnit>
            {
                d.FireUnits.First(f => f.Id == "air-standard").ToScenarioUnit(AerosolType.InertGas, 1, 5000, 1000, 0),
                d.FireUnits.First(f => f.Id == "air-standard").ToScenarioUnit(AerosolType.InertGas, 1, 5300, 1000, 0),
                d.FireUnits.First(f => f.Id == "air-standard").ToScenarioUnit(AerosolType.InertGas, 1, 5600, 1000, 0),
            });
            s.AddDetection(t.Id, d.Sensors.First(sn => sn.Id == "eo-station").ToScenarioUnit(5000, 1000, 0));
            s.SaveCloudDispersal(t.Id, new CloudDispersal { AerosolType = (int)AerosolType.InertGas, DisperseHeight = 500 });
            s.UpdateStep(t.Id, 5);
        }
    }
}
