using System.Collections.Generic;
using System.IO;
using CounterDrone.Core;
using CounterDrone.Core.Algorithms;
using CounterDrone.Core.Models;
using CounterDrone.Core.Repository;
using CounterDrone.Core.Services;
using UnityEngine;
using UVector3 = UnityEngine.Vector3;
using AVector3 = CounterDrone.Core.Algorithms.Vector3;

namespace CounterDrone.Unity
{
    /// <summary>一键启动：创建想定 → 推荐方案 → 运行仿真</summary>
    public class SimulationBootstrap : MonoBehaviour
    {
        [Header("Simulation Settings")]
        [SerializeField] private float _droneSpeed = 200f;
        [SerializeField] private float _routeLength = 20000f;
        [SerializeField] private float _timeScale = 4f;

        public SimulationRunner Runner { get; private set; }

        void Start()
        {
            var paths = new UnityPathProvider();

            // 清理上次残留数据
            if (System.IO.File.Exists(paths.GetMainDbPath()))
                System.IO.File.Delete(paths.GetMainDbPath());
            if (System.IO.Directory.Exists(paths.GetFramesDir()))
                System.IO.Directory.Delete(paths.GetFramesDir(), true);

            var dbm = new DatabaseManager(paths);
            var db = dbm.OpenMainDb();
            SqliteConnectionTracker.Track(db);
            foreach (var a in DefaultAmmunition.GetAll()) db.Insert(a);

            // 创建想定
            var scenario = new ScenarioService(
                new SimTaskRepository(db), new CombatSceneRepository(db),
                new ControlZoneRepository(db), new TargetConfigRepository(db),
                new EquipmentDeploymentRepository(db), new CloudDispersalRepository(db),
                new RoutePlanRepository(db), new WaypointRepository(db));

            var task = scenario.CreateTask("Unity Demo", "");
            var taskId = task.Id;

            scenario.SaveScene(taskId, new CombatScene
            {
                SceneType = (int)SceneType.Plain, WindSpeed = 3,
                WindDirection = (int)WindDirection.W, Temperature = 22,
            });
            scenario.SaveTarget(taskId, new TargetConfig
            {
                GroupId = "default",
                TargetType = (int)TargetType.Piston, PowerType = (int)PowerType.Piston,
                Quantity = 1, TypicalSpeed = _droneSpeed, TypicalAltitude = 500,
            });
            scenario.SaveRoute(taskId, "default", new RoutePlan { FormationMode = (int)FormationMode.Single },
                new List<Waypoint>
                {
                    new Waypoint { PosX = 0, PosY = 500, PosZ = 0, Speed = _droneSpeed },
                    new Waypoint { PosX = _routeLength, PosY = 500, PosZ = 0, Speed = _droneSpeed },
                });

            // 推荐方案
            var detail = scenario.GetTaskDetail(taskId);
            var ammoCatalog = db.Table<AmmunitionSpec>().ToList();
            var planner = new DefaultDefensePlanner(ammoCatalog);
            var droneGroup = new DroneGroup
            {
                GroupId = "default",
                Target = detail.Targets[0],
                Route = detail.Routes[0],
                Waypoints = detail.WaypointGroups["default"],
            };
            var fireUnits = new List<FireUnit>();
            for (int i = 0; i < 8; i++)
                fireUnits.Add(new FireUnit
                {
                    Id = $"u{i}",
                    Type = PlatformType.GroundBased,
                    Position = new AVector3(5000 + i * 50, 0, 50),
                    MuzzleVelocity = 800,
                    TotalMunitions = 3,
                    AmmoTypes = new() { AerosolType.InertGas, AerosolType.ActiveMaterial, AerosolType.ActiveFuel },
                });
            var result = planner.Plan(fireUnits, new List<DroneGroup> { droneGroup }, detail.Scene);
            scenario.SaveCloudDispersal(taskId, new CloudDispersal
            {
                PositionX = (droneGroup.Waypoints[0].PosX + droneGroup.Waypoints[^1].PosX) / 2,
                PositionY = (droneGroup.Waypoints[0].PosY + droneGroup.Waypoints[^1].PosY) / 2,
                PositionZ = (droneGroup.Waypoints[0].PosZ + droneGroup.Waypoints[^1].PosZ) / 2,
                DisperseHeight = droneGroup.Target.TypicalAltitude,
                Source = "Algorithm",
            });

            var equips = new List<EquipmentDeployment>();
            foreach (var u in fireUnits)
                equips.Add(new EquipmentDeployment
                {
                    EquipmentRole = (int)EquipmentRole.LaunchPlatform,
                    PlatformType = (int)u.Type, Quantity = 1,
                    PositionX = u.Position.X, PositionY = u.Position.Y, PositionZ = u.Position.Z,
                    AerosolType = (int)u.AmmoTypes[0],
                    MunitionCount = u.TotalMunitions, Cooldown = u.Cooldown, MuzzleVelocity = u.MuzzleVelocity,
                    CruiseSpeed = u.CruiseSpeed > 0 ? u.CruiseSpeed : null,
                    ReleaseAltitude = u.ReleaseAltitude > 0 ? u.ReleaseAltitude : null,
                });
            scenario.SaveDeployment(taskId, equips);

            SqliteConnectionTracker.Untrack(db);
            db.Dispose();

            var plan = result.Best;
            Debug.Log($"规划方案: {plan.ThreatsEngaged} 威胁被分配, {plan.MergedSchedule.Count} 发, 概率 {plan.OverallProbability:P0}");

            // 运行仿真
            Runner = GetComponent<SimulationRunner>();
            if (Runner == null) Runner = gameObject.AddComponent<SimulationRunner>();
            else Runner.enabled = true;
            Runner.LoadAndStart(taskId);

            // 设置倍速
            if (Runner.Engine != null)
            {
                Runner.Engine.TimeScale = _timeScale;
                Debug.Log($"Engine state: {Runner.Engine.State}, drones: {Runner.Engine.Drones.Count}");
            }

            // 移动 Game 视图相机
            var cam = Camera.main;
            if (cam == null) { var cgo = new GameObject("MainCamera"); cgo.AddComponent<Camera>(); cam = cgo.GetComponent<Camera>(); cam.tag = "MainCamera"; }
            cam.transform.position = new UVector3(_routeLength / 2f, 2000, -3000);
            cam.transform.LookAt(new UVector3(_routeLength / 2f, 500, 0));
            Debug.Log("Camera positioned. In Scene view, double-click 'Simulation' in Hierarchy to focus.");
        }
    }
}
