#ifndef CANCLIENT_H
#define CANCLIENT_H
#include <QThread>
#include <QCanBusDevice>
#include <QCanBus>
#include <QMap>
#include <QList>
#include <QMutex>
#include <QString>
#include <QByteArray>
#include <QTimer>
#include <QtQml/qqml.h>

#include "define.h"

// 响应回调函数类型定义
using CANResponseCallback = std::function<void(const QCanBusFrame& respFrame)>;

typedef struct {
    bool success = false;           // 读取是否成功
    bool leftHasKey = false;        // 左钥匙是否存在
    bool leftCharging = false;      // 左钥匙是否充电中
    bool rightHasKey = false;       // 右钥匙是否存在
    bool rightCharging = false;     // 右钥匙是否充电中
} CANKeyBaseStatus;
Q_DECLARE_METATYPE(CANKeyBaseStatus)

typedef struct {
    bool success = false;           // 读取是否成功
    bool leftLocked = false;        // 左钥匙是否锁住
    bool leftCharging = false;      // 左钥匙是否充电中
    bool rightLocked = false;       // 右钥匙是否锁住
    bool rightCharging = false;     // 右钥匙是否充电中
    bool leftBuckleFault = false;   // 左卡扣故障
    bool rightBuckleFault = false;  // 右卡扣故障
} CANKeyBaseControlStatus;

Q_DECLARE_METATYPE(CANKeyBaseControlStatus)

typedef struct {
    bool success = false;         // 读取是否成功
    QList<int> lockNums;
    QMap<int, bool> lockHasKeyMap;   // 1-5号锁有锁/无锁（索引0=1号锁）
    QMap<int, bool> lockFaultMap; // 锁故障状态（key=锁号）
} CANLockControlStatus;
Q_DECLARE_METATYPE(CANLockControlStatus)

typedef struct {
    int lockNum = 0;              // 锁号1-5
    bool isWorking = false;       // 设置工作状态
    bool isLocked = false;        // 设置锁定状态
} CANSingleLockStatus;
Q_DECLARE_METATYPE(CANSingleLockStatus)

typedef struct {
    bool success = false;
    QList<int> lockNums;
    QMap<int, bool> lockWorkMap;    // 设置工作状态（key=锁号）
    QMap<int, bool> lockLockedMap;  // 设置锁定状态（key=锁号）
} CANLocksControl;

Q_DECLARE_METATYPE(CANLocksControl)

typedef struct {
    bool success = false;               // 读取是否成功
    QString leftKeyRFID;                // 左钥匙卡号
    QString rightKeyRFID;               // 右钥匙卡号
    bool leftKeyReadSuccess = false;    // 左钥匙单独读取成功标记
    bool rightKeyReadSuccess = false;   // 右钥匙单独读取成功标记
} CANKeyRFIDStatus;
Q_DECLARE_METATYPE(CANKeyRFIDStatus)

typedef struct {
    bool success = false;                   // 读取是否成功
    QMap<int, QString> lockRFIDMap;         // 各锁卡号（key=锁号）
    QMap<int, bool> lockReadSuccessMap;     // 各锁读取成功标记（key=锁号）
} CANLockRFIDStatus;
Q_DECLARE_METATYPE(CANLockRFIDStatus)

enum class ChargeState {
    Uncharged = 0,  // 未充电
    Charging = 1,    // 充电中
};

typedef struct {
    bool success = false;         // 读取/写入是否成功

    // 可写控制项（仅充电使能）
    bool leftChargeEnable = false;// 左卡扣充电使能（1=开启，0=关闭）
    bool rightChargeEnable = false;// 右卡扣充电使能

    // 只读状态项（设备反馈）
    bool leftLocked = false;      // 左卡扣上锁状态（1=上锁）
    bool rightLocked = false;     // 右卡扣上锁状态
    bool leftWorking = false;     // 左卡扣工作状态（1=工作中）
    bool rightWorking = false;    // 右卡扣工作状态
    ChargeState leftChargeState = ChargeState::Uncharged; // 左卡扣充电细分状态
    ChargeState rightChargeState = ChargeState::Uncharged; // 右卡扣充电细分状态
} CANKeyBaseChargeStatus;
Q_DECLARE_METATYPE(CANKeyBaseChargeStatus)

typedef struct {
    QMap<QString, quint8> keysMap;
    QMap<QString, quint8> locksMap;
} CANReturnKeyDevices;
Q_DECLARE_METATYPE(CANReturnKeyDevices)

class CANClient : public QThread
{
    Q_OBJECT

    QML_NAMED_ELEMENT(CANClient)

    Q_PROPERTY(bool workingKey READ workingKey WRITE setWorkingKey NOTIFY workingKeyChanged)
    Q_PROPERTY(bool workingLocks READ workingLocks WRITE setWorkingLocks NOTIFY workingLocksChanged)
public:
    explicit CANClient(QObject *parent = nullptr);
    ~CANClient() override; // 补充析构函数，释放资源

    /* 连接或者断开 CAN 设备 */
    void connectDevice();

    /* 获取当前CAN设备连接状态 */
    bool isCanBusConnected() const { return m_canBusStatus; }

    // 异步发送CAN帧，通过回调返回响应
    void sendFrameAsync(const QCanBusFrame& frame, CANResponseCallback callback);

    void testFunc();

    QString getLockRFID(int lockNum);

    bool workingKey() const {
        return m_workingKey;
    }
    void setWorkingKey(bool isWorking) {
        m_workingKey = isWorking;
        emit workingKeyChanged();
    }

    bool workingLocks() const {
        return m_workingLocks;
    }
    void setWorkingLocks(bool isWorking) {
        m_workingLocks = isWorking;
        emit workingLocksChanged();
    }
protected:
    void run() override;
private:
    /* 初始化CAN总线插件列表 */
    void pluginItemInit();

    /* 初始化比特率和CAN设备实例 */
    void bitrateItemInit();
public:
    /* 安全停止线程并释放资源 */
    void stopThreadAndRelease();

    QMap<quint8, CANKeyRFIDStatus> keyRFIDStatus() const {
        return m_keyRFIDStatus;
    }
    QMap<quint8, CANKeyBaseStatus> keyBaseStatus() const {
        return m_keyBaseStatus;
    }
private slots:
    /* 接收CAN总线消息帧 */
    void receivedFrames();

    /* 处理CAN设备错误 */
    void canDeviceErrors(QCanBusDevice::CanBusError error) const;

    void slotUpdateKeyBaseStatus(quint8 nodeId, const CANKeyBaseStatus& status);
    // 根据读取到钥匙的状态(有/无钥匙和是否锁住)更新
    void slotUpdateKeyBaseControl(quint8 nodeId, const CANKeyBaseControlStatus& status);
    // 根据读取到5路锁的状态(有/无锁和是否锁住)更新
    void slotUpdateLockedStatus(quint8 nodeId, const CANLocksControl& status);

    void slotWorkingKeyChanged();
    void slotWorkingLocksChanged();
signals:
    // 设备类型信息读取完成
    void deviceInfoRead(bool success, const quint8& nodeId);
    // 钥匙底座状态读取完成
    void keyBaseStatusRead(quint8 nodeId, const CANKeyBaseStatus& status);
    void keyBaseControlStatusRead(quint8 nodeId, const CANKeyBaseControlStatus& status);
    // 5路锁状态读取完成
    void lockStatusRead(quint8 nodeId, const CANLockControlStatus& lockHasKeyList);
    void lockControlStatusRead(quint8 nodeId, const CANLocksControl& status);
    void lockBuckleWritten(bool success, const QList<QString>& lockNfc);
    // 锁扣控制完成
    void lockBuckleWrite(bool success, int lockNum, bool isLock);
    // 温湿度读取完成
    void temperatureRead(bool success, double leftTemp, double rightTemp);
    void humidityRead(bool success, double humidity);
    // CAN设备连接状态变化
    void signalCanBusStatusChanged(bool isConnected);

    void keyRFIDStatusRead(quint8 nodeId, const CANKeyRFIDStatus& status); // 钥匙RFID读取完成
    void lockRFIDStatusRead(quint8 nodeId, const CANLockRFIDStatus& status); // 锁RFID读取完成
    void singleKeyRFIDRead(bool isLeftKey, bool success, const QString& rfidCard); // 单个钥匙RFID
    void singleLockRFIDRead(int lockNum, bool success, const QString& rfidCard); // 单个锁RFID

    void keyBaseChargeControlWritten(const CANKeyBaseChargeStatus& status);
    void singleKeyBaseChargeControlWritten(bool isLeftKey, bool success,
                                           bool chargeEnable, bool locked,
                                           bool working, ChargeState chargeState);
    void keyBaseChargeStatusRead(const CANKeyBaseChargeStatus& status);

    void workingKeyChanged();
    void workingLocksChanged();
    
    // ========== 归还钥匙和锁检测信号 ==========
    // 当检测到NFC设备插入时发出（用于归还流程）
    void nfcDeviceDetected(const QString& nfcId, const QString& deviceType, int slotIndex);
    void signalLockNfcDeviceDetected(const QString& nfcId);
    // 当检测到设备异常时发出（无法读取NFC）
    void nfcDeviceError(const QString& deviceType, int slotIndex);
    // ==========================================
    
    void signalReturnKey();
    void signalPopDevices(const QString& nfcId, const QString& deviceType, int slotIndex);
private:
    // 处理设备主动上报的插入帧（归还流程）
    void handleDeviceInsertionFrame(const QCanBusFrame& frame);
    
    // 构造SDO读报文
    QCanBusFrame buildReadFrame(quint8 nodeId, quint16 index, quint8 subIndex);

    // 构造SDO写报文
    QCanBusFrame buildWriteFrame(quint8 nodeId, quint16 index, quint8 subIndex, const QByteArray& data, quint8 byteCount = 0);

    // 解析小端数据（16位）
    quint16 parseLittleEndian16(const QByteArray& data);

    // 解析小端数据（32位）
    quint32 parseLittleEndian32(const QByteArray& data);

    // 解析温度数据（有符号16位/10）
    double parseTemperature(const QByteArray& data);

    // 解析湿度数据（无符号16位/10）
    double parseHumidity(const QByteArray& data);

    // 解析RFID卡号（小端4字节）
    QString parseRFIDCard(const QByteArray& data);

    bool verifyNodeID(quint8 deviceNodeId, quint8& returnNodeId);

    ChargeState bitToChargeState(uint8_t bitValue) {
        switch (bitValue) {
            case 0: return ChargeState::Uncharged;
            case 1: return ChargeState::Charging;
            default: return ChargeState::Uncharged;
        }
    }

    QString chargeStateToString(ChargeState state) {
        switch (state) {
            case ChargeState::Uncharged: return "未充电";
            case ChargeState::Charging: return "充电中";
            default: return "未充电";
        }
    }
private:
    // 检查锁扣编号有效性（1-5号）
    bool checkLockNumValid(int lockNum);
    // 检查RGB通道有效性（1-4路）
    bool checkRGBChannelValid(int channel);
    // 检查亮度值有效性（0-100）
    bool checkBrightnessValid(int bright);
    //
    void readDeviceInfoAsync(quint8 nodeId);
    // 电子钥匙底座
    void readKeyBaseStatusAsync();
    void readKeyBaseControlStatusAsync();
    // 5路挂锁底座
    void readLockStatusAsync();
    void readLockControlStatusAsync();
    void writeSingleLockBuckleAsync(const CANSingleLockStatus& status);
    void writeLockBuckleAsync(const CANLocksControl& status);
    // 温湿度
    void readTemperatureAsync();

    // 批量读取：仅左+右钥匙
    void readKeyRFIDStatusAsync();
    // 批量读取：仅1-5号锁
    void readLockRFIDStatusAsync();
    // 单个读取：仅左/右钥匙
    void readSingleKeyRFIDAsync(bool isLeftKey);
    // 单个读取：仅某一个锁
    void readSingleLockRFIDAsync(int lockNum);

    // 左+右卡扣充电使能
    void writeKeyBaseChargeControlAsync(CANKeyBaseChargeStatus& chargeStatus);
    // 读取卡扣当前充电状态
    void readKeyBaseChargeStatusAsync();
public:
    bool openEKey(QString& keyNFC);
    bool unlockEKey();
    bool getLockRfids(int lockCount, QMap<int, QString>& rfids);
    bool unlockLocks(const QList<int>& lockNums);

    bool lockingEKey(quint8 nodeId, bool leftKey, bool rightKey);

    void unlockEKey(const QString& keyNFC);
    void unlockLock(const QString& lockNFC);
public:
    static CANReturnKeyDevices returnDevicesInfo;
private:
    bool m_threadstatus = true;          // 线程运行状态标志
    mutable QMutex m_mutex;              // 线程安全锁（mutable允许const函数修改）
    mutable QMutex m_frameNodeIdMutex;
    QCanBusDevice* m_CanDevice = nullptr;// CAN设备实例
    QStringList m_canBusPlugins;         // CANBus插件列表（修正拼写错误）
    QList<QCanBusDeviceInfo> m_canBusInterfaces; // 可用CAN设备接口列表
    QList<quint32> m_availableFrameId;  // 可用的FrameId列表
    int m_bitrate = CAN_BITERATE_1000000;// 比特率（默认1Mbps）
    bool m_canBusStatus = false;         // CAN设备连接状态
    QString m_pluginsName = "socketcan"; // 默认CAN插件名称（socketcan是Linux下标准插件）
    QString m_canInterfaceName = "can0"; // CAN接口名称（如can0/can1）

    QMap<quint8, quint8> m_deviceOfNodeId;

    // 请求映射：UUID -> 回调函数（用于匹配请求和响应）
    QMap<QString, CANResponseCallback> m_requestMap;
    QMutex m_requestMutex;

    QTimer* m_readControlTimer;
    QTimer* m_readStatusTimer;

    QMutex m_insertDataMutex;

    QMap<quint8, CANKeyBaseStatus> m_keyBaseStatus;
    QMap<quint8, CANKeyBaseControlStatus> m_keyBaseControlStatus;
    QMap<quint8, CANKeyRFIDStatus> m_keyRFIDStatus;

    QMap<quint8, CANLockControlStatus> m_locksControlStatus;
    QMap<quint8, CANLocksControl> m_locksControl;
    QMap<quint8, CANLockRFIDStatus> m_locksRFIDStatus;

    bool m_workingKey = false;        // 标记是否进入业务逻辑
    bool m_workingLocks = false;
};

#endif // CANCLIENT_H
