#pragma once

#include <chrono>        // 用来取当前时间，给创建时间、更新时间、报告时间戳赋值。
#include <string>        // 保存字符串字段，比如 session_id、summary。
#include <vector>        // 保存步骤列表、步骤执行结果列表。

#include "calibration_common_interfaces/msg/error_code.hpp"                         // 通用错误码，比如 OK、INVALID_ARGUMENT。
#include "calibration_common_interfaces/msg/job_state.hpp"                          // 通用任务状态，比如 RUNNING、SUCCEEDED。
#include "calibration_vehicle_profile_interfaces/msg/calibration_module_type.hpp"   // 模块类型，比如 external_localization。
#include "calibration_vehicle_profile_interfaces/msg/vehicle_profile.hpp"           // 车辆画像，告诉主控这台车是什么配置。
#include "calibration_vehicle_profile_interfaces/msg/workflow_stage_type.hpp"       // 步骤类型，比如 external_reference。
#include "calibration_workshop_orchestration_interfaces/msg/stage_plan.hpp"         // 单个步骤计划：这一步做什么、找谁执行。
#include "calibration_workshop_orchestration_interfaces/msg/stage_result_summary.hpp" // 单个步骤结果：这一步是否成功。
#include "calibration_workshop_orchestration_interfaces/msg/workshop_precheck_response.hpp" // 开跑前检查结果。
#include "calibration_workshop_orchestration_interfaces/msg/workshop_report.hpp"    // 最终报告：整场跑完后返回给外部。
#include "calibration_workshop_orchestration_interfaces/msg/workshop_session.hpp"   // 一次完整标定任务的主对象。
#include "calibration_workshop_orchestration_interfaces/msg/workshop_session_state.hpp" // 这次标定当前跑到哪一步了。

namespace workshop_orchestrator_v2
{

// 起短名字只是为了后面少写长命名空间。
using ErrorCode = calibration_common_interfaces::msg::ErrorCode;
using JobState = calibration_common_interfaces::msg::JobState;
using CalibrationModuleType = calibration_vehicle_profile_interfaces::msg::CalibrationModuleType;
using VehicleProfile = calibration_vehicle_profile_interfaces::msg::VehicleProfile;
using WorkflowStageType = calibration_vehicle_profile_interfaces::msg::WorkflowStageType;
using ApprovalState = calibration_workshop_orchestration_interfaces::msg::ApprovalState;
using ManualActionType = calibration_workshop_orchestration_interfaces::msg::ManualActionType;
using StagePlan = calibration_workshop_orchestration_interfaces::msg::StagePlan;
using StageResultSummary = calibration_workshop_orchestration_interfaces::msg::StageResultSummary;
using WorkshopPrecheckResponse = calibration_workshop_orchestration_interfaces::msg::WorkshopPrecheckResponse;
using WorkshopReport = calibration_workshop_orchestration_interfaces::msg::WorkshopReport;
using WorkshopSession = calibration_workshop_orchestration_interfaces::msg::WorkshopSession;
using WorkshopSessionState = calibration_workshop_orchestration_interfaces::msg::WorkshopSessionState;

// 返回当前时间的“微秒”整数。
// 这里统一用微秒，是为了直接写入项目里现成的 *_timestamp_us 字段。
inline int64_t now_us()
{
  return std::chrono::duration_cast<std::chrono::microseconds>(
           std::chrono::system_clock::now().time_since_epoch())
    .count();
}

// 把一个状态值包成 WorkshopSessionState 消息。
inline WorkshopSessionState make_session_state(uint8_t value)
{
  WorkshopSessionState state;
  state.value = value;
  return state;
}

// 把步骤类型值包成消息。
inline calibration_vehicle_profile_interfaces::msg::WorkflowStageType make_stage_type(uint8_t value)
{
  calibration_vehicle_profile_interfaces::msg::WorkflowStageType stage_type;
  stage_type.value = value;
  return stage_type;
}

// 把模块类型值包成消息。
inline calibration_vehicle_profile_interfaces::msg::CalibrationModuleType make_module_type(uint8_t value)
{
  calibration_vehicle_profile_interfaces::msg::CalibrationModuleType module_type;
  module_type.value = value;
  return module_type;
}

// 把任务状态值包成消息。
inline JobState make_job_state(uint8_t value)
{
  JobState state;
  state.state = value;
  return state;
}

// 把错误码值包成消息。
inline ErrorCode make_error_code(uint16_t value)
{
  ErrorCode code;
  code.code = value;
  return code;
}

namespace metadata_keys
{
// common template identity
inline constexpr const char * TASK_CODE = "task_code";
inline constexpr const char * TARGET_ID = "target_id";

// chassis
inline constexpr const char * CHASSIS_PRIMITIVE_TYPE = "primitive_type";
inline constexpr const char * CHASSIS_STRAIGHT_LINE_DISTANCE_M = "straight_line.target_distance_m";
inline constexpr const char * CHASSIS_STRAIGHT_LINE_SPEED_MS = "straight_line.target_speed_ms";
inline constexpr const char * CHASSIS_STRAIGHT_LINE_REVERSE = "straight_line.reverse";
inline constexpr const char * CHASSIS_ARC_SPEED_MS = "arc.target_speed_ms";
inline constexpr const char * CHASSIS_ARC_RADIUS_M = "arc.radius_m";
inline constexpr const char * CHASSIS_ARC_SWEEP_ANGLE_DEG = "arc.sweep_angle_deg";
inline constexpr const char * CHASSIS_ARC_CLOCKWISE = "arc.clockwise";
inline constexpr const char * CHASSIS_ROTATION_TARGET_YAW_DEG = "in_place_rotation.target_yaw_deg";
inline constexpr const char * CHASSIS_ROTATION_TARGET_ANGULAR_VEL_DEG_S = "in_place_rotation.target_angular_vel_deg_s";
inline constexpr const char * CHASSIS_STEERING_SWEEP_TARGET_ANGLE_DEG = "steering_sweep.target_angle_deg";
inline constexpr const char * CHASSIS_STEERING_SWEEP_AMPLITUDE_DEG = "steering_sweep.sweep_amplitude_deg";
inline constexpr const char * CHASSIS_STEERING_SWEEP_FREQUENCY_HZ = "steering_sweep.sweep_frequency_hz";
inline constexpr const char * CHASSIS_STEERING_SWEEP_DURATION_SEC = "steering_sweep.duration_sec";
inline constexpr const char * CHASSIS_LATERAL_SPEED_MS = "lateral_translation.target_speed_ms";
inline constexpr const char * CHASSIS_LATERAL_DISTANCE_M = "lateral_translation.target_distance_m";
inline constexpr const char * CHASSIS_LATERAL_MOVE_LEFT = "lateral_translation.move_left";
inline constexpr const char * CHASSIS_DIAGONAL_SPEED_MS = "diagonal_motion.target_speed_ms";
inline constexpr const char * CHASSIS_DIAGONAL_DISTANCE_M = "diagonal_motion.target_distance_m";
inline constexpr const char * CHASSIS_DIAGONAL_HEADING_DEG = "diagonal_motion.heading_deg";
inline constexpr const char * CHASSIS_MODULE_ALIGNMENT_IDS = "module_alignment.module_ids";
inline constexpr const char * CHASSIS_MODULE_ALIGNMENT_ZERO_DEG = "module_alignment.target_zero_deg";
inline constexpr const char * CHASSIS_MODULE_ALIGNMENT_TOLERANCE_DEG = "module_alignment.tolerance_deg";
inline constexpr const char * CHASSIS_COORDINATED_STEERING_IDS = "coordinated_steering.module_ids";
inline constexpr const char * CHASSIS_COORDINATED_STEERING_TARGET_ANGLE_DEG = "coordinated_steering.target_angle_deg";
inline constexpr const char * CHASSIS_COORDINATED_STEERING_HOLD_TIME_SEC = "coordinated_steering.hold_time_sec";
inline constexpr const char * COMMON_BRAKE_WHEN_FINISHED = "brake_when_finished";
inline constexpr const char * COMMON_TIMEOUT_SEC = "timeout_sec";

// control
inline constexpr const char * CONTROL_TASK_TYPE = "control.task_type";
inline constexpr const char * CONTROL_TRAJECTORY_PREFIX = "traj_pt_";
inline constexpr const char * CONTROL_STOP_AT_END = "control.stop_at_end";
inline constexpr const char * CONTROL_TIMEOUT_SEC = "control.timeout_sec";
inline constexpr const char * CONTROL_VELOCITY_STEP_TARGET_VELOCITY_MS = "velocity_step.target_velocity_ms";
inline constexpr const char * CONTROL_VELOCITY_STEP_HOLD_TIME_SEC = "velocity_step.hold_time_sec";
inline constexpr const char * CONTROL_VELOCITY_STEP_SETTLE_BEFORE_STEP_SEC = "velocity_step.settle_before_step_sec";
inline constexpr const char * CONTROL_ACCEL_DECEL_START_VELOCITY_MS = "accel_decel.start_velocity_ms";
inline constexpr const char * CONTROL_ACCEL_DECEL_TARGET_VELOCITY_MS = "accel_decel.target_velocity_ms";
inline constexpr const char * CONTROL_ACCEL_DECEL_TARGET_ACCEL_MS2 = "accel_decel.target_accel_ms2";
inline constexpr const char * CONTROL_ACCEL_DECEL_HOLD_TIME_SEC = "accel_decel.hold_time_sec";
inline constexpr const char * CONTROL_STOP_ACCURACY_X_M = "stop_accuracy.target_stop_x_m";
inline constexpr const char * CONTROL_STOP_ACCURACY_Y_M = "stop_accuracy.target_stop_y_m";
inline constexpr const char * CONTROL_STOP_ACCURACY_YAW_RAD = "stop_accuracy.target_stop_yaw_rad";

// sensor
inline constexpr const char * SENSOR_ID = "sensor.sensor_id";
inline constexpr const char * SENSOR_TASK_SUBTYPE = "sensor.task_subtype";
inline constexpr const char * CAMERA_INTRINSIC_REQUIRED_IMAGE_COUNT = "camera_intrinsic.required_image_count";
inline constexpr const char * CAMERA_INTRINSIC_TARGET_BOARD_ID = "camera_intrinsic.target_board_id";
inline constexpr const char * CAMERA_INTRINSIC_TIMEOUT_SEC = "camera_intrinsic.timeout_sec";
inline constexpr const char * IMU_INTRINSIC_REQUIRED_STATIC_SEGMENT_COUNT = "imu_intrinsic.required_static_segment_count";
inline constexpr const char * IMU_INTRINSIC_REQUIRED_MOTION_SEGMENT_COUNT = "imu_intrinsic.required_motion_segment_count";
inline constexpr const char * IMU_INTRINSIC_TIMEOUT_SEC = "imu_intrinsic.timeout_sec";
inline constexpr const char * SENSOR_EXTRINSIC_BASE_FRAME_ID = "sensor_extrinsic.base_frame_id";
inline constexpr const char * SENSOR_EXTRINSIC_REQUIRED_SAMPLE_COUNT = "sensor_extrinsic.required_sample_count";
inline constexpr const char * SENSOR_EXTRINSIC_TIMEOUT_SEC = "sensor_extrinsic.timeout_sec";
inline constexpr const char * HAND_EYE_ARM_ID = "hand_eye.arm_id";
inline constexpr const char * HAND_EYE_REQUIRED_POSE_COUNT = "hand_eye.required_pose_count";
inline constexpr const char * HAND_EYE_TIMEOUT_SEC = "hand_eye.timeout_sec";

// external
inline constexpr const char * EXTERNAL_STATIC_SAMPLE_COUNT = "external.static_sample_count";
inline constexpr const char * EXTERNAL_DYNAMIC_SAMPLE_COUNT = "external.dynamic_sample_count";
inline constexpr const char * EXTERNAL_REQUIRE_SHORT_MOTION_SEGMENT = "external.require_short_motion_segment";
inline constexpr const char * EXTERNAL_MAX_POSITION_STDDEV_M = "external.max_position_stddev_m";
inline constexpr const char * EXTERNAL_MAX_YAW_STDDEV_RAD = "external.max_yaw_stddev_rad";
inline constexpr const char * EXTERNAL_MAX_TRACKING_LOSS_RATIO = "external.max_tracking_loss_ratio";
inline constexpr const char * EXTERNAL_MAX_TIME_SYNC_OFFSET_MS = "external.max_time_sync_offset_ms";
inline constexpr const char * EXTERNAL_TIMEOUT_SEC = "external.timeout_sec";
}  // namespace metadata_keys

// SessionRecord 是主控在内存里保存的一条“这台车这次标定任务记录”。
struct SessionRecord
{
  WorkshopSession session;                  // 这次标定任务本体：ID、状态、车辆画像、步骤计划都在这里。
  WorkshopPrecheckResponse last_precheck;   // 最近一次开跑前检查结果；外部想知道“为什么没开跑”时会看它。
  WorkshopReport report;                    // 这次标定最终产出的报告；跑完或失败后会写这里。
  std::vector<StageResultSummary> stage_results; // 每一步执行完后的结果列表；最终报告会直接用它拼出来。
  std::string waiting_stage_id;             // 当前卡在哪个阶段的人工门控上。
  bool manual_action_pending{false};         // 当前是否在等人工动作完成。
  bool manual_action_confirmed{false};       // 人工动作是否已经确认完成。
  bool approval_pending{false};              // 当前是否在等阶段结果审批。
  bool approval_decided{false};              // 审批是否已经给出结论。
  bool approval_approved{false};             // 审批是否通过。
  bool report_ready{false};                 // 报告是否已经生成好；没生成好之前，get_report 不能返回有效报告。
  bool executing{false};                    // 是否有后台线程正在执行这条任务；防止同一 session 被并发执行。
};

}  // namespace workshop_orchestrator_v2
