/**
 * @file main.cpp
 * @brief 战场任务规划管理系统 - 命令行入口
 *
 * @requirement(name="业务目标", id="REQ-BMP-001")
 * 提供命令行交互接口，演示从事件接收、模板管理、任务生成到方案分发、状态监控的完整闭环流程。
 */

#include "app.hpp"
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <thread>
#include <chrono>

using namespace bmp;

/**
 * @brief 打印事件信息
 */
static void printEvent(const Event& evt) {
    std::cout << "  [事件] ID: " << evt.id
              << " | 标题: " << evt.title
              << " | 优先级: " << static_cast<int>(evt.priority)
              << " | 状态: ";
    switch (evt.status) {
        case EventStatus::PENDING:   std::cout << "待处理"; break;
        case EventStatus::PROCESSING: std::cout << "处理中"; break;
        case EventStatus::ACCEPTED:  std::cout << "已接受"; break;
        case EventStatus::REJECTED:  std::cout << "已拒绝"; break;
        case EventStatus::ERROR:     std::cout << "异常"; break;
    }
    std::cout << std::endl;
}

/**
 * @brief 打印模板信息
 */
static void printTemplate(const TaskTemplate& tmpl) {
    std::cout << "  [模板] ID: " << tmpl.id
              << " | 名称: " << tmpl.name
              << " | 场景: " << tmpl.scenario
              << " | 版本: " << tmpl.version << std::endl;
}

/**
 * @brief 打印计划信息
 */
static void printPlan(const TaskPlan& plan) {
    std::cout << "  [计划] ID: " << plan.id
              << " | 事件: " << plan.eventId
              << " | 模板: " << plan.templateId
              << " | 状态: ";
    switch (plan.status) {
        case PlanStatus::DRAFT:       std::cout << "草稿"; break;
        case PlanStatus::CONFIRMED:   std::cout << "已确认"; break;
        case PlanStatus::DISTRIBUTING: std::cout << "分发中"; break;
        case PlanStatus::EXECUTING:   std::cout << "执行中"; break;
        case PlanStatus::COMPLETED:   std::cout << "已完成"; break;
        case PlanStatus::FAILED:      std::cout << "失败"; break;
        case PlanStatus::CANCELLED:   std::cout << "已取消"; break;
    }
    std::cout << " | 节点数: " << plan.nodes.size() << std::endl;
}

/**
 * @brief 打印分发日志
 */
static void printDistributionLog(const DistributionLog& log) {
    std::cout << "  [分发] 日志ID: " << log.logId
              << " | 目标: " << log.targetAsset
              << " | 重试: " << log.retryCount
              << " | 响应: ";
    switch (log.response) {
        case DistributionResponse::ACK:     std::cout << "确认"; break;
        case DistributionResponse::NACK:    std::cout << "否定"; break;
        case DistributionResponse::TIMEOUT: std::cout << "超时"; break;
        case DistributionResponse::ERROR:   std::cout << "错误"; break;
    }
    std::cout << " | 错误码: " << log.errorCode << std::endl;
}

/**
 * @brief 打印状态日志
 */
static void printStatusLog(const StatusLog& log) {
    std::cout << "  [状态] 资产: " << log.assetId
              << " | 状态码: " << log.statusCode
              << " | 异常: " << (log.isAbnormal ? "是" : "否")
              << " | 详情: " << log.detailInfo << std::endl;
}

/**
 * @brief 分隔线
 */
static void separator() {
    std::cout << "----------------------------------------" << std::endl;
}

/**
 * @brief 主函数
 *
 * 演示完整的业务流程：
 * 1. 初始化系统
 * 2. 接收事件并标准化
 * 3. 加载模板并推荐
 * 4. 生成任务计划
 * 5. 分发方案
 * 6. 监控状态
 */
int main() {
    std::cout << "========================================" << std::endl;
    std::cout << "  战场任务规划管理系统 (BMP) v1.0" << std::endl;
    std::cout << "========================================" << std::endl;

    // 初始化系统
    BattlefieldMissionPlanner bmp;
    if (!bmp.initialize()) {
        std::cerr << "系统初始化失败！" << std::endl;
        return 1;
    }
    std::cout << "系统初始化成功。" << std::endl << std::endl;

    // ============================================================
    // 1. 事件接收与处理
    // ============================================================
    std::cout << "=== 1. 事件接收与处理 ===" << std::endl;

    // 模拟接收JSON格式事件
    std::string eventJson1 = "{ \"type\": \"敌情侦察\", \"priority\": \"HIGH\", "
                             "\"location\": { \"lat\": 39.9, \"lon\": 116.4 }, "
                             "\"description\": \"发现敌方装甲集群正向北移动\" }";
    bool ok = bmp.getEventService().receiveEvent(eventJson1);
    std::cout << "接收事件1: " << (ok ? "成功" : "失败") << std::endl;

    // 模拟接收XML格式事件
    std::string eventXml2 = "<event><type>空情预警</type><priority>CRITICAL</priority>"
                            "<location><lat>31.2</lat><lon>121.5</lon></location>"
                            "<description>探测到不明飞行物接近领空</description></event>";
    ok = bmp.getEventService().receiveEvent(eventXml2);
    std::cout << "接收事件2: " << (ok ? "成功" : "失败") << std::endl;

    // 模拟事件3（用于拒绝场景）
    std::string eventJson3 = "{ \"type\": \"后勤补给\", \"priority\": \"NORMAL\", "
                             "\"description\": \"弹药库存低于阈值，需紧急补给\" }";
    ok = bmp.getEventService().receiveEvent(eventJson3);
    std::cout << "接收事件3: " << (ok ? "成功" : "失败") << std::endl;

    separator();

    // 查询待处理事件
    auto pendingEvents = bmp.getEventService().getPendingEvents();
    std::cout << "待处理事件数量: " << pendingEvents.size() << std::endl;
    for (const auto& evt : pendingEvents) {
        printEvent(evt);
    }

    separator();

    // 标准化处理事件1
    std::cout << "标准化处理事件1..." << std::endl;
    if (!pendingEvents.empty()) {
        bmp.getEventService().processEvent(pendingEvents[0].id);
    }

    // 查询所有事件
    std::cout << "所有事件列表:" << std::endl;
    auto allEvents = bmp.getEventService().queryEvents({});
    for (const auto& evt : allEvents) {
        printEvent(evt);
    }

    std::cout << std::endl;

    // ============================================================
    // 2. 任务模板管理
    // ============================================================
    std::cout << "=== 2. 任务模板管理 ===" << std::endl;
    std::string templateData =
        "{\"id\":\"TMPL-A1\",\"name\":\"敌情侦察模板\",\"scenario\":\"敌情侦察\"}\n"
        "{\"id\":\"TMPL-B2\",\"name\":\"空情预警模板\",\"scenario\":\"空情预警\"}\n"
        "{\"id\":\"TMPL-C3\",\"name\":\"后勤补给模板\",\"scenario\":\"后勤补给\"}";

    size_t templateCount = bmp.getTemplateService().receiveTemplates(templateData);
    std::cout << "加载模板数量: " << templateCount << std::endl;

    auto templates = bmp.getTemplateService().getTemplateList();
    for (const auto& tmpl : templates) {
        printTemplate(tmpl);
    }

    // 自动推荐模板
    std::string recommended = bmp.getTemplateService().recommendTemplate("敌情侦察");
    std::cout << "为'敌情侦察'推荐模板: " << (recommended.empty() ? "无推荐" : recommended) << std::endl;

    recommended = bmp.getTemplateService().recommendTemplate("空情预警");
    std::cout << "为'空情预警'推荐模板: " << (recommended.empty() ? "无推荐" : recommended) << std::endl;

    std::cout << std::endl;

    // ============================================================
    // 3. 任务生成与计划管理
    // ============================================================
    std::cout << "=== 3. 任务生成与计划管理 ===" << std::endl;

    // 基于事件1和推荐模板生成任务
    std::string generatedPlanId = bmp.getPlanService().generateTask(
        pendingEvents[0].id, "TMPL-A1",
        {{"remarks", "优先处理，需快速响应"}});
    std::cout << "生成任务计划: " << (generatedPlanId.empty() ? "失败" : generatedPlanId) << std::endl;

    if (!generatedPlanId.empty()) {
        // 提交计划
        auto submittedPlan = bmp.getPlanService().submitTask(generatedPlanId);
        std::cout << "提交计划后状态: ";
        printPlan(submittedPlan);

        // 计划重配置
        std::cout << "执行计划重配置..." << std::endl;
        std::vector<PlanNode> newNodes;
        PlanNode node1;
        node1.nodeId = "NODE_NEW_001";
        node1.planId = generatedPlanId;
        node1.taskType = "侦察";
        node1.executeUnit = "无人侦察机编队";
        node1.startTime = std::chrono::system_clock::now();
        node1.endTime = std::chrono::system_clock::now() + std::chrono::hours(6);
        node1.status = PlanStatus::DRAFT;
        newNodes.push_back(node1);
        PlanNode node2;
        node2.nodeId = "NODE_NEW_002";
        node2.planId = generatedPlanId;
        node2.parentNodeId = "NODE_NEW_001";
        node2.taskType = "目标确认";
        node2.executeUnit = "情报分析中心";
        node2.startTime = std::chrono::system_clock::now() + std::chrono::hours(6);
        node2.endTime = std::chrono::system_clock::now() + std::chrono::hours(8);
        node2.status = PlanStatus::DRAFT;
        newNodes.push_back(node2);
        bool reconfigured = bmp.getPlanService().reconfigurePlan(generatedPlanId, newNodes);
        std::cout << "重配置: " << (reconfigured ? "成功" : "失败") << std::endl;

        // HITL通知
        bmp.getPlanService().notifyHITL(generatedPlanId, "请确认新侦察方案");
        std::cout << "已发送HITL通知给指挥员。" << std::endl;
    }

    // 查看所有计划
    std::cout << "当前计划列表:" << std::endl;
    auto planList = bmp.getPlanService().getPlanList();
    for (const auto& plan : planList) {
        printPlan(plan);
    }

    std::cout << std::endl;

    // ============================================================
    // 4. 方案分发
    // ============================================================
    std::cout << "=== 4. 方案分发 ===" << std::endl;
    if (!generatedPlanId.empty()) {
        auto distLogs = bmp.getDistributionService().distributePlan(generatedPlanId);
        std::cout << "分发日志数量: " << distLogs.size() << std::endl;
        for (const auto& log : distLogs) {
            printDistributionLog(log);
        }

        // 模拟接收ACK
        if (!distLogs.empty()) {
            bool ackOk = bmp.getDistributionService().receiveAck(
                distLogs[0].logId, DistributionResponse::ACK);
            std::cout << "接收资产确认: " << (ackOk ? "成功" : "失败") << std::endl;

            // 模拟接收NACK
            if (distLogs.size() > 1) {
                bmp.getDistributionService().receiveAck(
                    distLogs[1].logId, DistributionResponse::NACK);
            }
        }

        std::cout << "更新后分发日志:" << std::endl;
        auto updatedLogs = bmp.getDistributionService().getLogsByPlan(generatedPlanId);
        for (const auto& log : updatedLogs) {
            printDistributionLog(log);
        }
    }

    std::cout << std::endl;

    // ============================================================
    // 5. 状态监控
    // ============================================================
    std::cout << "=== 5. 状态监控 ===" << std::endl;

    // 模拟遥测数据（二进制格式）
    std::vector<uint8_t> telemetry1 = {
        0x00, 0x01, 0x00, 0x01,  // 资产ID: AST_65537
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 时间戳占位
        0x23, 0x28,              // 状态码: 9000 (正常)
        0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C               // "Normal"
    };
    auto statusLog1 = bmp.getStatusMonitorService().receiveTelemetry(telemetry1);
    std::cout << "接收遥测数据1:" << std::endl;
    printStatusLog(statusLog1);

    // 模拟异常遥测数据
    std::vector<uint8_t> telemetry2 = {
        0x00, 0x01, 0x00, 0x02,  // 资产ID: AST_65538
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x23, 0x38,              // 状态码: 9016 (异常)
        0x45, 0x72, 0x72, 0x6F, 0x72                    // "Error"
    };
    auto statusLog2 = bmp.getStatusMonitorService().receiveTelemetry(telemetry2);
    std::cout << "接收遥测数据2:" << std::endl;
    printStatusLog(statusLog2);

    // 触发报警
    if (statusLog2.isAbnormal) {
        std::string alarm = bmp.getStatusMonitorService().triggerAlarm(statusLog2);
        std::cout << "报警信息: " << alarm << std::endl;
    }

    // 检查数据陈旧
    std::cout << "检查数据陈旧（阈值100ms）..." << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(150));
    bmp.getStatusMonitorService().checkStaleData(100);
    auto staleStatus = bmp.getStatusMonitorService().getLatestStatus("AST_65537");
    std::cout << "资产 AST_65537 最新状态:" << std::endl;
    printStatusLog(staleStatus);

    std::cout << std::endl;

    // ============================================================
    // 6. 系统运行
    // ============================================================
    std::cout << "=== 6. 系统运行 ===" << std::endl;
    bmp.run();
    std::cout << "系统主循环启动完成（演示模式）。" << std::endl;

    std::cout << std::endl;
    std::cout << "========================================" << std::endl;
    std::cout << "  系统演示结束" << std::endl;
    std::cout << "========================================" << std::endl;

    return 0;
}
