#pragma once

#include <vector>

#include "calibration_vehicle_profile_interfaces/msg/calibration_ability_type.hpp"
#include "calibration_workshop_orchestration_interfaces/msg/workshop_session_config.hpp"
#include "workshop_orchestrator_v2/types.hpp"

namespace workshop_orchestrator_v2
{

using WorkshopSessionConfig = calibration_workshop_orchestration_interfaces::msg::WorkshopSessionConfig;
using RequestedCalibrationTask = calibration_workshop_orchestration_interfaces::msg::RequestedCalibrationTask;

// PlanBuilder 负责根据车辆画像和会话配置，生成这次标定任务应该执行的阶段列表。
// 默认顺序：外部真值校核 → 底盘标定 → 运控标定 → 传感器内参 → 传感器外参 → 手眼标定。
// 如果 config.requested_tasks 非空，则只生成用户显式启用的阶段。
class PlanBuilder
{
public:
  // 根据车辆画像和会话配置生成阶段列表。
  std::vector<StagePlan> build_minimal_plan(
    const VehicleProfile & profile,
    const WorkshopSessionConfig & config) const;

private:
  // 判断 profile.capabilities 中某个 ability_type 是否 supported。
  bool has_capability(
    const VehicleProfile & profile,
    uint8_t ability_type) const;

  // 在 requested_tasks 中查找某个 stage_type 对应的配置。
  // 找到返回指针，没找到返回 nullptr。
  const RequestedCalibrationTask * find_requested_task(
    const WorkshopSessionConfig & config,
    uint8_t stage_type) const;

  // 在 requested_tasks 中查找某个 task_code 对应的配置。
  const RequestedCalibrationTask * find_requested_task_by_code(
    const WorkshopSessionConfig & config,
    const std::string & task_code) const;

  // 判断某个阶段是否应该加入计划。
  // 综合考虑 requested_tasks 过滤和 capabilities 支持。
  bool should_include_stage(
    const VehicleProfile & profile,
    const WorkshopSessionConfig & config,
    uint8_t stage_type,
    uint8_t ability_type) const;

  // 各阶段的构造方法。
  StagePlan make_external_reference_stage(
    int order_index,
    const VehicleProfile & profile,
    const RequestedCalibrationTask * task_cfg) const;
  StagePlan make_chassis_stage(
    int order_index,
    const VehicleProfile & profile,
    const RequestedCalibrationTask * task_cfg) const;
  StagePlan make_control_stage(
    int order_index,
    const VehicleProfile & profile,
    const RequestedCalibrationTask * task_cfg) const;
  StagePlan make_sensor_intrinsic_stage(
    int order_index,
    const VehicleProfile & profile,
    const RequestedCalibrationTask * task_cfg) const;
  StagePlan make_sensor_extrinsic_stage(
    int order_index,
    const VehicleProfile & profile,
    const RequestedCalibrationTask * task_cfg) const;
  StagePlan make_hand_eye_stage(
    int order_index,
    const VehicleProfile & profile,
    const RequestedCalibrationTask * task_cfg) const;
  StagePlan make_stage_for_task(
    int order_index,
    const VehicleProfile & profile,
    const RequestedCalibrationTask & task) const;

  // 把 RequestedCalibrationTask 中的策略和配置应用到 StagePlan 上。
  void apply_task_config(StagePlan & stage, const RequestedCalibrationTask * task_cfg) const;
  void apply_task_identity(StagePlan & stage, const RequestedCalibrationTask & task) const;
  std::string make_task_suffix(const std::string & task_code) const;
};

}  // namespace workshop_orchestrator_v2
