using System;
using System.Collections.Generic;
using System.Linq;
using CounterDrone.Core;
using CounterDrone.Core.Models;
using CounterDrone.Core.Reporting;
using CounterDrone.Core.Simulation;

namespace CounterDrone.Core.Services
{
    public class ReportGenerator
    {
        public ReportData Generate(ScenarioConfig config, List<SimEvent> events,
            Simulation.DroneStatus finalDroneStatus, float simulationDuration,
            Dictionary<string, DroneSpec> droneSpecs,
            Dictionary<string, LaunchPlatformSpec> fireUnitSpecs,
            Dictionary<string, SensorSpec> sensorSpecs)
        {
            var platforms = config.Units.Where(e => e.EquipmentRole == (int)EquipmentRole.LaunchPlatform).ToList();
            var target = config.Drones.FirstOrDefault();
            var scene = config.Scene;
            var destroyed = events.Count(e => e.Type == SimEventType.DroneDestroyed);
            var reached = events.Count(e => e.Type == SimEventType.DroneReachedTarget);
            var intruded = events.Count(e => e.Type == SimEventType.ZoneIntruded);
            var totalDrones = config.Drones.Sum(t => t.Quantity);
            var result = DetermineInterceptResult(destroyed, reached + intruded, totalDrones);

            var data = new ReportData
            {
                Title = "仿真评估报告",
                Header = new List<MetaItem>
                {
                    new() { Label = "任务名称", Value = config.Info.Name },
                    new() { Label = "任务编号", Value = config.Info.ScenarioNumber },
                    new() { Label = "仿真耗时", Value = $"{simulationDuration:F1} 秒" },
                    new() { Label = "气溶胶类型", Value = TranslateAerosol((AerosolType)config.Cloud.AerosolType) },
                },
            };

            // === 一、仿真结果 ===
            data.Sections.Add(new ReportSection
            {
                Title = "一、仿真结果",
                Blocks = new List<ReportBlock>
                {
                    new KeyValueBlock
                    {
                        LabelHeader = "统计项",
                        Items = new List<MetaItem>
                        {
                            new() { Label = "无人机总数", Value = totalDrones.ToString() },
                            new() { Label = "被摧毁", Value = destroyed.ToString() },
                            new() { Label = "到达目标", Value = reached.ToString() },
                            new() { Label = "侵入管控区", Value = intruded.ToString() },
                            new() { Label = "弹药发射", Value = events.Count(e => e.Type == SimEventType.MunitionLaunched).ToString() },
                            new() { Label = "目标发现", Value = events.Count(e => e.Type == SimEventType.TargetDetected).ToString() },
                            new() { Label = "云团生成", Value = events.Count(e => e.Type == SimEventType.CloudGenerated).ToString() },
                        },
                    },
                    new TextBlock { Text = $"对抗结果：{TranslateResult(result)}", Bold = true },
                },
            });

            // === 二、作战环境 ===
            data.Sections.Add(new ReportSection
            {
                Title = "二、作战环境",
                Blocks = new List<ReportBlock>
                {
                    new KeyValueBlock
                    {
                        Items = new List<MetaItem>
                        {
                            new() { Label = "场景类型", Value = TranslateScene((SceneType)scene.SceneType) },
                            new() { Label = "时间段", Value = scene.TimeOfDay },
                            new() { Label = "天气", Value = TranslateWeather((WeatherType)scene.WeatherType) },
                            new() { Label = "风速", Value = $"{scene.WindSpeed:F1} m/s" },
                            new() { Label = "风向", Value = TranslateWindDirection((WindDirection)scene.WindDirection) },
                            new() { Label = "温度", Value = $"{scene.Temperature:F1}°C" },
                            new() { Label = "湿度", Value = $"{scene.Humidity:F0}%RH" },
                            new() { Label = "气压", Value = $"{scene.Pressure:F0} hPa" },
                            new() { Label = "能见度", Value = $"{scene.Visibility:F0} m" },
                            new() { Label = "场景范围", Value = $"{scene.SceneWidth:F0} × {scene.SceneLength:F0} × {scene.SceneHeight:F0} m (W×L×H)" },
                        },
                    },
                },
            });

            // === 三、威胁目标 ===
            droneSpecs.TryGetValue(target?.DroneSpecId ?? "", out var droneSpec);
            data.Sections.Add(new ReportSection
            {
                Title = "三、威胁目标",
                Blocks = new List<ReportBlock>
                {
                    new KeyValueBlock
                    {
                        Items = new List<MetaItem>
                        {
                            new() { Label = "类型", Value = TranslateTarget((DroneType)(droneSpec?.DroneType ?? 0)) },
                            new() { Label = "动力", Value = TranslatePower((PowerType)(droneSpec?.PowerType ?? 0)) },
                            new() { Label = "数量", Value = $"{totalDrones} 架" },
                            new() { Label = "翼展", Value = $"{droneSpec?.Wingspan ?? 0:F1} m" },
                            new() { Label = "速度", Value = $"{droneSpec?.TypicalSpeed ?? 0:F0} km/h" },
                            new() { Label = "高度", Value = $"{droneSpec?.TypicalAltitude ?? 0:F0} m" },
                        },
                    },
                },
            });

            // === 四、云团抛撒配置 ===
            var cloudItems = new List<MetaItem>
            {
                new() { Label = "气溶胶类型", Value = TranslateAerosol((AerosolType)config.Cloud.AerosolType) },
                new() { Label = "抛撒高度", Value = $"{config.Cloud.DisperseHeight:F0} m" },
                new() { Label = "触发模式", Value = TranslateTrigger((TriggerMode)config.Cloud.TriggerMode) },
                new() { Label = "释放方式", Value = TranslateRelease((ReleaseMode)config.Cloud.ReleaseMode) },
                new() { Label = "扩散方向", Value = $"{config.Cloud.SpreadAngle:F0}°" },
                new() { Label = "初始规模", Value = $"{config.Cloud.InitialScale:F0} m³" },
                new() { Label = "持续时间", Value = $"{config.Cloud.Duration:F0} s" },
                new() { Label = "释放总量", Value = $"{config.Cloud.TotalAmount:F1} kg" },
                new() { Label = "配置来源", Value = config.Cloud.Source },
            };
            if (config.Cloud.Source == "Algorithm" && config.Cloud.EstimatedProbability.HasValue)
            {
                cloudItems.Add(new() { Label = "推荐弹药数", Value = $"{config.Cloud.SalvoRounds} 发" });
                cloudItems.Add(new() { Label = "云团间距", Value = $"{config.Cloud.SalvoSpacing:F0} m" });
                cloudItems.Add(new() { Label = "拦截概率估计", Value = $"{config.Cloud.EstimatedProbability.Value:P0}" });
                cloudItems.Add(new() { Label = "抛撒时机", Value = $"{config.Cloud.RecommendedTiming:F0}s" });
            }
            data.Sections.Add(new ReportSection
            {
                Title = "四、云团抛撒配置",
                Blocks = new List<ReportBlock> { new KeyValueBlock { Items = cloudItems } },
            });

            // 构建 PlatformId → 火力单元 映射（去重，五和六共用）
            var platToEquip = new Dictionary<string, int>();
            var unitLaunchCounts = new Dictionary<int, int>();
            int platIdx = 1, unitNum = 0;
            for (int ei = 0; ei < config.Units.Count; ei++)
            {
                var eq = config.Units[ei];
                if (eq.EquipmentRole != (int)EquipmentRole.LaunchPlatform) continue;
                fireUnitSpecs.TryGetValue(eq.LaunchPlatformSpecId, out var fuSpec);
                int channels = (fuSpec?.GunCount ?? 1) * (fuSpec?.ChannelsPerGun ?? 1);
                for (int j = 0; j < eq.Quantity; j++)
                {
                    unitNum++;
                    for (int c = 0; c < channels; c++)
                        platToEquip[$"plat_{platIdx++}"] = unitNum;
                }
            }
            foreach (var e in events.Where(e => e.Type == SimEventType.MunitionLaunched))
            {
                if (platToEquip.TryGetValue(e.SourceId, out var u))
                    unitLaunchCounts[u] = unitLaunchCounts.GetValueOrDefault(u, 0) + 1;
            }

            // === 五、我方部署 ===
            var deployBlocks = new List<ReportBlock>();

            // 发射平台表
            var platRows = new List<string[]>();
            int unitNum2 = 0;
            foreach (var eq in config.Units.Where(e => e.EquipmentRole == (int)EquipmentRole.LaunchPlatform))
            {
                fireUnitSpecs.TryGetValue(eq.LaunchPlatformSpecId, out var fuSpec);
                int channels = (fuSpec?.GunCount ?? 1) * (fuSpec?.ChannelsPerGun ?? 1);
                for (int j = 0; j < eq.Quantity; j++)
                {
                    unitNum2++;
                    int fired = unitLaunchCounts.GetValueOrDefault(unitNum2, 0);
                    string ptype = ((PlatformType?)(fuSpec?.PlatformType ?? 0)) == PlatformType.AirBased ? "空基" : "地基";
                    string ammo = eq.AerosolType.HasValue ? TranslateAerosol((AerosolType)eq.AerosolType) : "-";
                    platRows.Add(new[] { $"#{unitNum2}", ptype, $"({eq.PositionX + j * 50:F0}, {eq.PositionY:F0}, {eq.PositionZ:F0})", ammo, $"{eq.MunitionCount ?? channels}", $"{fired}" });
                }
            }
            deployBlocks.Add(new TableBlock
            {
                Caption = "发射平台",
                Headers = new[] { "#", "平台类型", "位置 (X,Y,Z)", "弹药类型", "挂载量", "发射数" },
                Rows = platRows,
            });

            // 探测设备表
            var detections = config.Units.Where(e => e.EquipmentRole == (int)EquipmentRole.Detection).ToList();
            if (detections.Count > 0)
            {
                var detRows = new List<string[]>();
                int detIdx = 0;
                foreach (var d in detections)
                {
                    sensorSpecs.TryGetValue(d.SensorSpecId, out var sensor);
                    for (int j = 0; j < d.Quantity; j++)
                        detRows.Add(new[] { $"D{++detIdx}", $"({d.PositionX:F0}, {d.PositionY:F0}, {d.PositionZ:F0})", $"{(sensor?.RadarRange ?? 0):F0}", $"{(sensor?.EORange ?? 0):F0}", $"{(sensor?.IRRange ?? 0):F0}", $"{(sensor?.Accuracy ?? 0):F0} m", "1" });
                }
                deployBlocks.Add(new TableBlock
                {
                    Caption = "探测设备",
                    Headers = new[] { "#", "位置 (X,Y,Z)", "雷达", "光电", "红外", "精度", "数量" },
                    Rows = detRows,
                });
            }

            // 管控区域表
            if (config.ControlZones.Count > 0)
            {
                var zoneRows = new List<string[]>();
                int zIdx = 0;
                foreach (var z in config.ControlZones)
                    zoneRows.Add(new[] { $"Z{++zIdx}", z.Name, $"{(int)z.MinAltitude}-{(int)z.MaxAltitude} m" });
                deployBlocks.Add(new TableBlock
                {
                    Caption = "管控区域",
                    Headers = new[] { "#", "名称", "高度范围" },
                    Rows = zoneRows,
                });
            }

            data.Sections.Add(new ReportSection { Title = "五、我方部署", Blocks = deployBlocks });

            // === 六、事件时序 ===
            var eventRows = new List<string[]>();
            int munitionIdx = 0, cloudIdx = 0;
            foreach (var e in events.OrderBy(e => e.OccurredAt))
            {
                string unitCell = e.Type == SimEventType.MunitionLaunched && platToEquip.TryGetValue(e.SourceId, out var u)
                    ? $"#{u}" : "-";
                string prefix = e.Type switch
                {
                    SimEventType.MunitionLaunched => $"第 {++munitionIdx} 发",
                    SimEventType.CloudGenerated => $"云团 #{++cloudIdx}",
                    _ => string.Empty,
                };
                string desc = string.IsNullOrEmpty(prefix) ? e.Description : $"{prefix} · {e.Description}";
                eventRows.Add(new[] { $"{e.OccurredAt:F2}", TranslateEvent(e.Type), desc, unitCell });
            }
            data.Sections.Add(new ReportSection
            {
                Title = "六、事件时序",
                Blocks = new List<ReportBlock>
                {
                    new TableBlock
                    {
                        Headers = new[] { "时间(s)", "事件", "详情", "火力单元" },
                        Rows = eventRows,
                    },
                },
            });

            // === 七、时间线 ===
            var launches = events.Where(e => e.Type == SimEventType.MunitionLaunched).Select(e => e.OccurredAt).OrderBy(t => t).ToList();
            var clouds = events.Where(e => e.Type == SimEventType.CloudGenerated).Select(e => e.OccurredAt).OrderBy(t => t).ToList();
            var destroys = events.Where(e => e.Type == SimEventType.DroneDestroyed).Select(e => e.OccurredAt).OrderBy(t => t).ToList();
            float launchFirst = launches.DefaultIfEmpty(0).FirstOrDefault();
            float launchLast = launches.DefaultIfEmpty(0).LastOrDefault();
            float cloudFirst = clouds.DefaultIfEmpty(0).FirstOrDefault();
            float destroyFirst = destroys.DefaultIfEmpty(0).FirstOrDefault();

            var timelineRows = new List<string[]>();
            if (launchFirst > 0)
            {
                timelineRows.Add(new[] { "首发发射", $"{launchFirst:F1}s", "-" });
                if (launches.Count > 1)
                    timelineRows.Add(new[] { "末发发射", $"{launchLast:F1}s", $"{launchLast - launchFirst:F1}s（弹群展开）" });
                timelineRows.Add(new[] { "发射 → 云团生成", $"{launchFirst:F1}s → {cloudFirst:F1}s", $"{cloudFirst - launchFirst:F1}s（弹药飞行）" });
            }
            if (destroyFirst > 0)
                timelineRows.Add(new[] { "云团生成 → 首个击毁", $"{cloudFirst:F1}s → {destroyFirst:F1}s", $"{destroyFirst - cloudFirst:F1}s（暴露毁伤）" });
            timelineRows.Add(new[] { "总耗时", $"0 → {simulationDuration:F1}s", $"{simulationDuration:F1}s" });

            var timelineBlocks = new List<ReportBlock>
            {
                new TableBlock
                {
                    Headers = new[] { "阶段", "时间", "耗时" },
                    Rows = timelineRows,
                },
                new TextBlock { Text = "统计汇总：", Bold = true },
            };

            var summaryLines = new List<string>
            {
                $"- 弹药发射 {launches.Count} 发，云团生成 {clouds.Count} 朵，击毁 {destroys.Count} 架",
            };
            if (launchFirst > 0 && launchLast > 0)
                summaryLines.Add($"- 发射窗口 {launchLast - launchFirst:F1}s，弹药飞行 {(cloudFirst - launchFirst):F1}s");
            timelineBlocks.Add(new TextBlock { Text = string.Join("\n", summaryLines) });

            data.Sections.Add(new ReportSection { Title = "七、时间线", Blocks = timelineBlocks });

            return data;
        }

        public InterceptResult DetermineInterceptResult(int destroyed, int reachedOrIntruded, int total)
        {
            if (total == 0) return InterceptResult.Failed;
            if (destroyed >= total) return InterceptResult.Success;
            if (destroyed > 0) return InterceptResult.Partial;
            return InterceptResult.Failed;
        }

        private static string TranslateResult(InterceptResult r) => r switch
        {
            InterceptResult.Success => "成功拦截",
            InterceptResult.Partial => "部分拦截",
            InterceptResult.Failed => "拦截失败",
            _ => "未知",
        };

        private static string TranslateAerosol(AerosolType t) => t switch
        {
            AerosolType.InertGas => "惰性气体（吸入式灭火）",
            AerosolType.ActiveMaterial => "活性材料（爆燃式）",
            AerosolType.ActiveFuel => "活性燃料（吸入式爆炸）",
            _ => t.ToString(),
        };

        private static string TranslateWeather(WeatherType w) => w switch
        {
            WeatherType.Sunny => "晴天", WeatherType.Overcast => "阴天",
            WeatherType.Fog => "雾天", WeatherType.Rain => "雨天",
            WeatherType.Night => "夜间", _ => w.ToString(),
        };

        private static string TranslateWindDirection(WindDirection d) => d switch
        {
            WindDirection.N => "北 (N)", WindDirection.NE => "东北 (NE)",
            WindDirection.E => "东 (E)", WindDirection.SE => "东南 (SE)",
            WindDirection.S => "南 (S)", WindDirection.SW => "西南 (SW)",
            WindDirection.W => "西 (W)", WindDirection.NW => "西北 (NW)",
            _ => d.ToString(),
        };

        private static string TranslateScene(SceneType s) => s switch
        {
            SceneType.Urban => "城市", SceneType.Plain => "平原",
            SceneType.Mountain => "山区", SceneType.Coast => "海岸",
            _ => s.ToString(),
        };

        private static string TranslateTrigger(TriggerMode t) => t switch
        {
            TriggerMode.Time => "时间触发", TriggerMode.Area => "区域触发",
            TriggerMode.Manual => "手动触发", _ => t.ToString(),
        };

        private static string TranslateTarget(DroneType t) => t switch
        {
            DroneType.Rotor => "旋翼", DroneType.FixedWing => "固定翼",
            DroneType.HighSpeed => "高速目标", _ => t.ToString(),
        };

        private static string TranslatePower(PowerType p) => p switch
        {
            PowerType.Electric => "电推式", PowerType.Piston => "活塞式",
            PowerType.Jet => "喷吸气式", _ => p.ToString(),
        };

        private static string TranslateRelease(ReleaseMode r) => r switch
        {
            ReleaseMode.Single => "单次齐射", ReleaseMode.Continuous => "连续释放",
            ReleaseMode.Pulse => "脉冲释放", _ => r.ToString(),
        };

        private static string TranslateEvent(SimEventType t) => t switch
        {
            SimEventType.MunitionLaunched => "弹药发射",
            SimEventType.CloudGenerated => "云团生成",
            SimEventType.DroneDestroyed => "目标击毁",
            SimEventType.DroneReachedTarget => "抵达目标",
            SimEventType.ZoneIntruded => "侵入管控区",
            SimEventType.SimulationEnd => "仿真结束",
            SimEventType.TargetDetected => "目标发现",
            _ => t.ToString(),
        };
    }
}
