using System.Collections.Generic;
using System.Linq;
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>
    /// 前端参考模板 — 展示两种运行方式：
    ///   1. 预设模式：直接运行数据库中的 [Demo] 想定（最简单）
    ///   2. 自定义模式：用 DefaultData 预设快速组装新想定 → Planner → 仿真
    /// </summary>
    public class SimulationBootstrap : MonoBehaviour
    {
        [Header("Mode")]
        [SerializeField] private bool _usePreset = true;  // true=预设想定, false=自定义

        [Header("Custom Settings")]
        [SerializeField] private float _droneSpeed = 200f;
        [SerializeField] private float _routeLength = 5000f;
        [SerializeField] private float _timeScale = 4f;

        public SimulationRunner Runner { get; private set; }

        void Start()
        {
            var paths = new UnityPathProvider();
            var dbm = new DatabaseManager(paths);
            var db = dbm.OpenMainDb(); // 自动种子弹药 + 6个[Demo]想定 + 基础数据
            SqliteConnectionTracker.Track(db);

            var dataService = new DataService(
                new AmmunitionSpecRepository(db), new FireUnitSpecRepository(db),
                new DroneSpecRepository(db), new SensorSpecRepository(db),
                new EnvironmentSpecRepository(db), new FormationTemplateRepository(db),
                new RouteTemplateRepository(db));

            var scenario = new ScenarioService(
                new ScenarioRepository(db), new CombatSceneRepository(db),
                new ControlZoneRepository(db), new ScenarioDroneRepository(db),
                new ScenarioUnitRepository(db), new CloudDispersalRepository(db),
                new RoutePlanRepository(db), new WaypointRepository(db));

            string scenarioId;

            if (_usePreset)
            {
                // 方式1：直接使用预设想定（最简单）
                var demos = scenario.SearchScenarios("Demo", null, null, 1, 1);
                if (demos.TotalCount == 0)
                {
                    Debug.LogError("无预设想定，请确认 defaults.json 已放入 StreamingAssets");
                    return;
                }
                scenarioId = demos.Items[0].Id;
                Debug.Log($"使用预设想定: {demos.Items[0].Name}");
            }
            else
            {
                // 方式2：用 DefaultData 预设组装自定义想定
                var defaults = DefaultData.Load(paths);

                var sc = scenario.CreateScenario("Unity Demo", "");
                scenarioId = sc.Id;

                scenario.SaveScene(scenarioId, defaults.Environments.First(w => w.Id == "sunny-calm").ToCombatScene());
                scenario.SaveScenarioDrone(scenarioId, defaults.Drones.First(p => p.Id == "shahed").ToScenarioDrone());
                scenario.SaveRoute(scenarioId, "default",
                    defaults.Formations.First(f => f.Id == "single").ToRoutePlan(),
                    defaults.Routes.First(r => _routeLength > 6000 ? r.Id == "10km-h500" : r.Id == "5km-h500")
                        .ToWaypoints(_droneSpeed));

                // 从火力单元预设构建 FireUnit → Planner 自动生成方案 → 引擎执行
                var detail = scenario.GetScenarioDetail(scenarioId);
                var ammoCatalog = db.Table<AmmunitionSpec>().ToList();
                var planner = new DefensePlanner(ammoCatalog, PlannerConfig.Load(paths));
                var threats = new List<DroneWave>
                {
                    new DroneWave { WaveId = "default",
                        Profile = db.Table<DroneSpec>().First(d => d.Id == "shahed"),
                        Route = detail.Routes[0], Waypoints = detail.WaypointGroups["default"] }
                };
                var fireUnits = new List<FireUnit>();
                for (int i = 0; i < 4; i++)
                    fireUnits.Add(new FireUnit
                    {
                        Id = $"fu{i}",
                        Type = PlatformType.GroundBased,
                        Position = new AVector3(_routeLength / 2f + i * 50, 0, 50),
                        MuzzleVelocity = 800, TotalMunitions = 3,
                        AmmoTypes = new() { AerosolType.InertGas, AerosolType.ActiveMaterial, AerosolType.ActiveFuel },
                    });
                var plan = planner.Plan(fireUnits, threats, detail.Scene, new List<DetectionSource>());

                scenario.SaveCloudDispersal(scenarioId, new CloudDispersal
                {
                    AerosolType = (int)AerosolType.InertGas,
                    DisperseHeight = db.Table<DroneSpec>().First(d => d.Id == "shahed").TypicalAltitude,
                    Source = "Algorithm",
                });
                scenario.SaveDeployment(scenarioId, new List<ScenarioUnit>
                {
                    defaults.FireUnits.First(f => f.Id == "ground-light")
                        .ToScenarioUnit(AerosolType.InertGas, 1, _routeLength / 2f, 0, 50),
                });
                scenario.UpdateStep(scenarioId, 5);

                Debug.Log($"自定义想定: {plan.Best.ThreatsEngaged} 威胁已分配, {plan.Best.MergedSchedule.Count} 发, 概率 {plan.Best.OverallProbability:P0}");
            }

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

            // 运行仿真
            Runner = GetComponent<SimulationRunner>();
            if (Runner == null) Runner = gameObject.AddComponent<SimulationRunner>();
            else Runner.enabled = true;
            Runner.DataService = dataService;
            Runner.LoadAndStart(scenarioId);
            Runner.Engine.TimeScale = _timeScale;

            // 定位相机
            var cam = Camera.main;
            if (cam == null) { cam = new GameObject("MainCamera").AddComponent<Camera>(); cam.tag = "MainCamera"; }
            float midX = _usePreset ? 2500f : _routeLength / 2f;
            cam.transform.position = new UVector3(midX, 2000, -3000);
            cam.transform.LookAt(new UVector3(midX, 500, 0));
        }
    }
}
