"""
机械臂 Gymnasium 环境的配置类定义。

使用 OmegaConf 的 dataclass 实现类型安全的配置管理。
"""

from dataclasses import dataclass, field
from typing import Optional, Tuple

from omegaconf import MISSING


@dataclass
class PhysicsConfig:
    """物理引擎相关配置"""

    time_step: float = 1.0 / 100.0
    """物理模拟时间步长（秒）"""

    gravity: Tuple[float, float, float] = (0.0, 0.0, -9.8)
    """重力加速度向量 (x, y, z)，单位：m/s²"""

    frame_skip: int = 1
    """每个动作执行多少个物理步骤"""


@dataclass
class RobotConfig:
    """机械臂机器人相关配置"""

    urdf_path: str = "urdfs/simple_arm.urdf"
    """机械臂模型的 URDF 文件路径"""

    anchor_position: Tuple[float, float, float] = (0.0, 0.0, 1.05)
    """机械臂固定的锚点位置（世界坐标系）"""

    use_fixed_base: bool = False
    """是否使用固定基座加载 URDF"""

    joint_indices: Tuple[int, ...] = (0, 1)
    """要控制的关节索引列表"""


@dataclass
class ControlConfig:
    """控制相关配置"""

    max_torque: float = 50.0
    """关节允许的最大扭矩（单位：N·m）"""

    action_low: float = -1.0
    """动作空间下限"""

    action_high: float = 1.0
    """动作空间上限"""


@dataclass
class EpisodeConfig:
    """Episode 相关配置"""

    max_episode_steps: int = 2500
    """一个 episode 的最大步数"""

    initial_joint_noise: float = 0.05
    """重置时关节初始角度的随机噪声范围（弧度）"""

    q0_termination_threshold: Optional[float] = None
    """关节0角度超出此阈值时终止 episode（弧度），为 None 时不限制"""

    q1_termination_threshold: Optional[float] = 100.0
    """关节1角度超出此阈值时终止 episode（弧度），为 None 时不限制"""


@dataclass
class RenderConfig:
    """渲染相关配置"""

    render_modes: list = field(default_factory=list)
    """支持的渲染模式列表"""

    render_fps: int = 100
    """渲染帧率"""


@dataclass
class GymEnvConfig:
    """
    Gymnasium 机械臂环境的完整配置。

    这个配置类封装了所有与环境相关的参数，
    使用 OmegaConf 的 dataclass 实现类型安全和默认值管理。
    """

    physics: PhysicsConfig = field(default_factory=PhysicsConfig)
    """物理引擎配置"""

    robot: RobotConfig = field(default_factory=RobotConfig)
    """机器人配置"""

    control: ControlConfig = field(default_factory=ControlConfig)
    """控制配置"""

    episode: EpisodeConfig = field(default_factory=EpisodeConfig)
    """Episode 配置"""

    render: RenderConfig = field(default_factory=RenderConfig)
    """渲染配置"""
