#include "radio_ctrl/uart_handler.h"
#include "radio_ctrl/get_config.h"
#include <iostream>
#include <algorithm>
#include <rclcpp/rclcpp.hpp>
#include "mc/msg/mc_ctrl.hpp"
#include "mc/msg/can_frame.hpp"

constexpr float EPS_GEAR_RATIO = 16.5f;
constexpr float DELTA_T = 0.02f; // 20ms

class SBUSNode : public rclcpp::Node
{
public:
    SBUSNode() : Node("sbus_node"), current_feedback_angle(0.0f)
    {
        if (load_config(config))
        {
            std::cout << "Serial Port: " << config.serial_port << "\n";
            std::cout << "Baudrate: " << config.baudrate << "\n";
            std::cout << "MCU RPM Max: " << config.mcu_rpm_max << "\n";
            std::cout << "EPS Angle Max: " << config.eps_angle_max << "\n";
        }

        // 发布控制指令消息的发布器
        pub_ = this->create_publisher<mc::msg::McCtrl>("mc_ctrl", 10);

        // 订阅CAN反馈的回调函数
        can_sub_ = this->create_subscription<mc::msg::CanFrame>(
            "can_data", 10,
            std::bind(&SBUSNode::can_callback, this, std::placeholders::_1));

        // 初始化串口读取（读取遥控器数据）
        uart_handler_ = std::make_shared<UartHandler>(config.serial_port, config.baudrate);
        if (!uart_handler_->open_serial())
        {
            RCLCPP_ERROR(this->get_logger(), "Failed to open serial port!");
            return;
        }
        uart_handler_->start_reading(); // 启动串口后台读线程

        // 创建周期定时器（每20ms回调一次控制逻辑，50Hz）
        timer_ = this->create_wall_timer(
            std::chrono::milliseconds(20),
            std::bind(&SBUSNode::timer_callback, this));
    }

    ~SBUSNode()
    {
        if (uart_handler_)
        {
            uart_handler_->stop_reading();
        }
    }

private:
    // 定时器回调函数，用于周期性发布控制指令
    void timer_callback()
    {
        static int MCU_RPM_MAX = config.mcu_rpm_max;
        static float EPS_ANGLE_MAX = config.eps_angle_max;

        bool data_safe = uart_handler_->get_data_safe(); // 获取数据安全性

        auto msg = mc::msg::McCtrl(); // 控制消息对象
        uint16_t ch_data[8];          // 各通道遥控数据

        if (data_safe) // 数据安全，进行数据解析并发布
        {
            // 赋值与打印
            for (int i = 0; i < 8; ++i)
            {
                ch_data[i] = uart_handler_->get_channel_value(i);
                // printf("ch[%d]:%d   ", i, ch_data[i]);
            }
            // printf("\n");

            if (ch_data[6] == 192) // 是否使能车辆控制
            {
                msg.mcu_enabled = true;
                msg.brake = 0;
                // 挡位选择
                if (ch_data[7] == 192)
                {
                    msg.gear = 3; // D挡
                }
                else if (ch_data[7] == 1792)
                {
                    msg.gear = 1; // R挡
                }
                else if (ch_data[7] == 992)
                {
                    msg.gear = 2; // N挡
                }
                else
                {
                    msg.gear = 0; // 未知状态
                }

                // 油门 / 刹车逻辑
                if (ch_data[1] >= 1016)
                {
                    msg.brake = 1;
                    msg.brake_time_ms = static_cast<uint16_t>(30000 + (500 - 30000) * (ch_data[1] - 1016) / (1816 - 1016));
                    msg.rpm = 0;
                }
                else
                {
                    msg.brake = 0;
                    msg.brake_time_ms = 500;
                    msg.rpm = static_cast<uint16_t>(MCU_RPM_MAX * (1016 - ch_data[1]) / (1016 - 216));
                }

                // 一键清扫
                if (ch_data[5] == 1792)
                {
                    msg.main_brush_lift = false;
                    msg.edge_brush_lift = false;
                    msg.vacuum = false;
                    msg.spray = false;
                    msg.mud_flap = false;
                    msg.dust_shake = false;
                    msg.main_brush_spin = false;
                    msg.edge_brush_spin = false;
                }
                else if (ch_data[5] == 192)
                {
                    msg.main_brush_lift = true;
                    msg.edge_brush_lift = true;
                    msg.vacuum = true;
                    msg.spray = true;
                    msg.mud_flap = true;
                    msg.dust_shake = false;
                    msg.main_brush_spin = true;
                    msg.edge_brush_spin = true;
                    msg.main_brush_pwm = 100;
                    msg.edge_brush_pwm = 100;
                }

                // 转向逻辑
                float target_angle = (static_cast<float>(ch_data[3]) - 800) / 800 * EPS_ANGLE_MAX;

                // 角速度（度/秒）
                float angle_speed = fabs(target_angle - current_feedback_angle) / DELTA_T;

                // 电机转速（单位：rpm）
                float motor_rpm = angle_speed * EPS_GEAR_RATIO;

                // 限制电机转速到 [120, 1500] 范围，防止过小/过大
                uint16_t can_speed = std::clamp(
                    static_cast<uint16_t>(motor_rpm),
                    static_cast<uint16_t>(120),
                    static_cast<uint16_t>(1500));

                msg.angle = target_angle;
                msg.angle_speed = can_speed;
            }
            else // 未使能状态，发送安全默认控制指令
            {
                msg.mcu_enabled = false;
                msg.brake = 1;
                msg.gear = 0;
                msg.rpm = 0;
                msg.brake_time_ms = 500;
                msg.angle = 0;
                msg.angle_speed = 120;
                msg.main_brush_lift = false;
                msg.edge_brush_lift = false;
                msg.vacuum = false;
                msg.spray = false;
                msg.mud_flap = false;
                msg.dust_shake = false;
                msg.main_brush_spin = false;
                msg.edge_brush_spin = false;
            }

            // 发布控制消息
            pub_->publish(msg);

            RCLCPP_INFO_STREAM(this->get_logger(), "Publishing ControlMsg:"
                                                       << "\n  mcu_enabled: " << msg.mcu_enabled
                                                       << "\n  brake: " << static_cast<int>(msg.brake)
                                                       << "\n  gear: " << static_cast<int>(msg.gear)
                                                       << "\n  rpm: " << msg.rpm
                                                       << "\n  brake_time_ms: " << msg.brake_time_ms
                                                       << "\n  angle: " << msg.angle
                                                       << "\n  angle_speed: " << msg.angle_speed
                                                       << "\n  main_brush_lift: " << msg.main_brush_lift
                                                       << "\n  edge_brush_lift: " << msg.edge_brush_lift
                                                       << "\n  vacuum: " << msg.vacuum
                                                       << "\n  spray: " << msg.spray
                                                       << "\n  mud_flap: " << msg.mud_flap
                                                       << "\n  dust_shake: " << msg.dust_shake
                                                       << "\n  left_light: " << msg.left_light
                                                       << "\n  right_light: " << msg.right_light
                                                       << "\n  night_light: " << msg.night_light
                                                       << "\n  brake_light: " << msg.brake_light
                                                       << "\n  headlight: " << msg.headlight
                                                       << "\n  main_brush_spin: " << msg.main_brush_spin
                                                       << "\n  edge_brush_spin: " << msg.edge_brush_spin
                                                       << "\n  main_brush_pwm: " << static_cast<int>(msg.main_brush_pwm)
                                                       << "\n  edge_brush_pwm: " << static_cast<int>(msg.edge_brush_pwm));
        }
        else
        {
            RCLCPP_INFO(this->get_logger(), "Waiting for remote control data...");
            return; // 下次循环，等待数据安全
        }
    }

    // CAN反馈回调函数（用于获取当前转向角度）
    void can_callback(const mc::msg::CanFrame::SharedPtr msg)
    {
        // 判断是否为转向反馈帧（ID=0x401，且数据长度大于5）
        if (msg->id == 0x401 && msg->dlc >= 5)
        {
            // 第3、4字节拼接为原始角度数据
            uint16_t raw_value = static_cast<uint16_t>((msg->data[3] << 8) | msg->data[4]);

            // 数据偏移：减去1024并除以5，得到角度（单位：度）
            current_feedback_angle = (raw_value - 1024) / 5.0f;
        }
    }

    // ROS2 发布/订阅/定时器/串口读取器
    rclcpp::Publisher<mc::msg::McCtrl>::SharedPtr pub_;
    rclcpp::Subscription<mc::msg::CanFrame>::SharedPtr can_sub_;
    rclcpp::TimerBase::SharedPtr timer_;
    std::shared_ptr<UartHandler> uart_handler_;

    float current_feedback_angle; // 当前反馈角度（从CAN中读取）
    RmoCtlConfig config;
};

int main(int argc, char *argv[])
{
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<SBUSNode>()); // 启动节点
    rclcpp::shutdown();
    return 0;
}