#ifndef GLOBALS_H
#define GLOBALS_H

#include <QObject>
#include <QVariant>
#include <QMutex>
#include <QGlobalStatic>
#include <QMap>

#include "DataTypeDef.h"

/**
 * @brief 全局变量管理类，提供全局变量的存储、获取和监听功能。
 * 
 * 该类实现了全局变量的存储和管理，支持通过键值对存储和获取数据，并提供了信号机制，当全局变量的值发生变化时，可以发出相应的信号。
 * 
 * 核心功能：
 * - 提供全局变量的存储和获取方法。
 * - 支持通过键值对存储和获取数据。
 * - 支持监听全局变量的变化，通过信号机制通知外部。
 * - 提供静态方法获取类的唯一实例。
 * 
 * 使用示例：
 * @code
 * Globals* globals = Globals::instance();
 * globals->setValue("exampleKey", 42);
 * int value = globals->getValue("exampleKey").toInt();
 * @endcode
 * 
 * 构造函数参数：
 * - parent: QObject的父对象，默认为nullptr。
 * 
 * 注意事项：
 * - 该类是单例模式，通过静态方法instance()获取唯一实例。
 * - 使用setValue方法设置值时，如果键已存在，则更新该键的值；如果键不存在，则创建新的键值对。
 * - 使用getValue方法获取值时，如果键不存在，则返回默认值。
 * - 使用contains方法检查键是否存在。
 * - 使用信号机制监听全局变量的变化，需要连接相应的信号槽。
 * - 使用模板方法setValue和getValue时，需要指定值的类型。
 */
class Globals : public QObject
{
    Q_OBJECT
public:
    /**
     * @brief 获取类的唯一实例。
     * @return Globals类的唯一实例。
     */
    static Globals* instance();

    /**
     * @brief 设置全局变量的值。
     * @param key 键。
     * @param value 值。
     */
    void setValue(const QString& key, const QVariant& value);

    /**
     * @brief 获取全局变量的值。
     * @param key 键。
     * @param defaultValue 默认值，当键不存在时返回。
     * @return 全局变量的值。
     */
    QVariant getValue(const QString& key, const QVariant& defaultValue = QVariant());

    /**
     * @brief 检查全局变量是否存在。
     * @param key 键。
     * @return 如果键存在返回true，否则返回false。
     */
    bool contains(const QString& key) const;

    /**
     * @brief 获取键的索引。
     * @param key 键。
     * @return 键的索引。
     */
    uint8_t getKeyIndex(const QString& key);

    /**
     * @brief 获取全局变量的值，指定值的类型。
     * @tparam T 值的类型。
     * @param key 键。
     * @param defaultValue 默认值，当键不存在时返回。
     * @return 全局变量的值。
     */
    template<typename T>
    T getValue(const QString& key, const T& defaultValue = T());

    /**
     * @brief 设置全局变量的值，指定值的类型。
     * @tparam T 值的类型。
     * @param key 键。
     * @param value 值。
     */
    template<typename T>
    void setValue(const QString& key, const T& value);

private:
    /**
     * @brief 构造函数，私有化以实现单例模式。
     * @param parent QObject的父对象。
     */
    explicit Globals(QObject *parent = nullptr);

    /**
     * @brief 析构函数。
     */
    ~Globals() = default;

    /**
     * @brief 生成信号。
     * @param key 键。
     * @param value 值。
     */
    void signalGeneration(const QString& key, const QVariant& value);

signals:
    /**
     * @brief 当值改变时发出。
     * @param key 键。
     * @param value 值。
     */
    void valueChanged(const QString& key, const QVariant& value);

    // 为各个全局变量添加信号表明，当值发生变化时发出
    void chargeGunBasicValueChanged(const BASIC_INFO& value);
    void chargeInfoValueChanged(const CHARGING_INFO& value);
    void gunErrorValueChanged_1(const UINT32_QSTRING_MAP& value);
    void gunErrorValueChanged_2(const UINT32_QSTRING_MAP& value);
    void gunStateValueChanged_1(const UINT32_QSTRING_MAP& value);
    void gunStateValueChanged_2(const UINT32_QSTRING_MAP& value);
    void gunTypeValueChanged_1(const UINT8_QSTRING_MAP& value);
    void gunTypeValueChanged_2(const UINT8_QSTRING_MAP& value);
    void authListValueChanged(const AUTH_LIST& value);
    void ccuConfigValueChanged(const CCU_CFG& value);
    void chargingProfilesValueChanged(const CHARGING_PROFILES& value);
    void chargingProfilesMapValueChanged(const QVARIANTMAP_INT_MAP& value);
    void ocppConfigKeyValueChanged(const CONFIG_KEY_INFO& value);
    void chargingRecordsValueChanged(const CHARGING_RECORDS_INFO& value);
    void tcuConfigValueChanged(const TCU_CFG& value);
    void pcuConfigValueChanged(const PCU_CFG& value);
    void priceInfoValueChanged(const PRICE_INFO& value);
    void versionValueChanged(const VERSION& value);

private:
    QMap<QString, QVariant> m_values;
    UINT8_QSTRING_MAP m_keys;
    mutable QMutex m_mutex;
};

#define GLOBALS Globals::instance()

#endif // GLOBALS_H
