#include "protocol_struct.hpp"

namespace ProtocolCodec
{

    // BCC 校验
    uint8_t calculate_bcc(const std::vector<uint8_t> &data)
    {
        uint8_t bcc = 0;
        for (uint8_t byte : data)
        {
            bcc ^= byte;
        }
        return bcc;
    }

    // 编码 FullPacket 为字节流（使用大端）
    std::vector<uint8_t> encode_full_packet(const FullPacket &packet)
    {
        std::vector<uint8_t> buf;

        buf.push_back(packet.start_flag1);
        buf.push_back(packet.start_flag2);
        buf.push_back(packet.command_id);
        buf.push_back(packet.response_flag);

        // VIN: 填充至17字节
        std::string vin_padded = packet.vin;
        vin_padded.resize(17, ' ');
        buf.insert(buf.end(), vin_padded.begin(), vin_padded.end());

        buf.push_back(packet.encryption_method);

        // 大端写入 data_length（高字节在前）
        buf.push_back((packet.data_length >> 8) & 0xFF);
        buf.push_back(packet.data_length & 0xFF);

        buf.insert(buf.end(), packet.data_unit.begin(), packet.data_unit.end());

        // BCC 校验（从 command_id 到最后的 data）
        std::vector<uint8_t> bcc_range(buf.begin() + 2, buf.end());
        uint8_t bcc = calculate_bcc(bcc_range);
        buf.push_back(bcc);

        return buf;
    }

    // 解码字节流为 FullPacket（成功返回 packet，否则 std::nullopt）
    std::optional<FullPacket> decode_full_packet(const std::vector<uint8_t> &buffer)
    {
        if (buffer.size() < 24)
        {
            // std::cout << "[decode_full_packet] Buffer too short (<24), size = " << buffer.size() << std::endl;
            return std::nullopt;
        }

        if (!(buffer[0] == 0x23 && buffer[1] == 0x23))
        {
            // std::cout << "[decode_full_packet] Invalid start flag: "
            //           << std::hex << static_cast<int>(buffer[0]) << " "
            //           << static_cast<int>(buffer[1]) << std::dec << std::endl;
            return std::nullopt;
        }

        FullPacket pkt;
        pkt.start_flag1 = buffer[0];
        pkt.start_flag2 = buffer[1];
        pkt.command_id = buffer[2];
        pkt.response_flag = buffer[3];

        pkt.vin = std::string(buffer.begin() + 4, buffer.begin() + 21);
        pkt.encryption_method = buffer[21];

        // 大端读取 data_length（高字节在前）
        pkt.data_length = (buffer[22] << 8) | buffer[23];

        // std::cout << "data_length: " << pkt.data_length << std::endl;
        // std::cout << "expected total len: " << (24 + pkt.data_length + 1)
        //           << ", actual: " << buffer.size() << std::endl;

        size_t expected_len = 24 + pkt.data_length + 1; // header + data + checksum
        if (buffer.size() < expected_len)
        {
            // std::cout << "[decode_full_packet] Incomplete packet, expected = " << expected_len
            //           << ", actual = " << buffer.size() << std::endl;
            return std::nullopt;
        }

        pkt.data_unit.assign(buffer.begin() + 24, buffer.begin() + 24 + pkt.data_length);

        uint8_t expected_bcc = buffer[24 + pkt.data_length];
        std::vector<uint8_t> bcc_range(buffer.begin() + 2, buffer.begin() + 24 + pkt.data_length);
        uint8_t actual_bcc = calculate_bcc(bcc_range);

        if (expected_bcc != actual_bcc)
        {
            // std::cout << "[decode_full_packet] BCC mismatch, expected = "
            //           << (int)expected_bcc << ", actual = " << (int)actual_bcc << std::endl;
            return std::nullopt;
        }

        pkt.checksum = expected_bcc;
        return pkt;
    }

    // 构造心跳包
    FullPacket create_heartbeat_packet(const std::string &vin)
    {
        FullPacket pkt;
        pkt.command_id = 0x07;
        pkt.response_flag = 0xFE;
        pkt.vin = vin;
        pkt.encryption_method = 0x01;
        pkt.data_length = 0;
        pkt.data_unit = {};
        return pkt;
    }

    std::optional<MqttParamSetting> parse_mqtt_param_setting(const std::vector<uint8_t> &data)
    {
        if (data.size() < 9)
        {
            return std::nullopt;
        }

        MqttParamSetting setting;

        // 提取时间戳（6字节），可忽略内容，但结构上要读
        setting.timestamp.year = data[0];
        setting.timestamp.month = data[1];
        setting.timestamp.day = data[2];
        setting.timestamp.hour = data[3];
        setting.timestamp.minute = data[4];
        setting.timestamp.second = data[5];

        setting.sequence = (data[6] << 8) | data[7]; //  流水号
        setting.param_count = data[8];               //  参数个数

        if ((setting.param_count % 2) != 0) // 参数必须成对出现
        {
            return std::nullopt;
        }

        size_t offset = 9;
        for (int i = 0; i < (setting.param_count / 2); ++i)
        {
            if (offset + 2 > data.size())
            {
                return std::nullopt;
            }

            // 长度参数
            MqttParameterItem length_item;
            length_item.param_id = data[offset++];
            uint8_t value_len = data[offset++];
            length_item.value.push_back(value_len); // 只存1字节的长度值
            setting.items.push_back(std::move(length_item));

            // 内容参数
            if (offset + value_len > data.size())
            {
                return std::nullopt;
            }

            MqttParameterItem content_item;
            content_item.param_id = data[offset++];
            content_item.value.insert(content_item.value.end(), data.begin() + offset, data.begin() + offset + value_len);
            offset += value_len;

            setting.items.push_back(std::move(content_item));
        }

        return setting;
    }

    std::optional<VehicleMessage> parse_vehicle_message(const std::vector<uint8_t> &data)
    {
        if (data.size() < 10) // 时间戳6 + 流水号2 + 长度2
        {
            return std::nullopt;
        }

        VehicleMessage msg;

        // 提取时间戳（6字节），可忽略内容，但结构上要读
        msg.timestamp.year = data[0];
        msg.timestamp.month = data[1];
        msg.timestamp.day = data[2];
        msg.timestamp.hour = data[3];
        msg.timestamp.minute = data[4];
        msg.timestamp.second = data[5];

        // 流水号（大端）
        msg.sequence = (data[6] << 8) | data[7];

        // 消息长度（大端）
        msg.message_length = (data[8] << 8) | data[9];

        // 判断是否足够长
        if (data.size() < 10 + msg.message_length)
        {
            return std::nullopt;
        }

        // 提取 JSON 字符串内容
        msg.json_payload = std::string(data.begin() + 10, data.begin() + 10 + msg.message_length);

        return msg;
    }

    // 构造通用应答包（根据 ret 设置应答标志，保留时间戳和流水号）
    std::vector<uint8_t> make_ack_response(const FullPacket &request, bool result)
    {
        FullPacket reply;
        reply.command_id = request.command_id;
        reply.response_flag = result ? 0x01 : 0x02; // 成功 0x01，失败 0x02
        reply.vin = request.vin;
        reply.encryption_method = request.encryption_method;

        // 保留时间戳（6字节）和流水号（2字节），总共 8 字节
        if (request.data_unit.size() >= 8)
        {
            reply.data_unit.assign(request.data_unit.begin(), request.data_unit.begin() + 8);
        }
        else
        {
            reply.data_unit = {}; // 不足 8 字节时，清空
        }

        reply.data_length = reply.data_unit.size();

        return ProtocolCodec::encode_full_packet(reply);
    }

}
