#include "device/motor_lz.h"
#include "bsp/can.h"
#include "bsp/time.h"
#include "component/kinematics.h"
#include "component/limiter.h"
#include "component/user_math.h"
#include "device/virtual_chassis.h"
#include "module/balance_chassis.h"
#include <math.h>
#include <stddef.h>
#include <string.h>


static Virtual_Chassis_t virtual_chassis;

/**
 * @brief 使能所有电机
 * @param c 底盘结构体指针
 * @return
 */
static int8_t Chassis_MotorEnable(Chassis_t *c) {
  if (c == NULL)
    return CHASSIS_ERR_NULL;
  // for (int i = 0; i < 4; i++) {
  //   // MOTOR_LZ_Enable(&c->param->joint_motors[i]);
  // }
  // for (int i = 0; i < 2; i++) {
  //   MOTOR_LK_MotorOn(&c->param->wheel_motors[i]);
  // }
  return CHASSIS_OK;
}

static int8_t Chassis_MotorRelax(Chassis_t *c) {
  if (c == NULL)
    return CHASSIS_ERR_NULL;
  // for (int i = 0; i < 2; i++) {
  //   // MOTOR_LK_Relax(&c->param->wheel_motors[i]);
  // }
  // for (int i = 0; i < 4; i++) {
  //   MOTOR_LZ_Relax(&c->param->joint_motors[i]);
  // }
  return CHASSIS_OK;
}

static int8_t Chassis_SetMode(Chassis_t *c, Chassis_Mode_t mode) {
  if (c == NULL)
    return CHASSIS_ERR_NULL; /* 主结构体不能为空 */
  if (mode == c->mode)
    return CHASSIS_OK; /* 模式未改变直接返回 */

  Chassis_MotorEnable(c);

  PID_Reset(&c->pid.leg_length[0]);
  PID_Reset(&c->pid.leg_length[1]);
  PID_Reset(&c->pid.yaw);
  PID_Reset(&c->pid.roll);
  PID_Reset(&c->pid.tp[0]);
  PID_Reset(&c->pid.tp[1]);

  c->yaw_control.target_yaw = c->feedback.imu.euler.yaw;

  // 清空位移
  c->chassis_state.position_x = 0.0f;
  c->chassis_state.velocity_x = 0.0f;
  c->chassis_state.last_velocity_x = 0.0f;
  c->chassis_state.target_x = 0.0f;

  LQR_Reset(&c->lqr[0]);
  LQR_Reset(&c->lqr[1]);
  c->mode = mode;
  c->state = 0; // 重置状态，确保每次切换模式时都重新初始化

  return CHASSIS_OK;
}

/* 更新机体状态估计 */
static void Chassis_UpdateChassisState(Chassis_t *c) {
  if (c == NULL)
    return;

  // 从轮子编码器估计机体速度 (参考C++代码)
  float left_wheel_speed_dps = c->feedback.wheel[0].rotor_speed; // dps (度每秒)
  float right_wheel_speed_dps =
      c->feedback.wheel[1].rotor_speed; // dps (度每秒)

  // 将dps转换为rad/s
  float left_wheel_speed = left_wheel_speed_dps * M_PI / 180.0f;   // rad/s
  float right_wheel_speed = right_wheel_speed_dps * M_PI / 180.0f; // rad/s

  float wheel_radius = 0.072f;

  float left_wheel_linear_vel = left_wheel_speed * wheel_radius;
  float right_wheel_linear_vel = right_wheel_speed * wheel_radius;

  // 机体x方向速度 (轮子中心速度)
  c->chassis_state.last_velocity_x = c->chassis_state.velocity_x;
  c->chassis_state.velocity_x =
      (left_wheel_linear_vel + right_wheel_linear_vel) / 2.0f;

  // 积分得到位置
  c->chassis_state.position_x += c->chassis_state.velocity_x * c->dt;
}

int8_t Chassis_Init(Chassis_t *c, Chassis_Params_t *param, float target_freq) {
  if (c == NULL || param == NULL || target_freq <= 0.0f) {
    return -1; // 参数错误
  }
  c->param = param;

  /*初始化can*/
  BSP_CAN_Init();

  /*初始化和注册所有电机*/
  MOTOR_LZ_Init();

  Virtual_Chassis_Init(&virtual_chassis, &c->param->virtual_chassis_param);
  MOTOR_DM_Register(&c->param->yaw_motor);

  /*初始化VMC控制器*/
  VMC_Init(&c->vmc_[0], &param->vmc_param[0], target_freq);
  VMC_Init(&c->vmc_[1], &param->vmc_param[1], target_freq);

  /*初始化pid*/
  PID_Init(&c->pid.leg_length[0], KPID_MODE_CALC_D, target_freq,
           &param->leg_length);
  PID_Init(&c->pid.leg_length[1], KPID_MODE_CALC_D, target_freq,
           &param->leg_length);
  PID_Init(&c->pid.yaw, KPID_MODE_CALC_D, target_freq, &param->yaw);
  PID_Init(&c->pid.roll, KPID_MODE_CALC_D, target_freq, &param->roll);
  PID_Init(&c->pid.tp[0], KPID_MODE_CALC_D, target_freq, &param->tp);
  PID_Init(&c->pid.tp[1], KPID_MODE_CALC_D, target_freq, &param->tp);

  /*初始化LQR控制器*/
  LQR_Init(&c->lqr[0], &param->lqr_gains);
  LQR_Init(&c->lqr[1], &param->lqr_gains);

  /*初始化机体状态*/
  c->chassis_state.position_x = 0.0f;
  c->chassis_state.velocity_x = 0.0f;
  c->chassis_state.last_velocity_x = 0.0f;
  c->chassis_state.target_x = 0.0f;

  /*初始化yaw控制状态*/
  c->yaw_control.target_yaw = 0.0f;
  c->yaw_control.current_yaw = 0.0f;
  c->yaw_control.yaw_force = 0.0f;

  return CHASSIS_OK;
}

int8_t Chassis_UpdateFeedback(Chassis_t *c) {
  if (c == NULL) {
    return -1; // 参数错误
  }
  Virtual_Chassis_Update(&virtual_chassis);
  
  for (int i = 0; i < 4; i++) {
    c->feedback.joint[i] = virtual_chassis.data.joint[i];
    if (c->feedback.joint[i].rotor_abs_angle > M_PI) {
      c->feedback.joint[i].rotor_abs_angle -= M_2PI;
    }
    c->feedback.joint[i].rotor_abs_angle =
        -c->feedback.joint[i].rotor_abs_angle; // 机械零点调整
  }
  for (int i = 0; i < 2; i++) {
    c->feedback.wheel[i] = virtual_chassis.data.wheel[i];
  }
  c->feedback.imu.accl = virtual_chassis.data.imu.accl;
  c->feedback.imu.gyro = virtual_chassis.data.imu.gyro;
  c->feedback.imu.euler = virtual_chassis.data.imu.euler;

  /* 更新云台电机反馈数据（yaw轴） */
  MOTOR_DM_Update(&(c->param->yaw_motor));
  MOTOR_DM_t *dm_motor = MOTOR_DM_GetMotor(&(c->param->yaw_motor));
  if (dm_motor != NULL) {
    c->feedback.yaw = dm_motor->motor.feedback;
  }

  // 更新机体状态估计
  Chassis_UpdateChassisState(c);

  return 0;
}

int8_t Chassis_UpdateIMU(Chassis_t *c, const Chassis_IMU_t imu) {
  if (c == NULL) {
    return -1; // 参数错误
  }
  c->feedback.imu = imu;
  return 0;
}

int8_t Chassis_Control(Chassis_t *c, const Chassis_CMD_t *c_cmd) {
  if (c == NULL || c_cmd == NULL) {
    return CHASSIS_ERR_NULL; // 参数错误
  }
  c->dt = (BSP_TIME_Get_us() - c->lask_wakeup) /
          1000000.0f; /* 计算两次调用的时间间隔，单位秒 */
  c->lask_wakeup = BSP_TIME_Get_us();

  /*设置底盘模式*/
  if (Chassis_SetMode(c, c_cmd->mode) != CHASSIS_OK) {
    return CHASSIS_ERR_MODE; // 设置模式失败
  }

  VMC_ForwardSolve(&c->vmc_[0], c->feedback.joint[0].rotor_abs_angle,
                   c->feedback.joint[1].rotor_abs_angle,
                   c->feedback.imu.euler.pit, c->feedback.imu.gyro.y);
  VMC_ForwardSolve(&c->vmc_[1], c->feedback.joint[3].rotor_abs_angle,
                   c->feedback.joint[2].rotor_abs_angle,
                   c->feedback.imu.euler.pit, c->feedback.imu.gyro.y);

  /*根据底盘模式执行不同的控制逻辑*/
  switch (c->mode) {
  case CHASSIS_MODE_RELAX:
    // 放松模式，电机不输出
    Chassis_MotorRelax(c);

    Chassis_LQRControl(c, c_cmd);

    break;

  case CHASSIS_MODE_RECOVER: {
    float fn;
    fn = -25.0f;

    VMC_InverseSolve(&c->vmc_[0], fn, 0.0f);
    VMC_GetJointTorques(&c->vmc_[0], &c->output.joint[0],
                        &c->output.joint[1]);
    VMC_InverseSolve(&c->vmc_[1], fn, 0.0f);
    VMC_GetJointTorques(&c->vmc_[1], &c->output.joint[3],
                        &c->output.joint[2]);
    // Chassis_MotorEnable(c);
    c->output.wheel[0] = 0.0f;
    c->output.wheel[1] = 0.0f;
    Chassis_Output(c); // 统一输出

  } break;


  case CHASSIS_MODE_WHELL_LEG_BALANCE:
    // 执行LQR控制（包含PID腿长控制）
    Chassis_LQRControl(c, c_cmd);

    Chassis_Output(c); // 统一输出
    break;

  default:
    return CHASSIS_ERR_MODE;
  }

  return CHASSIS_OK;
}

void Chassis_Output(Chassis_t *c) {
  if (c == NULL)
    return;
  // for (int i = 0; i < 4; i++) {
  //   // MOTOR_LZ_MotionParam_t param = {0};
  //   // param.torque = c->output.joint[i];
  //   // MOTOR_LZ_MotionControl(&c->param->joint_motors[i], &param);
  // }
  // BSP_TIME_Delay_us(400); // 等待CAN总线空闲，确保前面的命令发送完成
  // for (int i = 0; i < 2; i++) {
  //   MOTOR_LK_SetOutput(&c->param->wheel_motors[i], c->output.wheel[i]);
  //   // MOTOR_LK_SetOutput(&c->param->wheel_motors[i], 0.0f);
  // }
}

int8_t Chassis_LQRControl(Chassis_t *c, const Chassis_CMD_t *c_cmd) {
  if (c == NULL || c_cmd == NULL) {
    return CHASSIS_ERR_NULL;
  }


  /* 运动参数（参考C++版本的状态估计） */
  static float xhat = 0.0f, x_dot_hat = 0.0f;
  float target_dot_x = 0.0f;

  // 简化的速度估计（后续可以改进为C++版本的复杂滤波）
  x_dot_hat = c->chassis_state.velocity_x;
  xhat = c->chassis_state.position_x;

  // 目标设定
  target_dot_x = c_cmd->move_vec.vx * 2;
  // target_dot_x = SpeedLimit_TargetSpeed(300.0f, c->chassis_state.velocity_x,
  // target_dot_x, c->dt); // 速度限制器，假设最大加速度为1 m/s²
  c->chassis_state.target_x += target_dot_x * c->dt;

  /* 分别计算左右腿的LQR控制 */
    /* 构建当前状态 */
    LQR_State_t current_state = {0};
    current_state.theta = c->vmc_[0].leg.theta;
    current_state.d_theta = c->vmc_[0].leg.d_theta;
    current_state.x = xhat;
    current_state.d_x = x_dot_hat;
    current_state.phi = -c->feedback.imu.euler.pit;
    current_state.d_phi = -c->feedback.imu.gyro.y;

    LQR_UpdateState(&c->lqr[0], &current_state);

    current_state.theta = c->vmc_[1].leg.theta;
    current_state.d_theta = c->vmc_[1].leg.d_theta;
    LQR_UpdateState(&c->lqr[1], &current_state);

    /* 根据当前腿长更新增益矩阵 */
    LQR_CalculateGainMatrix(&c->lqr[0], c->vmc_[0].leg.L0);
    LQR_CalculateGainMatrix(&c->lqr[1], c->vmc_[1].leg.L0);

    /* 构建目标状态 */
    LQR_State_t target_state = {0};
    target_state.theta = 0.0f;   // 目标摆杆角度
    target_state.d_theta = 0.0f; // 目标摆杆角速度
    target_state.phi = -0.1f;  // 目标俯仰角
    target_state.d_phi = 0.0f; // 目标俯仰角速度
    target_state.x = c->chassis_state.target_x; // 目标位置
    target_state.d_x = target_dot_x;            // 目标速度
    
    /* 更新LQR状态 */
    LQR_SetTargetState(&c->lqr[0], &target_state);
    LQR_SetTargetState(&c->lqr[1], &target_state);
     
    LQR_Control(&c->lqr[0]);
    LQR_Control(&c->lqr[1]);



  c->yaw_control.current_yaw = c->feedback.yaw.rotor_abs_angle;
  c->yaw_control.target_yaw = c->param->mech_zero_yaw;
  c->yaw_control.yaw_force = PID_Calc(&c->pid.yaw, c->yaw_control.target_yaw,
               c->feedback.yaw.rotor_abs_angle, 0.0f, c->dt);

  /* 轮毂力矩输出（参考C++版本的减速比） */
  c->output.wheel[0] = c->lqr[0].control_output.T / 4.5f + c->yaw_control.yaw_force;
  c->output.wheel[1] = c->lqr[1].control_output.T / 4.5f - c->yaw_control.yaw_force;
  /* 腿长控制和VMC逆解算（使用PID控制） */
  float virtual_force[2];
  float target_L0[2];
  float leg_d_length[2]; // 腿长变化率

  /* 横滚角PID补偿计算 */
  // 使用PID控制器计算横滚角补偿力，目标横滚角为0
  float roll_compensation_force = PID_Calc(&c->pid.roll, 0.0f, 
                                           c->feedback.imu.euler.rol, 
                                           c->feedback.imu.gyro.x, 
                                           c->dt);
  
  // 限制补偿力范围，防止过度补偿
  if (roll_compensation_force > 20.0f) roll_compensation_force = 20.0f;
  if (roll_compensation_force < -20.0f) roll_compensation_force = -20.0f;
  
  // 目标腿长设定（移除横滚角补偿）
  target_L0[0] = 0.15f + c_cmd->height * 0.2f; // 左腿：基础腿长 + 高度调节
  target_L0[1] = 0.15f + c_cmd->height * 0.2f; // 右腿：基础腿长 + 高度调节

  // 获取腿长变化率
  VMC_GetVirtualLegState(&c->vmc_[0], NULL, NULL, &leg_d_length[0], NULL);
  VMC_GetVirtualLegState(&c->vmc_[1], NULL, NULL, &leg_d_length[1], NULL);

  /* 左右腿摆角相互补偿（参考C++版本的Delta_Tp机制） */
  float Delta_Tp[2];
  // 使用tp_pid进行左右腿摆角同步控制
  // 左腿补偿力矩：使左腿theta向右腿theta靠拢
  Delta_Tp[0] = c->vmc_[0].leg.L0 * 10.0f *
                PID_Calc(&c->pid.tp[0], c->vmc_[1].leg.theta, c->vmc_[0].leg.theta,
                         c->vmc_[0].leg.d_theta, c->dt);
  // 右腿补偿力矩：使右腿theta向左腿theta靠拢（符号相反）
  Delta_Tp[1] = -Delta_Tp[0];

  
  // 左腿控制
  {
    // 使用PID进行腿长控制
    float pid_output = PID_Calc(&c->pid.leg_length[0], target_L0[0],
                                c->vmc_[0].leg.L0, leg_d_length[0], c->dt);

    // 腿长控制力 = LQR摆杆力矩的径向分量 + PID腿长控制输出 + 基础支撑力 - 横滚角补偿力（左腿减少支撑力）
    virtual_force[0] = (c->lqr[0].control_output.Tp) * sinf(c->vmc_[0].leg.theta) + pid_output + 50.0f - roll_compensation_force;

    // VMC逆解算（包含摆角补偿）
    if (VMC_InverseSolve(&c->vmc_[0], virtual_force[0],
                         c->lqr[0].control_output.Tp + Delta_Tp[0]) == 0) {
      VMC_GetJointTorques(&c->vmc_[0], &c->output.joint[0],
                          &c->output.joint[1]);
    } else {
      // VMC失败，设为0力矩
      c->output.joint[0]= 0.0f;
      c->output.joint[1]= 0.0f;
    }
  }

  // 右腿控制
  {
    // 使用PID进行腿长控制
    float pid_output = PID_Calc(&c->pid.leg_length[1], target_L0[1],
                                c->vmc_[1].leg.L0, leg_d_length[1], c->dt);

    // 腿长控制力 = LQR摆杆力矩的径向分量 + PID腿长控制输出 + 基础支撑力 + 横滚角补偿力（右腿增加支撑力）
    virtual_force[1] = (c->lqr[1].control_output.Tp) * sinf(c->vmc_[1].leg.theta) + pid_output + 50.0f + roll_compensation_force;

    // VMC逆解算（包含摆角补偿）
    if (VMC_InverseSolve(&c->vmc_[1], virtual_force[1],
                         c->lqr[1].control_output.Tp + Delta_Tp[1]) == 0) {
      VMC_GetJointTorques(&c->vmc_[1], &c->output.joint[3],
                          &c->output.joint[2]);
    } else {
      // VMC失败，设为0力矩
      c->output.joint[2] = 0.0f;
      c->output.joint[3] = 0.0f;
    }
  }

  /* 安全限制 */
  for (int i = 0; i < 2; i++) {
    if (fabsf(c->output.wheel[i]) > 0.8f) {
      c->output.wheel[i] = (c->output.wheel[i] > 0) ? 0.8f : -0.8f;
    }
  }

  for (int i = 0; i < 4; i++) {
    if (fabsf(c->output.joint[i]) > 20.0f) {
      c->output.joint[i] =
          (c->output.joint[i] > 0) ? 20.0f : -20.0f;
    }
  }

  return CHASSIS_OK;
}
