#ifndef BLUETOOTHCLIENT_H
#define BLUETOOTHCLIENT_H
#include <QThread>
#include <QBluetoothDeviceDiscoveryAgent>
#include <QLowEnergyController>
#include <QLowEnergyService>
#include <QBluetoothUuid>
#include <QBluetoothServiceInfo>
#include <QByteArray>
#include <QMap>
#include <QTimer>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QCryptographicHash>
#include <QDateTime>
#include <QMutex>

// ========== 协议常量定义 ==========
#define BLE_SERVICE_UUID 0xFEE7                  // 服务UUID
#define BLE_CHAR_INDICATE_UUID 0xFED1            // 通知特征值UUID（设备→APP）
#define BLE_CHAR_WRITE_UUID 0xFED2               // 写特征值UUID（APP→设备）
#define AES_KEY_SIZE 16                          // AES-128密钥长度
#define BLE_FRAME_MINI_LEN 8                   // 最小8字节
#define BLE_RETRY_COUNT 3                       // 指令重传次数
#define BLE_RETRY_DELAY 1000                     // 重传延迟（ms）
#define BLE_MULTIPACK_DELAY 500                  // 多包传输间隔（ms）

// ========== 指令INS定义 ==========
enum BLE_INS {
    INS_GET_TOKEN = 0x01,                        // 获取令牌
    INS_SEND_CMD = 0x02,                         // 指令下发
    INS_UPLOAD_DATA = 0x03,                      // 数据上传
    INS_FILE_TRANS = 0x06,                       // 文件传输
    INS_GET_FIRMWARE = 0xEE                      // 获取固件版本
};

// ========== 数据上传子指令定义 ==========
enum BLE_UPLOAD_SUB_CMD {
    UPLOAD_DEVICE_STATUS = 0x01,                 // 获取设备状态
    UPLOAD_WORK_TICKET = 0x02,                   // 获取工作票完成情况
    UPLOAD_BATTERY = 0x03,                       // 获取钥匙电量
    UPLOAD_RFID = 0x04,                          // 获取RFID号
    UPLOAD_CHARGE_PARAM = 0x05                   // 获取充电参数
};

// ========== 指令下发子指令定义 ==========
enum BLE_SEND_SUB_CMD {
    SEND_MODE_SWITCH = 0x01,                     // 模式切换
    SEND_WORK_TICKET = 0x02,                     // 工作票下发
    SEND_FINGERPRINT = 0x03,                     // 指纹特征值下发
    SEND_CHARGE_PARAM = 0x04,                    // 充电参数设置
    SEND_DISCONNECT = 0xEA,                      // 蓝牙断开
    SEND_SHUTDOWN = 0xEE                         // 设备关机
};

// ========== 结构体定义（协议数据封装） ==========
// 令牌结构体
struct BLEToken {
    bool success = false;
    QByteArray token; // 4字节令牌
};
Q_DECLARE_METATYPE(BLEToken)

// 设备基础信息结构体
struct BLEDeviceInfo {
    QString deviceName = "keyLock";
    QString macAddress;
    quint8 deviceType = 0x01;
    QString firmwareVersion; // 固件版本（如V1.0.6）
};
Q_DECLARE_METATYPE(BLEDeviceInfo)

// 设备状态结构体
struct BLEDeviceStatus {
    bool success = false;
    enum Status { WORK_MODE = 0x01, STANDBY_MODE = 0x02, FAULT_MODE = 0x03 } status;
    QString statusDesc;
};
Q_DECLARE_METATYPE(BLEDeviceStatus)

// 充电参数结构体
struct BLEChargeParam {
    bool success = false;
    quint8 startPercent = 0; // 充电开启百分比
    quint8 stopPercent = 0;  // 充电终止百分比
    enum ChargeState { UNCHARGED = 0x01, CHARGING = 0x02, FULL = 0x03 } chargeState;
    QString chargeStateDesc;
};
Q_DECLARE_METATYPE(BLEChargeParam)

// RFID信息结构体
struct BLERFIDInfo {
    bool success = false;
    QList<QString> rfidList; // 读取到的RFID号列表
};
Q_DECLARE_METATYPE(BLERFIDInfo)

// 工作票结构体
struct BLERWorkTicket {
    bool success = false;
    QJsonDocument ticketDoc;
};
Q_DECLARE_METATYPE(BLERWorkTicket)

// 工作票完成情况结构体
struct BLERWorkTicketResult {
    bool success = false;
    QJsonDocument resultDoc;
};
Q_DECLARE_METATYPE(BLERWorkTicketResult)

// 多包接收状态（仅追踪当前正在接收的多包任务，协议同一时间仅一个多包任务）
struct MultiPackRecvState {
    quint16 currentIdx;
    quint16 totalPack;          // 从上行返回解析的总包数（TOTAL）
    quint16 receivedCount;      // 已接收且校验通过的包数
    QMap<quint16, QByteArray> packCache; // 缓存（key=IDX，value=DATA）
    bool isCompleted;           // 是否接收完成
    QTimer timeoutTimer;        // 超时定时器（5秒未收包则重置）
};

// 工作票下发多包发送状态（跟踪每包发送进度、响应、超时）
struct WorkTicketSendState {
    quint16 totalPack;          // 总包数
    quint16 currentIdx;          // 当前发送包索引
    QList<QByteArray> packList;  // 所有分包数据（含协议头：TOTAL+IDX+CRC+SIZE+DATA）
    bool isCompleted;           // 是否发送完成
    QTimer packTimeoutTimer;    // 单包超时定时器（5秒）
    int retryCount;             // 当前包重试次数
};

class BLEClient : public QThread
{
    Q_OBJECT
public:
    explicit BLEClient(QObject *parent = nullptr);
    ~BLEClient();

    // 启动蓝牙搜索
    void startDeviceDiscovery();
    // 停止蓝牙搜索
    void stopDeviceDiscovery();

    // 连接蓝牙设备（通过MAC地址）
    void connectDevice(const QString& macAddress, const QString& name);

    // 断开蓝牙连接
    void disconnectDevice();

    void testFunc();

    /* 安全停止线程并释放资源 */
    void stopThreadAndRelease();

    void sendJobTicket(const QJsonDocument& doc);
    void startGetWorkTicketResult();

    bool isConnected();

    void apiConnectDevice(const QString& macAddress);
protected:
    void run() override;
signals:
    // 蓝牙连接状态信号
    void connectStateChanged(QLowEnergyController::ControllerState state, const QString& msg);

    // 发现新BLE设备
    void deviceFound(const QString &name, const QString &mac);
    // 搜索错误
    void discoveryError(const QString &msg);
    // 搜索状态变化
    void discoveryStateChanged(bool isSearching);

    void tokenReceived(const BLEToken& token);
    void deviceStatusReceived(const BLEDeviceStatus& status);
    void batteryStatusReceived(quint8 battery, const BLEChargeParam& chargeState);
    void rfidReceived(const BLERFIDInfo& rfidInfo);
    void chargeParamReceived(const BLEChargeParam& param);
    void workTicketResultReceived(const BLERWorkTicketResult& result);
    void firmwareVersionReceived(const QString& softVersion, const QString& hardVersion);
    void cmdSendResult(bool success, const QString& cmdName, const QString& msg);
signals:
    void signalSendJobTicketStatus(bool success);
    void signalFailConnect();
private slots:
    // 蓝牙扫描结果
    void onDeviceDiscovered(const QBluetoothDeviceInfo& device);
    // 搜索错误回调
    void onDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error error);
    // 扫描完成
    void onDiscoveryFinished();
    // 连接状态变化（QLowEnergyController）
    void onControllerStateChanged(QLowEnergyController::ControllerState state);
    // 服务发现完成
    void onServiceDiscovered(const QBluetoothUuid& uuid);
    // 服务状态变化（特征值发现用）
    void onServiceStateChanged(QLowEnergyService::ServiceState state);
    // 收到设备通知数据
    void onCharacteristicChanged(const QLowEnergyCharacteristic& chara, const QByteArray& data);
    // 写特征值完成
    void onWriteCharacteristicFinished(const QLowEnergyCharacteristic& chara, const QByteArray& newValue);
private:
    // 构建下行指令帧
    QByteArray buildDownFrame(quint8 ins, const QByteArray& data, const QByteArray& token);
    // 解析上行指令帧
    bool parseUpFrame(const QByteArray& cipherData, quint8& ins, QByteArray& data, QByteArray& token);
    // 计算CRC16/MODBUS
    quint16 calculateCRC16(const QByteArray& data);
    // 发送指令（带重传机制）
    void sendCmdWithRetry(const QByteArray& frame, const QString& cmdName, int retryCount = BLE_RETRY_COUNT);
    void sendOnce(const QString& cmdName, int retryCount);
    // 多包数据分割
    QList<QByteArray> splitMultiPackData(const QByteArray& data, int packSize = 128);
    // 解析上行返回的多包字段（从dataField中提取TOTAL/IDX/CRC/SIZE/DATA）
    bool parseMultiPackField(const QByteArray& dataField, quint16& total, quint16& idx, quint16& crc, quint16& size, QByteArray& data);
    // 多包数据拼接（所有包接收完成后调用）
    QByteArray mergeMultiPackData();
    // 重置多包接收状态
    void resetMultiPackRecvState();

    bool parseWorkTicketSendResp(const QByteArray& dataField, quint16& respIdx, quint16& respTotal, quint8& respRes);
    void resetWorkTicketSendState();

    // 获取令牌
    void getToken();
    // 设备模式切换（工作/待机）
    void switchDeviceMode(bool isWorkMode);
    // 下发工作票
    void sendWorkTicket(const BLERWorkTicket& workTicket);
    void sendNextWorkTicketPack();
    // 设置充电参数
    void setChargeParam(quint8 startPercent, quint8 stopPercent);
    // 断开蓝牙指令
    void sendDisconnectCmd();
    // 设备关机/重启
    void sendShutdownCmd(bool isShutdown = true);
    // 获取设备状态
    void getDeviceStatus();
    // 获取工作票完成情况
    void getWorkTicketOtherData();
    void getWorkTicketResult();
    // 获取电量状态
    void getBatteryStatus();
    // 获取RFID号
    void getRFID();
    // 获取充电参数
    void getChargeParam();
    // 获取固件版本
    void getFirmwareVersion();

    // 字节数组转16进制字符串
    QString byteArrayToHex(const QByteArray& data);
    // 16进制字符串转字节数组
    QByteArray hexToByteArray(const QString& hexStr);
    // 获取当前UNIX时间戳（4字节小端）
    QByteArray getCurrentUnixTime();
    // 小端字节数组转16位整数
    quint16 littleEndianToUInt16(const QByteArray& data);
    // 小端字节数组转32位整数
    quint32 littleEndianToUInt32(const QByteArray& data);
    // 16位整数转小端字节数组
    QByteArray uint16ToLittleEndian(quint16 value);
    // 32位整数转小端字节数组
    QByteArray uint32ToLittleEndian(quint32 value);
public:
    QString m_selectedMAC;      // 选定的钥匙MAC地址
    bool m_isSearching = false; // 标记是否正在搜索
private:
    bool m_threadstatus = true;

    QBluetoothDeviceDiscoveryAgent* m_discoveryAgent = nullptr;
    QLowEnergyController* m_leController = nullptr;
    QLowEnergyService* m_targetService = nullptr;    // 目标服务（FEE7）
    QLowEnergyCharacteristic m_indicateChar;         // 通知特征值（FED1）
    QLowEnergyCharacteristic m_writeChar;            // 写特征值（FED2）

    QByteArray m_aesKey;          // AES密钥
    QByteArray m_token;           // 令牌（4字节）
    QString m_targetMac;          // 目标设备MAC地址
    QMutex m_mutex;               // 线程安全锁

//    QList<QByteArray> m_multiPackList; // 多包数据列表
//    int m_currentPackIdx = 0;          // 当前发送包索引
//    quint8 m_multiPackSubCmd = 0;       // 多包传输子指令
//    QTimer m_multiPackTimer;            // 多包传输定时器

    // 多包接收状态（全局唯一，同一时间仅处理一个多包任务）
    MultiPackRecvState m_multiPackRecvState;
    QMutex m_multiPackRecvMutex;

    WorkTicketSendState m_workTicketSendState; // 工作票下发多包状态
    QMutex m_workTicketSendMutex;              // 下发状态线程安全锁

    QMap<QString, int> m_cmdRetryCount; // 当前指令的重试次数
    QMap<QString, bool> m_cmdSendSuccess; //发送成功标记
    QMutex m_retryMutex;
    QMap<QString, QTimer*> m_cmdRetryTimers;  // 指令名-专属重传Timer
    QMap<QString, QByteArray> m_cmdFrameCache;// 指令名-待发送的帧数据

    QList<QString> m_filterDevice;  // 过滤设备
    QTimer* m_stateMonitorTimer;
};

#endif // BLUETOOTHCLIENT_H
