#pragma once

#include "rm_control/common/result.h"
#include "rm_control/common/robot_types.h"

#include <string>
#include <vector>

namespace rm_control::config {

// JSON 支持的动作类型。
// 这里把“只读命令”和“运动命令”放在同一个枚举里，执行器可以集中做安全校验。
enum class CommandType {
    GetRobotInfo,
    GetCurrentArmState,
    GetForceData,
    SleepMs,
    MoveJ,
    MoveJDelta,
    MoveJDeltaSteps,
    MoveL,
};

// 单条运动命令的通用选项，对应 RM_API2 moveJ/moveL 的速度、平滑半径、
// 轨迹连接和阻塞执行参数。
struct MotionOptions {
    int speed_percent = 5;
    int blend_radius = 0;
    int trajectory_connect = 0;
    bool blocking = true;
};

// JSON 中的一条命令被解析后的结构体。
// 不同命令只使用其中一部分字段，例如 movej 使用 joints_deg，
// movej_delta_steps 使用 joint_delta_deg + steps。
struct ArmCommand {
    std::string name;
    CommandType type = CommandType::GetRobotInfo;
    std::vector<float> joints_deg;
    std::vector<float> joint_delta_deg;
    common::Pose pose;
    int duration_ms = 0;
    int steps = 1;
    int step_sleep_ms = 0;
    MotionOptions motion;
};

// 全局安全限制。默认 dry_run=true 且 allow_motion=false，
// 是为了避免首次运行 JSON 文件时误发真实运动指令。
struct SafetyOptions {
    bool dry_run = true;
    bool allow_motion = false;
    int max_speed_percent = 20;
    float max_joint_delta_deg = 5.0F;
    float max_cartesian_step_m = 0.02F;
    float max_euler_delta_rad = 0.2F;
};

// 一个完整 JSON 指令文件：连接参数 + 安全策略 + 命令列表。
struct JsonCommandProgram {
    common::RobotConnectionConfig connection;
    SafetyOptions safety;
    std::vector<ArmCommand> commands;
};

// 从字符串或文件加载 JSON 指令，并完成字段类型校验和默认值填充。
common::Result<JsonCommandProgram> parseCommandProgramText(const std::string &text);
common::Result<JsonCommandProgram> loadCommandProgramFromFile(const std::string &path);

const char *commandTypeName(CommandType type);

} // namespace rm_control::config
