#pragma once

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

#include <cstddef>
#include <vector>

namespace rm_control::modules::trajectory {

/**
 * @brief RM75 拖动示教轨迹的关节运动安全上限。
 *
 * @reason 将可调安全限制作为显式输入，使校验算法不读取配置文件且能够在 Mock 测试中复现。
 *
 * @author 唐永康
 * @date 2026-07-10
 *
 * @safety 三项限制都必须是有限正数；单位分别为 degree、degree/second 和 degree/second^2。
 * @note 这些限制用于离线轨迹校验，不会改变机械臂控制器内部限制。
 */
struct DragTrajectoryValidationLimits {
    double maximum_joint_jump_deg = 5.0;
    double maximum_joint_velocity_deg_per_second = 30.0;
    double maximum_joint_acceleration_deg_per_second_squared = 100.0;
};

/**
 * @brief 通过校验的 RM75 拖动示教轨迹统计报告。
 *
 * @reason 在允许回放前保留计算得到的峰值和位置，便于 manifest、审计日志和回放报告复用。
 *
 * @author 唐永康
 * @date 2026-07-10
 *
 * @safety 报告仅在 `ValidateDragTrajectory` 成功时有效，关节索引使用 0..6。
 * @note 时间单位为 millisecond，运动指标单位与 `DragTrajectoryValidationLimits` 一致。
 */
struct DragTrajectoryValidationReport {
    std::size_t sample_count = 0;
    long long duration_ms = 0;
    double observed_maximum_joint_jump_deg = 0.0;
    double observed_maximum_joint_velocity_deg_per_second = 0.0;
    double observed_maximum_joint_acceleration_deg_per_second_squared = 0.0;
    std::size_t maximum_jump_sample_index = 0;
    std::size_t maximum_jump_joint_index = 0;
    std::size_t maximum_velocity_sample_index = 0;
    std::size_t maximum_velocity_joint_index = 0;
    std::size_t maximum_acceleration_sample_index = 0;
    std::size_t maximum_acceleration_joint_index = 0;
};

/**
 * @brief 校验 RM75 七关节拖动示教轨迹并计算运动峰值。
 *
 * @reason 在进入 DryRun 或硬件回放前一次性拒绝空轨迹、维度错误、非法浮点数、时间倒退及
 *         超出跃变、速度或加速度限制的轨迹，避免播放线程中临时发现结构性错误。
 *
 * @author 唐永康
 * @date 2026-07-10
 *
 * @param samples 已全部载入内存的轨迹点；关节角单位为 degree，时间为单调 elapsed millisecond。
 * @param limits 关节跃变、速度和加速度的有限正数上限。
 * @return 轨迹完全合规时返回峰值报告；任一输入或安全限制非法时返回带样本和关节上下文的失败。
 *
 * @calls 仅调用标准数学函数和本模块内部纯算法函数。
 * @safety 本函数不连接设备、不触发运动；失败结果不得被转换为可回放状态。
 * @note 相邻区间速度按各自时间差计算，加速度按两个区间中点之间的时间差计算。
 */
common::Result<DragTrajectoryValidationReport> ValidateDragTrajectory(
    const std::vector<common::TrajectorySample> &samples,
    const DragTrajectoryValidationLimits &limits);

} // namespace rm_control::modules::trajectory
