#include <vector>
#include <cstdint>
#include <cstring>
#include <string>
#include <stdexcept>
#include <algorithm>
#include <cctype>
#include <cstdlib>
#include "client2.h"
// 辅助转换函数
float IntToFloat(int num) {
    return static_cast<float>(num) / 65536.0f;
}

float ShorToFloat100(short num) {
    return static_cast<float>(num) / 100.0f;
}

float ShorToFloat1000(short num) {
    return static_cast<float>(num) / 1000.0f;
}

float ShorToFloat10000(short num) {
    return static_cast<float>(num) / 10000.0f;
}
// 辅助函数：解析MAC地址并填充到缓冲区
void GetMAC(const std::string& strMAC, std::vector<unsigned char>& packet, size_t startIndex) {
    // 移除所有空格和短横线
    std::string cleanedMAC = strMAC;
    cleanedMAC.erase(std::remove(cleanedMAC.begin(), cleanedMAC.end(), ' '), cleanedMAC.end());
    cleanedMAC.erase(std::remove(cleanedMAC.begin(), cleanedMAC.end(), '-'), cleanedMAC.end());

    // 验证长度
    if (cleanedMAC.length() != 12) {
        throw std::invalid_argument("MAC地址长度必须为12个字符");
    }

    try {
        // 解析每两个字符作为十六进制字节
        for (int i = 0; i < 6; i++) {
            // 提取两个字符的子串
            std::string byteStr = cleanedMAC.substr(i * 2, 2);

            // 转换为十六进制字节
            unsigned char byte = static_cast<unsigned char>(
                std::stoi(byteStr, nullptr, 16)
                );

            // 填充到指定位置
            if (startIndex + i < packet.size()) {
                packet[startIndex + i] = byte;
            }
        }

        // 剩余部分填0 (总共需要64字节，但MAC只占6字节)
        for (int i = 6; i < 64; i++) {
            if (startIndex + i < packet.size()) {
                packet[startIndex + i] = 0;
            }
        }
    }
    catch (const std::exception& e) {
        throw std::invalid_argument("无效的MAC地址: " + std::string(e.what()));
    }
}

// CRC计算函数
unsigned char GetCrcSum(const std::vector<unsigned char>& Check, int nOffset, int nLen) {
    unsigned char reg_b = 0x00;
    for (int i = 0; i < nLen; ++i) {
        if (static_cast<size_t>(i + nOffset) >= Check.size()) {
            throw std::out_of_range("Index out of range in GetCrcSum");
        }
        reg_b += Check[i + nOffset];
    }
    return reg_b;
}

// 主函数：组装二进制报文
std::vector<unsigned char> GetMsg(const std::vector<unsigned char>& SrcData, unsigned char nType) {
    // 参数检查
    if (SrcData.empty() ||
        ((nType < 0x01 || nType > 0xA4) && nType != 0xFF)) {
        return {};
    }

    try {
        // 计算总长度：报文头(6) + 额外字段(2) + 功能码(1) + 数据体 + CRC+结束符(2)
        const size_t total_len = 6 + 2 + 1 + SrcData.size() + 2;
        std::vector<unsigned char> msg(total_len);

        // 组装报文头 (6字节)
        msg[0] = 0xEB;  // 报文头
        msg[1] = 0x90;  // 报文头
        msg[2] = 0x00;  // 备用
        msg[3] = 0x00;  // 备用

        // 设置长度字段（数据体长度+功能码）
        uint16_t data_len = static_cast<uint16_t>(SrcData.size() + 1);
        msg[4] = static_cast<unsigned char>(data_len >> 8);   // 长度高字节
        msg[5] = static_cast<unsigned char>(data_len & 0xFF); // 长度低字节

        // 额外字段 (2字节)
        msg[6] = 0x00;  // 备用
        msg[7] = 0xFF;  // 备用

        // 功能码
        msg[8] = nType;

        // 复制数据体
        if (!SrcData.empty()) {
            std::copy(SrcData.begin(), SrcData.end(), msg.begin() + 9);
        }

        // 计算CRC（从索引8开始，长度 = 功能码+数据体）
        unsigned char crc = GetCrcSum(msg, 8, 1 + SrcData.size());
        msg[msg.size() - 2] = crc;
        msg[msg.size() - 1] = 0x16;  // 结束符

        return msg;
    }
    catch (const std::exception& ex) {
        throw std::runtime_error(std::string("Exception in GetMsg: ") + ex.what());
    }
    catch (...) {
        throw std::runtime_error("Unknown exception in GetMsg");
    }
}

// 生成装置云服务登录报文
std::vector<unsigned char> generate_frontlogin_message(const std::string& strMac)
{
    const size_t packetSize = 150; // 报文总长150 数据体+帧序号140
    std::vector<unsigned char> packet(packetSize, 0); // 初始化为全0

    // 协议头
    packet[0] = 0xEB; // 起始标志1
    packet[1] = 0x90;
    packet[2] = 0xEB; // 起始标志2
    packet[3] = 0x90;
    packet[4] = 0x8C; // 数据体长度 (140 = 0x008C)
    packet[5] = 0x00;
    // [6-7] 随机码 (保持为0)
    // [8-9] 功能码 (保持为0)
    // [10-11] 帧序号 (保持为0)
    // 数据体1
    packet[12] = 'F';
    packet[13] = 'T';
    packet[14] = 'I';
    packet[15] = 'D';
    // [16-19] 数据体2 (保持为0)

    // 填充MAC地址 (从位置20开始，64字节)
    GetMAC(strMac, packet, 20);

    // 计算校验和 (从偏移8到137)
    unsigned char checksum = 0;
    for (size_t i = 8; i < packetSize - 2; i++) {
        checksum += packet[i];
    }
    packet[packetSize - 2] = checksum;

    // 结束符
    packet[packetSize - 1] = 0x16;

    return packet;
}

//询问统计数据时间报文
std::vector<unsigned char> generate_statequerytime_message() {
    // 创建2字节数据缓冲区（初始化为0）
    std::vector<unsigned char> DataBuf(2, 0x00);

    // 调用GetMsg生成完整报文
    return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_StatTime));
}

//询问统计数据报文
std::vector<unsigned char> generate_statequerystat_message(tagTime time, uint16_t nDeviceNo, uint16_t nDataType) {
    // 计算总大小：3(备用) + 2(nDeviceNo) + 2(nDataType) + time结构大小
    const size_t totalSize = 3 + 2 * sizeof(uint16_t) + time.GetSize();
    std::vector<unsigned char> DataBuf(totalSize, 0x00); // 初始化为全0

    size_t offset = 0;

    // 1. 跳过3字节备用区（已初始化为0）
    offset += 3;

    // 2. 写入nDeviceNo（网络字节序）
    uint16_t netDeviceNo = htons(nDeviceNo);
    memcpy(DataBuf.data() + offset, &netDeviceNo, sizeof(uint16_t));
    offset += sizeof(uint16_t);

    // 3. 写入nDataType（网络字节序）
    uint16_t netDataType = htons(nDataType);
    memcpy(DataBuf.data() + offset, &netDataType, sizeof(uint16_t));
    offset += sizeof(uint16_t);

    // 4. 写入time结构（内部已处理网络字节序）
    time.GetStructBuf(DataBuf.data(), DataBuf.size(), offset);

    // 生成完整报文
    return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Stat));
}

//询问实时数据报文 测点1-6 数据类型1-11 谐波次数0-2
std::vector<unsigned char> generate_realstat_message(unsigned char nCpuNo,
    unsigned char StaTtype,
    unsigned char flag)
{
    // 计算总大小：3(备用) + 1(nCpuNo) + 1(StaTtype) + 1(固定值) + 1(flag)
    const size_t totalSize = 7;
    std::vector<unsigned char> DataBuf(totalSize, 0x00);  // 初始化为全0

    size_t offset = 0;

    // 1. 跳过3字节备用区（已初始化为0）
    offset += 3;

    // 2. 写入nCpuNo（1字节） 监测点序号 1-6
    memcpy(DataBuf.data() + offset, &nCpuNo, sizeof(unsigned char));
    offset += sizeof(unsigned char);

    // 3. 写入StaTtype（1字节） 数据类型 1-11 一般仅读 1-6
    memcpy(DataBuf.data() + offset, &StaTtype, sizeof(unsigned char));
    offset += sizeof(unsigned char);

    // 4. 写入固定值1（1字节） 3秒实时数据仅有1 表示平均值
    const unsigned char fixedValue = 1;
    memcpy(DataBuf.data() + offset, &fixedValue, sizeof(unsigned char));
    offset += sizeof(unsigned char);

    // 5. 写入flag（1字节） 标志位 0-2 谐波次数 25 50 100次
    memcpy(DataBuf.data() + offset, &flag, sizeof(unsigned char));

    // 生成完整报文
    return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_New_3S));
}

