#ifndef CONFIGMANAGER_H
#define CONFIGMANAGER_H

#include <QObject>
#include <QMap>
#include <QSettings>
#include <QJsonObject>
#include <QFileSystemWatcher>

#include "DataTypeDef.h"

/**
 * @class ConfigManager
 * @brief ConfigManager 类用于管理配置文件，并提供加载和保存配置文件的功能。
 * 
 * ConfigManager 类继承自 QObject，用于管理各种配置文件，如 CCU 配置文件、TCU 配置文件、价格信息文件等。
 * 它提供了一系列静态方法和实例方法，用于加载和保存配置文件，并提供了获取和设置配置信息的功能。
 * 
 * 核心功能包括：
 * - 加载和保存各种配置文件
 * - 获取和设置配置信息
 * - 监控配置文件的变化
 * 
 * 使用示例：
 * @code
 * ConfigManager* manager = ConfigManager::instance();
 * manager->loadCcuConfigFile("path/to/ccu/config/file");
 * uint8_t result = manager->saveConfig(setting_index_enum::Language, QVariant(1));
 * @endcode
 * 
 * 构造函数参数：
 * - parent: QObject 的父对象，默认为 nullptr
 * 
 * 注意事项：
 * - 请确保在使用 ConfigManager 之前已经正确初始化了应用程序。
 * - 在使用 ConfigManager 时，请确保配置文件的路径是正确的。
 * - 保存配置时，请确保提供正确的配置类型和数据。
 */
class ConfigManager : public QObject
{
    Q_OBJECT
public:
    static ConfigManager* instance();

    explicit ConfigManager(QObject *parent = nullptr);

public:
    // load config file
    uint8_t loadCcuConfigFile(const QString& path);
    uint8_t loadTcuConfigFile(const QString& path);
    uint8_t loadPcuConfigFile(const QString& path);
    uint8_t loadPriceInfoFile(const QString& path);
    uint8_t loadAuthorizationList(const QString& path);
    uint8_t loadChargingProfiles(const QString& path);
    uint8_t loadConfigKey(const QString& path);
    uint8_t loadOffileChargingRecords(const QString& path);
    uint8_t loadErrorCodeNote(const QString& path);

    // save config file
    bool saveConfig(const setting_index_enum& type, const QVariant& data);

    tcp_server_cfg_info_t getTcpServerCfg();

    int getLanguage();
    void setLanguage(int language);

    admin_cfg_info_t getAdminConfig();
    void setAdminConfig(const admin_cfg_info_t& admin_cfg);

    tcu_config_info_t tcu_cfg() const;

    ccu_config_info_t ccu_cfg() const;

    CHARGING_RECORDS_INFO charging_records() const;

    CHARGING_PROFILES charging_profiles() const;

    AUTH_LIST auth_list() const;

    config_key_info_t cfg_key() const;

    PCU_CFG pcu_cfg() const;

    PRICE_INFO price_info() const;

    QVARIANTMAP_INT_MAP charging_profiles_map() const;

private:
    void initWatcher();
    void initConnect();
    void initConfigObject();
    bool reloadConfig(const setting_index_enum type, const QString& path);
    bool saveToObject(const setting_index_enum type, const QVariant& data);
    bool saveConfigToFile(const setting_index_enum type, const QString& path);
    QString getConfigFilePath(const setting_index_enum& type);

    // json to tcu config
    LOG_INFO logCfgFromJson(const QJsonObject& obj);
    PAYMENT_INFO    paymentCfgFromJson(const QJsonObject& obj);
    PRICE_SETTING   jsonToPriceSetting(const QJsonObject& obj);
    POS_MACHINE     jsonToPosMachine(const QJsonObject& obj);
    PAX_INFO        jsonToPaxInfo(const QJsonObject& obj);
    WIZAR_INFO      jsonToWizarInfo(const QJsonObject& obj);
    void tcuCfgFromJson();
    QJsonObject tcpServerToJson(const tcp_server_cfg_info_t& data);
    QJsonObject loginToJson(const admin_cfg_info_t& data);
    QJsonObject strectToJson(const layout_strect_info_t& data);
    QJsonObject logCfgToJson(const LOG_INFO& data);
    QJsonObject authTypeEnableToJson(const AUTH_TYPE_ENABLE& data);
    QJsonObject timeOutToJson(const TIME_OUT& data);
    QJsonObject paymentCfgToJson(const PAYMENT_INFO& data);
    QJsonObject priceSettingToJson(const PRICE_SETTING& data);
    QJsonObject posMachineToJson(const POS_MACHINE& data);
    QJsonObject paxInfoToJson(const PAX_INFO& data);
    QJsonObject wizarInfoToJson(const WIZAR_INFO& data);
    bool tcuCfgToJson();

    // json to ccu config
    void ccuCfgFromJson();
    QList<GUN_DETAIL> jsonToGUNDetail(const QJsonArray& array);
    PCUHW_CFG jsonToPcuhw(const QJsonObject& obj);
    PCUTC_CFG jsonToPcutc(const QJsonObject& obj);
    QTTCU_CFG jsonToQttcu(const QJsonObject& obj);
    QList<OCPP1_6> jsonToOcpp16(const QJsonArray& obj);
    QList<OCPP2_1> jsonToOcpp21(const QJsonArray& obj);
    bool ccuCfgToJson();
    QJsonArray gunDetailToJson(const QList<GUN_DETAIL> &config);
    QJsonObject pcuhwToJson(const PCUHW_CFG& config);
    QJsonObject pcutcToJson(const PCUTC_CFG& config);
    QJsonObject qttcuToJson(const QTTCU_CFG& config);
    QJsonArray ocpp16ToJson(const QList<OCPP1_6>& config);
    QJsonArray ocpp21ToJson(const QList<OCPP2_1>& config);

    // json to pcu config
    void pcuCfgFromJson();
    bool pcuCfgToJson();

    // json to price info
    QList<OFFLINE_PRICE> jsonToOfflinePrice(const QJsonArray &array);
    void priceInfoFromJson();
    QJsonArray offlinePriceToJson(const QList<OFFLINE_PRICE>& config);
    bool priceInfoToJson();

    // json to authorization list
    void authorizationFromJson();
    void fromValue(QList<AUTH_CARD_INFO> &auth_card_info, const QJsonArray& jsonArray);
    bool authorizationToJson();
    QJsonArray toJson(const QList<AUTH_CARD_INFO> &auth_card_info);

    // json to ocpp config key
    void configKeyFromJson();
    CORE_PROFILE    jsonToCoreProfile(const QJsonObject& obj);
    AUTH_LIST_MANAGE    jsonToLocalAuthList(const QJsonObject& obj);
    RESE_PROFILE    jsonToReservationProfile(const QJsonObject& obj);
    SMART_CHARGE    jsonToSmartChargingProfile(const QJsonObject& obj);
    bool configKeyToJson();
    QJsonObject coreProfileToJson(const CORE_PROFILE& config);
    QJsonObject localAuthListToJson(const AUTH_LIST_MANAGE& config);
    QJsonObject reservationProfileToJson(const RESE_PROFILE& config);
    QJsonObject smartChargingProfileToJson(const SMART_CHARGE& config);

    // json to charging profiles
    void chargingCfgFromJson();
    QList<charging_schedule_period_info_t>  jsonToChargingSchedulePeriod(const QJsonArray& array);
    charging_schedule_info_t                jsonToChargingSchedule(const QJsonObject &object);
    QList<charging_profiles_detail_info_t>  jsonToChargingProfileDetail(const QJsonArray &array);
    bool chargingCfgToJson();
    QJsonArray chargingSchedulePeriodToJson(const QList<charging_schedule_period_info_t>& config);
    QJsonObject chargingScheduleToJson(const charging_schedule_info_t& config);
    QJsonArray chargingProfileDetailToJson(const QList<charging_profiles_detail_info_t>& config);

    // json to charging records
    void chargingRecordsFromJson();
    QList<CHARGING_RECORD_INFO> jsonToChargingRecord(const QJsonArray& array);
    bool chargingRecordsToJson();
    QJsonArray chargingRecordsDetailToJson(const QList<CHARGING_RECORD_INFO>& config);

    // json to QVariant
    QStringList jsonToStringList(const QJsonValue &value);
    QJsonValue stringListToJson(const QStringList& stringList);
    QList<int> jsonToIntList(const QJsonValue &value);
    QJsonValue intListToJson(const QList<int>& intList);

    QString getTypeString(setting_index_enum type);
    int countKeysContaining(const QJsonObject &obj, const QString &target,
                            Qt::CaseSensitivity cs = Qt::CaseSensitive);

    void errorCodeNoteFromJson();
    bool errorCodeNoteToJson();

private slots:

signals:

private:
    QMap<setting_index_enum, QJsonObject> m_cfg_object;
    QMap<setting_index_enum, QFileSystemWatcher*> m_watcher;

    TCU_CFG                 m_tcu_cfg;
    CCU_CFG                 m_ccu_cfg;
    PCU_CFG                 m_pcu_cfg;
    PRICE_INFO              m_price_info;
    CONFIG_KEY_INFO         m_cfg_key;
    AUTH_LIST               m_auth_list;
    CHARGING_PROFILES       m_charging_profiles;
    QVARIANTMAP_INT_MAP     m_charging_profiles_map;
    CHARGING_RECORDS_INFO   m_charging_records;
};

#endif // CONFIGMANAGER_H
