using KYFramework;
using MongoDB.Bson;
using SimulationServer.Utils;

namespace SimulationServer;

public class XHRescueMission : Entity
{
    public string MissionId; // 任务ID
    public bool Success; // 任务是否成功

    // 火场点
    public FireGround FireGround;

    public double tn;
    
    public List<AircraftXH> AircraftXHs = new List<AircraftXH>();

    public bool IsRunning;
    public Action End;
    public double SimulationTime;
    
    public int ExcuteCount = 0;
    public int FailureTimes = 0;
   
   // 巡护的 单机能力
   // <机型,<sheet,<指标名,值列表>>>
   public Dictionary<string,Dictionary<string,Dictionary<string,List<string>>>> singleReport = new ();
    
    
    // 灭火的 整体能力
    public Dictionary<string, Dictionary<string, List<string>>> totalXhReport = new ();

    public Dictionary<string, Dictionary<string, List<string>>> equipReport = new ();

    public void Reset()
    {
        
    }
    
    public void Start()
    {
        IsRunning = true;
        Log.Info($"{MissionId} 任务开始!");
        AircraftXHs.ForEach(a => a.Start());
    }
    
    public void EndMission()
    {
        IsRunning = false;
        Log.Info($"{MissionId} 任务结束!");
        // 灭火完成 任务结束
        End?.Invoke();
        SaveXH();
        ReportXH();
        
        var readyTime = AircraftXHs.First().TaskReadyTime;
        Task.Delay(TimeSpan.FromSeconds(readyTime)).ContinueWith(t => this.StartAsyncXH());
    }

    

    public void SaveXH()
    {
        foreach (AircraftXH aircraftXh in AircraftXHs)
        {
            var staticCapacity = aircraftXh.GetComponent<XHStaticCapacityComponent>();
            var economical = aircraftXh.GetComponent<XHEconomicalComponent>();
            
            staticCapacity.FillData(aircraftXh.Db);
            economical.FillData(aircraftXh.Db);

            if (!singleReport.ContainsKey(aircraftXh.AircraftId))
            {
                singleReport[aircraftXh.AircraftId] = new Dictionary<string, Dictionary<string, List<string>>>();
            }


            // 1次的报告
            Dictionary<string, Dictionary<string, string>> staticReport = staticCapacity.GetReport();
            foreach (var kv in staticReport)
            {
                if(!singleReport[aircraftXh.AircraftId].ContainsKey(kv.Key)) singleReport[aircraftXh.AircraftId][kv.Key] = new Dictionary<string, List<string>>();
                foreach (var kv2 in kv.Value)
                {
                    if (!singleReport[aircraftXh.AircraftId][kv.Key].ContainsKey(kv2.Key)) singleReport[aircraftXh.AircraftId][kv.Key][kv2.Key] = new List<string>();
                    singleReport[aircraftXh.AircraftId][kv.Key][kv2.Key].Add(kv2.Value);
                }
            }
            Dictionary<string, Dictionary<string, string>> economicalReport = economical.GetReport();
            foreach (var kv in economicalReport)
            {
                if(!singleReport[aircraftXh.AircraftId].ContainsKey(kv.Key)) singleReport[aircraftXh.AircraftId][kv.Key] = new Dictionary<string, List<string>>();
                foreach (var kv2 in kv.Value)
                {
                    if (!singleReport[aircraftXh.AircraftId][kv.Key].ContainsKey(kv2.Key)) singleReport[aircraftXh.AircraftId][kv.Key][kv2.Key] = new List<string>();
                    singleReport[aircraftXh.AircraftId][kv.Key][kv2.Key].Add(kv2.Value);
                }
            }
        }
        
        var totalPerformance = GetComponent<XHTotalTaskPerformanceComponent>();
        totalPerformance.FillData();
        var totalPerformanceReport = totalPerformance.GetReport();
        foreach (var kv in totalPerformanceReport)
        {
            if(!totalXhReport.ContainsKey(kv.Key)) totalXhReport[kv.Key] = new Dictionary<string, List<string>>();
            foreach (var kv2 in kv.Value)
            {
                if (!totalXhReport[kv.Key].ContainsKey(kv2.Key)) totalXhReport[kv.Key][kv2.Key] = new List<string>();
                totalXhReport[kv.Key][kv2.Key].Add(kv2.Value);
            }
        }
        
        var TotalEquipment = GetComponent<EquipmentComponent>();
        TotalEquipment.FillData();
        var totalEquipmentReport = TotalEquipment.GetReport();
        foreach (var kv in totalEquipmentReport)
        {
            if(!equipReport.ContainsKey(kv.Key)) equipReport[kv.Key] = new Dictionary<string, List<string>>();
            foreach (var kv2 in kv.Value)
            {
                if (!equipReport[kv.Key].ContainsKey(kv2.Key)) equipReport[kv.Key][kv2.Key] = new List<string>();
                equipReport[kv.Key][kv2.Key].Add(kv2.Value);
            }
        }
    }

    public void ReportXH()
    {
        string data = DateTime.Now.ToString("yyyy-MM-dd");
        string path = $"Reports/XH/{data}/{MissionId}";
        if(!Directory.Exists(path)) Directory.CreateDirectory(path);
        foreach (var kv in singleReport)
        {
            string filePath = $"{path}/{kv.Key}巡护任务单机指标报告.xls";
            DataTableExtensions.SaveToExcel(filePath, kv.Value);
        }
        string totalPath = $"{path}/{"巡护任务总体指标报告"}.xls";
        DataTableExtensions.SaveToExcel(totalPath, totalXhReport);
        
        string equicPath = $"{path}/{"装备体系评估报告"}.xls";
        DataTableExtensions.SaveToExcel(equicPath, equipReport);
    }
}

[ObjectSystem]
public class XHRescueMissionUpdateSystem : UpdateSystem<XHRescueMission>
{
    public override void Update(XHRescueMission self)
    {
        if(!self.IsRunning) return;
        
        foreach (var aircraftXh in self.AircraftXHs)
        {
            if(aircraftXh.isOver)
            {
                self.EndMission();
                self.IsRunning = false;
            }
        }
    }
}