#ifndef RESCUELOAD_H
#define RESCUELOAD_H

#include "qjsonarray.h"
#include "qtmetamacros.h"
#include <QObject>
#include <QString>
#include <QUdpSocket>
#include <QAbstractItemModel>
#include <QMouseEvent>

/**
 * @brief 搜救载荷通信和数据处理
 * 包含数据元素类 ImsiData: 存储搜救信息单元
 * 数据模型类 ImsiTableModel: Imsi的数据容器,向表格和地图提供数据
 * 载荷通信类 RescueLoad: 发送和接收数据
 */

//搜救载荷移动身份识别码数据
class ImsiData
{
public:
    static QHash<QString, QString> operatorMap;
    static QString getOperatorNameByImsi(QString imsi);
public:
    ImsiData(){};
    ImsiData(const QJsonObject& json);
    ImsiData(const ImsiData& from);
    ~ImsiData(){};
public:
    QString imsi;
    QString operatorName;
    QString longitude;
    QString latitude;
    int altitude; // 海拔高度
    QString fcn; // 频点/BAND
    int		rssi; // 强度
    QString createDate;

} /*ImsiData*/;

class ImsiTableModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    enum RoleNames {
        imsiRole = Qt::UserRole,
        latitudeRole = Qt::UserRole+2,
        longitudeRole = Qt::UserRole+3,
        altitudeRole = Qt::UserRole+4,
        dateRole = Qt::UserRole+5,
        rssiRole = Qt::UserRole+6,
        fcnRole = Qt::UserRole+7,
        operatorRole = Qt::UserRole+8,

    };
public:
    explicit ImsiTableModel(QObject *parent = nullptr);
    virtual ~ImsiTableModel();
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    Q_INVOKABLE QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const override;

    void setDataMap(const QHash<QString, ImsiData>& dataMap );
    void updateData(const ImsiData &data);
    QHash<QString, ImsiData>& getDataMap(){
        return m_dataMap;
    }
    QString getSaveDir() {return m_defaultDir;}
    Q_INVOKABLE int getRole(QString);
    void saveDataListToCsv(const QString &filePath, const QString &delimiter = ",");
signals:
    void detailUpdated(QString, double, double);
protected:
    // return the roles mapping to be used by QML
    virtual QHash<int, QByteArray> roleNames()  const override;
private:
    QHash<QString, ImsiData> m_dataMap; // 用于存储数据,不需要排序时用QHash即可
    QList<QString> m_imsiList; // 用于同步TableView的行索引
    QHash<QString, int> m_imsiIndex; // 用于更新数据时获取行索引
    QHash<int, QByteArray> m_roleNames;
    QStringList m_horizontalHeader;
    QString m_defaultDir;
};


class RescueLoad: public QObject
{
    Q_OBJECT

public:
    RescueLoad(QObject *parent);
    ~RescueLoad();


    // udp通信
public:
    void startCommunication(); // 在工作线程中运行
    void sendMessage(const QString &message);
    void sendMessage(const QByteArray &datagram);
    void syncTime();
    void sendNameList(const QString action, const QString type, const QList<QString> &wnamelist, const QList<QString> &bnamelist);

signals:
    void dataUpdate(ImsiData data);
private slots:
    void readData();

public :
    QString remoteIp;
    int remotePort;

private:
    QUdpSocket* udpSocket;
    void handleMessage(const QByteArray &datagram);


};

#endif // RESCUELOAD_H