#ifndef APP_HPP
#define APP_HPP

#include <string>
#include <vector>
#include <unordered_map>
#include <cstdint>
#include <chrono>
#include <functional>

/**
 * @brief 核心命名空间，包含战场任务规划管理系统的所有组件。
 */
namespace bmp {

// ============================================================================
// 数据结构定义
// ============================================================================

/**
 * @brief 事件状态枚举
 *
 * @requirement(name="事件接收与处理", id="SU-01")
 * 定义事件从接收到处理完成的生命周期状态。
 */
enum class EventStatus {
    PENDING,      ///< 待处理
    PROCESSING,   ///< 处理中
    ACCEPTED,     ///< 已接受
    REJECTED,     ///< 已拒绝
    ERROR         ///< 处理异常
};

/**
 * @brief 事件优先级枚举
 */
enum class EventPriority {
    LOW = 0,
    NORMAL = 1,
    HIGH = 2,
    CRITICAL = 3
};

/**
 * @brief 任务计划状态枚举
 *
 * @requirement(name="计划管理", id="SU-06")
 * 定义计划从生成到完成的各个阶段状态。
 */
enum class PlanStatus {
    DRAFT,        ///< 草稿
    CONFIRMED,    ///< 已确认
    DISTRIBUTING, ///< 分发中
    EXECUTING,    ///< 执行中
    COMPLETED,    ///< 已完成
    FAILED,       ///< 失败
    CANCELLED     ///< 已取消
};

/**
 * @brief 资产状态枚举
 *
 * @requirement(name="状态监控", id="SU-08")
 * 定义遥测数据中资产运行状态的分类。
 */
enum class AssetStatus {
    ONLINE,       ///< 在线
    OFFLINE,      ///< 离线
    BUSY,         ///< 忙碌
    ERROR,        ///< 故障
    STALE         ///< 数据陈旧
};

/**
 * @brief 分发响应状态枚举
 *
 * @requirement(name="方案分发", id="SU-07")
 * 定义任务分发后的资产响应状态。
 */
enum class DistributionResponse {
    ACK,          ///< 确认收到
    NACK,         ///< 否定确认
    TIMEOUT,      ///< 超时
    ERROR         ///< 协议错误
};

/**
 * @brief 事件数据结构
 *
 * @requirement(name="事件接收与处理", id="SU-01")
 * 表示从上游系统接收的原始事件，经过标准化处理后存储。
 */
struct Event {
    std::string id;                                ///< 事件ID
    std::string type;                              ///< 事件类型
    std::string title;                             ///< 事件标题
    std::string description;                       ///< 事件描述
    double latitude = 0.0;                         ///< 纬度坐标
    double longitude = 0.0;                        ///< 经度坐标
    EventPriority priority = EventPriority::NORMAL; ///< 优先级
    EventStatus status = EventStatus::PENDING;     ///< 当前状态
    std::string rawData;                           ///< 原始JSON/XML数据
    std::string receiveNodeId;                     ///< 接收节点ID
    std::chrono::system_clock::time_point occurTime;   ///< 发生时间
    std::chrono::system_clock::time_point createTime;  ///< 创建时间
};

/**
 * @brief 任务模板数据结构
 *
 * @requirement(name="任务模板管理", id="SU-05")
 * 表示系统从模板服务接收的任务模板，包含版本控制信息。
 */
struct TaskTemplate {
    std::string id;                                ///< 模板ID
    std::string name;                              ///< 模板名称
    std::string scenario;                          ///< 适用场景描述
    std::string content;                           ///< 模板内容（JSON/XML）
    std::string version;                           ///< 版本号
    std::chrono::system_clock::time_point effectiveTime; ///< 生效时间
    std::chrono::system_clock::time_point expireTime;    ///< 过期时间
    std::chrono::system_clock::time_point createTime;    ///< 创建时间
};

/**
 * @brief 任务计划节点数据结构
 *
 * @requirement(name="计划管理", id="SU-06")
 * 表示计划中的单个任务节点，支持树状结构。
 */
struct PlanNode {
    std::string nodeId;                            ///< 节点ID
    std::string planId;                            ///< 所属计划ID
    std::string parentNodeId;                      ///< 父节点ID（空为根节点）
    std::string taskType;                          ///< 任务类型
    std::string executeUnit;                       ///< 执行单位
    std::chrono::system_clock::time_point startTime; ///< 开始时间
    std::chrono::system_clock::time_point endTime;   ///< 结束时间
    PlanStatus status = PlanStatus::DRAFT;         ///< 节点状态
};

/**
 * @brief 任务计划数据结构
 *
 * @requirement(name="计划管理", id="SU-06")
 * 表示一个完整的作战任务计划，关联事件和模板，包含多个计划节点。
 */
struct TaskPlan {
    std::string id;                                ///< 计划ID
    std::string eventId;                           ///< 关联事件ID
    std::string templateId;                        ///< 使用的模板ID
    std::string responsiblePerson;                 ///< 负责人
    std::string remarks;                           ///< 备注
    PlanStatus status = PlanStatus::DRAFT;         ///< 计划状态
    std::chrono::system_clock::time_point generateTime; ///< 生成时间
    std::vector<PlanNode> nodes;                   ///< 计划节点列表
};

/**
 * @brief 分发日志数据结构
 *
 * @requirement(name="方案分发", id="SU-07")
 * 记录每次任务分发操作的详细日志。
 */
struct DistributionLog {
    std::string logId;                             ///< 日志ID
    std::string planId;                            ///< 计划ID
    std::string targetAsset;                       ///< 目标资产标识
    std::chrono::system_clock::time_point sendTime; ///< 发送时间
    DistributionResponse response;                 ///< 响应状态
    int retryCount = 0;                            ///< 重发次数
    std::string errorCode;                         ///< 错误码
};

/**
 * @brief 状态日志数据结构
 *
 * @requirement(name="状态监控", id="SU-08")
 * 记录资产状态遥测数据的日志条目。
 */
struct StatusLog {
    std::string recordId;                          ///< 记录ID
    std::string assetId;                           ///< 资产ID
    std::chrono::system_clock::time_point timestamp; ///< 时间戳
    std::string statusCode;                        ///< 状态码
    std::string detailInfo;                        ///< 详细信息
    bool isAbnormal = false;                       ///< 是否异常
};

/**
 * @brief 用户数据结构
 *
 * @requirement(name="人机交互界面", id="SU-03")
 * 表示系统用户信息，支持RBAC权限模型。
 */
struct User {
    std::string userId;                            ///< 用户ID
    std::string name;                              ///< 姓名
    std::string role;                              ///< 角色
    int permissionLevel = 0;                       ///< 权限等级
    std::string loginAccount;                      ///< 登录账号
    std::string contactInfo;                       ///< 联系方式
};

// ============================================================================
// 核心服务接口
// ============================================================================

/**
 * @brief 事件接收与处理服务
 *
 * @requirement(name="事件接收与处理", id="SU-01")
 * @requirement(name="事件标准化处理", id="SU-02")
 * 负责接收原始事件、校验完整性、标准化并推送至内部消息队列。
 */
class EventService {
public:
    EventService() = default;
    virtual ~EventService() = default;

    /**
     * @requirement(name="事件接收与处理", id="SU-01")
     * 接收原始事件数据（JSON/XML格式），进行完整性校验。
     * @param rawData 原始事件数据字符串
     * @return true 接收成功，false 数据格式无效
     */
    bool receiveEvent(const std::string& rawData);

    /**
     * @requirement(name="事件接收与处理", id="SU-01")
     * 返回接收确认消息。
     * @param eventId 事件ID
     * @return 确认字符串
     */
    std::string sendAck(const std::string& eventId);

    /**
     * @requirement(name="事件标准化处理", id="SU-02")
     * 获取原始事件对象。
     * @param eventId 事件ID
     * @return 事件对象指针，未找到返回nullptr
     */
    const Event* getRawEvent(const std::string& eventId) const;

    /**
     * @requirement(name="事件标准化处理", id="SU-02")
     * 执行事件过滤、字段精简和时间戳坐标转换等标准化处理。
     * @param eventId 事件ID
     * @return true 处理成功，false 处理失败
     */
    bool processEvent(const std::string& eventId);

    /**
     * @requirement(name="事件标准化处理", id="SU-02")
     * 将标准化事件保存至内部存储。
     * @param event 标准化后的事件对象
     */
    void saveStandardEvent(const Event& event);

    /**
     * @requirement(name="事件展示与操作", id="SU-03")
     * 根据查询条件（时间范围、优先级、状态）查询事件列表。
     * @param filters 过滤条件映射
     * @return 匹配的事件列表
     */
    std::vector<Event> queryEvents(const std::unordered_map<std::string, std::string>& filters) const;

    /**
     * @requirement(name="事件展示与操作", id="SU-03")
     * 获取所有待处理事件。
     * @return 待处理事件列表
     */
    std::vector<Event> getPendingEvents() const;

private:
    std::unordered_map<std::string, Event> events_; ///< 内部事件存储
};

/**
 * @brief 任务模板管理服务
 *
 * @requirement(name="任务模板管理", id="SU-05")
 * 管理任务模板的接收、解析、版本比对、存储和推荐。
 */
class TemplateService {
public:
    TemplateService() = default;
    virtual ~TemplateService() = default;

    /**
     * @requirement(name="任务模板管理", id="SU-05")
     * 接收并解析推送的任务模板集合。
     * @param rawData 原始模板数据（JSON/XML）
     * @return 成功解析的模板数量
     */
    size_t receiveTemplates(const std::string& rawData);

    /**
     * @requirement(name="任务模板管理", id="SU-05")
     * 获取所有可用模板列表。
     * @return 模板列表
     */
    std::vector<TaskTemplate> getTemplateList() const;

    /**
     * @requirement(name="任务模板管理", id="SU-05")
     * 用户手动选择指定模板。
     * @param templateId 模板ID
     * @return true 选择成功
     */
    bool selectTemplate(const std::string& templateId);

    /**
     * @requirement(name="任务模板管理", id="SU-05")
     * 基于匹配算法自动推荐最优模板。
     * @param eventType 事件类型
     * @return 推荐的模板ID，无匹配返回空字符串
     */
    std::string recommendTemplate(const std::string& eventType) const;

    /**
     * @requirement(name="任务模板管理", id="SU-05")
     * 获取配置参数映射。
     * @return 配置参数
     */
    std::unordered_map<std::string, std::string> getConfig() const;

private:
    std::unordered_map<std::string, TaskTemplate> templates_; ///< 模板存储
};

/**
 * @brief 任务生成与计划管理服务
 *
 * @requirement(name="任务生成", id="SU-04")
 * @requirement(name="计划管理", id="SU-06")
 * 处理从事件到任务计划的生成、计划列表管理、计划重配置和HITL通知。
 */
class PlanService {
public:
    PlanService() = default;
    virtual ~PlanService() = default;

    /**
     * @requirement(name="任务生成", id="SU-04")
     * 使用指定模板和用户输入参数，为待处理事件生成任务草案。
     * @param eventId 事件ID
     * @param templateId 模板ID
     * @param params 用户输入参数映射
     * @return 生成的任务计划ID，失败返回空字符串
     */
    std::string generateTask(const std::string& eventId,
                             const std::string& templateId,
                             const std::unordered_map<std::string, std::string>& params);

    /**
     * @requirement(name="任务生成", id="SU-04")
     * 提交任务草案。
     * @param planId 计划ID
     * @return 提交后的计划对象
     */
    TaskPlan submitTask(const std::string& planId);

    /**
     * @requirement(name="计划管理", id="SU-06")
     * 获取所有计划的列表。
     * @return 计划列表
     */
    std::vector<TaskPlan> getPlanList() const;

    /**
     * @requirement(name="计划管理", id="SU-06")
     * 基于权重设置对计划列表排序。
     * @param weights 排序权重映射
     */
    void sortPlans(const std::unordered_map<std::string, int>& weights);

    /**
     * @requirement(name="计划管理", id="SU-06")
     * 提交计划重配置请求。
     * @param planId 计划ID
     * @param newNodes 新的节点列表
     * @return true 重配置成功
     */
    bool reconfigurePlan(const std::string& planId, const std::vector<PlanNode>& newNodes);

    /**
     * @requirement(name="计划管理", id="SU-06")
     * 向指挥员发送人机协同（HITL）干预通知。
     * @param planId 计划ID
     * @param message 通知消息
     */
    void notifyHITL(const std::string& planId, const std::string& message);

private:
    std::unordered_map<std::string, TaskPlan> plans_; ///< 计划存储
};

/**
 * @brief 方案分发服务
 *
 * @requirement(name="方案分发", id="SU-07")
 * 负责将最终任务方案下发至作战资产，支持多种通信协议与ACK确认机制。
 */
class DistributionService {
public:
    DistributionService() = default;
    virtual ~DistributionService() = default;

    /**
     * @requirement(name="方案分发", id="SU-07")
     * 启动分发流程，将计划分发至指定资产。
     * @param planId 计划ID
     * @return 分发日志列表
     */
    std::vector<DistributionLog> distributePlan(const std::string& planId);

    /**
     * @requirement(name="方案分发", id="SU-07")
     * 接收资产返回的ACK/NACK响应。
     * @param logId 分发日志ID
     * @param response 响应状态
     * @return true 更新成功
     */
    bool receiveAck(const std::string& logId, DistributionResponse response);

    /**
     * @requirement(name="方案分发", id="SU-07")
     * 更新UI分发状态指示灯。
     * @param planId 计划ID
     */
    void updateStatus(const std::string& planId);

    /**
     * @requirement(name="方案分发", id="SU-07")
     * 查询指定计划的分发日志。
     * @param planId 计划ID
     * @return 分发日志列表
     */
    std::vector<DistributionLog> getLogsByPlan(const std::string& planId) const;

private:
    std::vector<DistributionLog> logs_; ///< 分发日志存储
};

/**
 * @brief 状态监控服务
 *
 * @requirement(name="状态监控", id="SU-08")
 * 实时接收并解析资产遥测数据，监控执行状态，异常时触发报警。
 */
class StatusMonitorService {
public:
    StatusMonitorService() = default;
    virtual ~StatusMonitorService() = default;

    /**
     * @requirement(name="状态监控", id="SU-08")
     * 接收二进制遥测数据。
     * @param rawData 原始遥测数据
     * @return 解析后的状态日志
     */
    StatusLog receiveTelemetry(const std::vector<uint8_t>& rawData);

    /**
     * @requirement(name="状态监控", id="SU-08")
     * 解析遥测数据并提取状态信息。
     * @param rawData 原始二进制数据
     * @return 解析后的状态日志
     */
    StatusLog parseData(const std::vector<uint8_t>& rawData);

    /**
     * @requirement(name="状态监控", id="SU-08")
     * 检测到异常时触发报警。
     * @param statusLog 异常状态日志
     * @return 报警消息
     */
    std::string triggerAlarm(const StatusLog& statusLog);

    /**
     * @requirement(name="状态监控", id="SU-08")
     * 获取指定资产的最新状态。
     * @param assetId 资产ID
     * @return 最新状态日志
     */
    StatusLog getLatestStatus(const std::string& assetId) const;

    /**
     * @requirement(name="状态监控", id="SU-08")
     * 检查并标记数据陈旧状态（超过阈值未更新）。
     * @param thresholdMs 阈值毫秒数
     */
    void checkStaleData(uint64_t thresholdMs);

private:
    std::unordered_map<std::string, StatusLog> latestStatus_; ///< 最新状态缓存
};

// ============================================================================
// 系统外观类
// ============================================================================

/**
 * @brief 战场任务规划管理系统外观类
 *
 * @requirement(name="业务目标", id="REQ-BMP-001")
 * 提供统一入口，协调事件、模板、计划、分发、监控等子系统的交互。
 * 实现从战场事件感知到任务生成、执行监控的闭环管理。
 */
class BattlefieldMissionPlanner {
public:
    /**
     * @brief 构造系统外观类，初始化各子系统服务。
     */
    BattlefieldMissionPlanner();

    /**
     * @brief 初始化系统，加载配置。
     * @return true 初始化成功
     */
    bool initialize();

    /**
     * @brief 运行主循环，处理事件并驱动任务流程。
     */
    void run();

    /**
     * @brief 获取事件服务引用。
     */
    EventService& getEventService() { return eventService_; }

    /**
     * @brief 获取模板服务引用。
     */
    TemplateService& getTemplateService() { return templateService_; }

    /**
     * @brief 获取计划服务引用。
     */
    PlanService& getPlanService() { return planService_; }

    /**
     * @brief 获取分发服务引用。
     */
    DistributionService& getDistributionService() { return distributionService_; }

    /**
     * @brief 获取状态监控服务引用。
     */
    StatusMonitorService& getStatusMonitorService() { return statusMonitorService_; }

private:
    EventService eventService_;               ///< 事件接收与处理服务
    TemplateService templateService_;         ///< 任务模板管理服务
    PlanService planService_;                 ///< 任务生成与计划管理服务
    DistributionService distributionService_; ///< 方案分发服务
    StatusMonitorService statusMonitorService_; ///< 状态监控服务
};

} // namespace bmp

#endif // APP_HPP
