#ifndef M4255NFCHELPER_H
#define M4255NFCHELPER_H

#include "RS485Controller.h"
#include <QObject>

class M4255NFCHelper : public QObject
{
    Q_OBJECT
public:
    static M4255NFCHelper* instance();
    explicit M4255NFCHelper(QObject *parent = nullptr);
    ~M4255NFCHelper();

public:
    void closePort();

    int init(const QString& portName);
    int readCardId(QByteArray& cardType, QByteArray& cardID);
    int readDataBlock(const uint8_t& useKeyB, const uint8_t blockId, QByteArray& buff);
    int fillDataBlock(const uint8_t& useKeyB, const uint8_t blockId, const QByteArray& data);
    int fillPIN(const QByteArray& data);
    int fillORG(const QByteArray& data);
    int fillPINBlock(const uint8_t& useKeyB, const uint8_t& block_id, const QByteArray& keyA, const QByteArray &keyB);
    int initPrepaidIC(const uint8_t& useKeyB, const uint8_t& blockId, const uint32_t& value);
    int subPrepaidIC(const uint8_t& useKeyB, const uint8_t& blockId, const uint32_t& value);
    int addPrepaidIC(const uint8_t& useKeyB, const uint8_t& blockId, const uint32_t& value);
    int readPrepaidIC(const uint8_t& useKeyB, const uint8_t& blockId, uint32_t& value);
    int setBeep(const uint8_t& on);
    int forceBeep(const uint8_t& on);
    int setWorkMode(const uint8_t& mode);
    int setReadOnce(const uint8_t& type);
    int waitReadCardId(QByteArray& cardId, int timeout = 3000);

private:
    uint8_t checkSum(const QByteArray& data, int len);
    bool openPort(const QString& portName = "/dev/ttys2",
                  qint32 baudRate = QSerialPort::Baud9600,
                  QSerialPort::DataBits dataBits = QSerialPort::Data8,
                  QSerialPort::Parity parity = QSerialPort::NoParity,
                  QSerialPort::StopBits stopBits = QSerialPort::OneStop,
                  QSerialPort::FlowControl flowControl = QSerialPort::NoFlowControl);

    int parseCardIdRecvData(const QByteArray& data, QByteArray& cardType, QByteArray& cardID);
    int parseReadDataBlockRecvData(const QByteArray& data, QByteArray& buff);
    int parseFillDataBlockRecvData(const QByteArray& data);
    int parseFillPinRecvData(const QByteArray& data);
    int parseFillOrgRecvData(const QByteArray& data);
    int parseFillPinBlockRecvData(const QByteArray& data);
    int parseInitPrepaidICRecvData(const QByteArray& data);
    int parseSubPrepaidICRecvData(const QByteArray& data);
    int parseAddPrepaidICRecvData(const QByteArray& data);
    int parseReadPrepaidICRecvData(const QByteArray& data, uint32_t &value);
    int parseSetBeepRecvData(const QByteArray& data);
    int parseForceBeepRecvData(const QByteArray& data);
    int parseSetWorkModeRecvData(const QByteArray& data);
    int parseSetReadOnceRecvData(const QByteArray& data);

    int generalRecvData(const QByteArray& data);

private slots:
    void parseResponseReceived(const QByteArray& data);
    void parseReceiveData(const QByteArray& data);
    void parseErrorOccurred(const QString& errorString);

signals:
    void signalWaitReadCardId();

private:
    RS485Controller *m_controller;
    QByteArray m_recvData;
};



#define NFCReader M4255NFCHelper::instance()

#endif // M4255NFCHELPER_H
