#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include <memory>
#include <map>
#include <unordered_map>
#include "common/Fields.h"
#include "app/Config.h"
#include "common/Spdlogger.h"

class Station;
class Device;
class SysPolicy;

using VecPairSS = std::vector<std::pair<std::string, std::string>>;

struct User
{
    std::string userId;
    std::string account;
    std::string token;
    int64_t loginTime {};
};

struct DeviceType
{
    int typeId {};
    std::string name;
    std::string group;
    std::string attr;
    Fields fieldsAttr;
};

struct Role
{
    int roleId {};
    std::string name;
    bool isOpen {false};
};

class ElectPeriod
{
public:
    double priceSuperPeak {};
    double pricePeak {};
    double priceShoulder {};
    double priceOffPeak {};

    std::vector<std::vector<std::string>> vecPeriods;

    void parse(std::string jsonstr);

    std::string dump();
};

class StateGrid
{
public:
};

class AppData
{
public:
    bool init();
    bool initFromDB();

    // 读取统计数据： 今日统计数据，累计统计数据
    void loadStatData();

    std::string userLogin(std::string userId, std::string account);
    User getUser(std::string token);

    std::shared_ptr<Station> getStation(int stationId);
    int getStationCount();

    std::shared_ptr<Station> getStationByName(std::string name);
    std::shared_ptr<Station> getStationByCode(std::string code);

    std::shared_ptr<Device> getDevice(int stationId, int deviceId);
    std::shared_ptr<Device> getDeviceByType(int stationId, int deviceType, std::string code);
    
    std::string getDeviceNameById(int typeId);

    // 获取设备类型定义
    std::shared_ptr<DeviceType> getDeviceTypeDef(int typeId);

    int getWorkModeIdByName(std::string name);

    ///////////////////////////////////////////////////////////////////////////////////////////////
    // 获取角色名称列表
    std::vector<std::string> getRoleNames();
    // 获取场站名称列表
    std::vector<std::string> getStationNames();
    // 获取设备类型
    std::vector<std::string> getDeviceTypeNames();
    // 获取工作模式
    std::vector<std::string> getWorkModes();
    // 获取策略类型定义
    std::vector<std::string> getPolicyTypeNames();
    // 获取策略名称
    std::vector<std::string> getPolicyNames();
    // 根据策略类型ID获取策略信息
    std::shared_ptr<SysPolicy> getPolicyByType(int typeId);

    std::shared_ptr<SysPolicy> getPolicyById(int policyId);
    

    //std::vector<std::string> getElectPreiodVals(int month);
    //std::string getElectPreiodVal(int month, int hour);

    void storeRuntimeDB();


public:
    ///////////////////////////////////////////////////////////////////////////////////////////////
    // === 系统 ===
    std::string launchDate;

    ///////////////////////////////////////////////////////////////////////////////////////////////
    // === 数据库 ===
    struct {
        std::string host;
        int port;
        std::string user;
        std::string passwd;
    } db;

    struct {
        VecPairSS isopen {{"0", "禁用"}, {"1", "启用"}};
        VecPairSS gender {{"0", "女"}, {"1", "男"}};
        // 角色 Mapping （id->name）
        VecPairSS role;

        VecPairSS deviceType;

        VecPairSS workMode;

        VecPairSS policyType;
        VecPairSS stationName;
    } mapping;

    //double electPriceSuperPeak {};
    //double electPricePeak {};
    //double electPriceShoulder {};
    //double electPriceOffPeak {};
    // 电力峰谷分段 (12个月，每个月按小时分成24个时段)
    //std::vector<std::vector<std::string>> vecElectPeriods;

    // 场站信息
    std::map<int, std::shared_ptr<Station>> mapStation;

    // 角色信息
    std::unordered_map<int, std::shared_ptr<Role>> mapRole;

    // 设备类型定义
    std::unordered_map<int, std::shared_ptr<DeviceType>> mapDeviceType;

    // 工作模式定义
    std::unordered_map<int, std::string> mapWorkMode;

    // 策略类型定义
    std::unordered_map<int, std::string> mapPolicyType;

    // 策略信息
    std::unordered_map<int, std::shared_ptr<SysPolicy>> mapPolicy;

    std::map<int64_t, double> mapDataDay;

};
