#pragma once
#include <string>
#include "JsonSerializer.h"
#include "RtxApiClient.h"

namespace rtx
{
    namespace account
    {
        enum class OwnedType : uint32_t
        {
            /**
             * 分享者
             */
            SHARED = 0,
            /**
             * 拥有者
             */
            OWNED = 1,

            ALL = 10000
        };

        REGISTER_SERIALIZE_ENUM_INT(rtx::account::OwnedType, account,
                                    rtx::account::OwnedType::SHARED,
                                    rtx::account::OwnedType::OWNED,
                                    rtx::account::OwnedType::ALL)

        struct DeviceListReq : public Serializable
        {
            /**
             * 该参数仅调用客户端API时生效，主要用于确认请求发起者的系统参数，使用生活物联网平台提供的账号SDK时该值会自动生成。
             */
            std::string iotToken;
            /**
             * 当前页码，从1开始。
             */
            uint32_t pageNo = 1;
            /**
             * 分页大小，大于等于1，小于等于100。
             */
            uint32_t pageSize = 100;
            /**
             * 绑定类型。取值为：0（表示被分享的设备）；1（表示拥有的设备）；null（表示所有的设备）。
             */
            OwnedType owned = OwnedType::ALL;
            /**
             * 分组id，可按照分组id过滤列表
             */
            uint64_t groupId = 0;
            /**
             * 是否为子设备，true（表示获取子设备列表），false（表示获取直连设备列表）
             */
            bool isSubDevice = false;

            Json::Value toJson() const override;
            void fromJson(const Json::Value &json) override;
        };

        enum class DeviceStatus : uint32_t
        {
            /**
             * 未激活
             */
            INACTIVE = 0,
            /**
             * 在线
             */
            ONLINE = 1,
            /**
             * 休眠
             */
            SLEEP = 2,
            /**
             * 离线
             */
            OFFLINE = 3,
            /**
             * 禁用
             */
            DISABLE = 8
        };
        REGISTER_SERIALIZE_ENUM_INT(rtx::account::DeviceStatus, account,
                                    rtx::account::DeviceStatus::INACTIVE,
                                    rtx::account::DeviceStatus::ONLINE,
                                    rtx::account::DeviceStatus::SLEEP,
                                    rtx::account::DeviceStatus::OFFLINE,
                                    rtx::account::DeviceStatus::DISABLE)
        enum class NodeType : uint32_t
        {
            DEVICE = 0,
            GATEWAY = 1,

            UNKNOWN = 10000
        };
        REGISTER_SERIALIZE_ENUM_STRING(rtx::account::NodeType, account,
                                       {rtx::account::NodeType::DEVICE, "DEVICE"},
                                       {rtx::account::NodeType::GATEWAY, "GATEWAY"},
                                       {rtx::account::NodeType::UNKNOWN, "UNKNOWN"})

        enum class NetType : uint32_t
        {
            /**
             * 表示LoRa
             */
            NET_LORA = 0,
            /**
             * 表示2G/3G/4G/5G蜂窝网
             */
            NET_CELLULAR = 1,
            /**
             * 表示Wi-Fi
             */
            NET_WIFI = 2,
            /**
             * 表示ZigBee
             */
            NET_ZIGBEE = 3,
            /**
             * 表示以太网
             */
            NET_ETHERNET = 4,
            /**
             * 表示其他网络类型
             */
            NET_OTHER = 5,
            /**
             * 未知
             */
            NET_UNKNOWN = 10000

        };
        REGISTER_SERIALIZE_ENUM_STRING(rtx::account::NetType, account,
                                       {rtx::account::NetType::NET_LORA, "NET_LORA"},
                                       {rtx::account::NetType::NET_CELLULAR, "NET_CELLULAR"},
                                       {rtx::account::NetType::NET_WIFI, "NET_WIFI"},
                                       {rtx::account::NetType::NET_ZIGBEE, "NET_ZIGBEE"},
                                       {rtx::account::NetType::NET_ETHERNET, "NET_ETHERNET"},
                                       {rtx::account::NetType::NET_OTHER, "NET_OTHER"},
                                       {rtx::account::NetType::NET_UNKNOWN, "NET_UNKNOWN"})

        enum class ThingType : uint32_t
        {
            /**
             * 普通设备
             */
            DEVICE = 0,

            UNKNOWN = 10000

        };
        REGISTER_SERIALIZE_ENUM_STRING(rtx::account::ThingType, account,
                                       {rtx::account::ThingType::DEVICE, "DEVICE"})

        struct DeviceInfo : public Serializable
        {
            /**
             * 用户的身份ID。
             */
            uint64_t identityId;
            /**
             * 平台为设备颁发的ID，设备的唯一标识符。
             */
            std::string iotId;
            std::string deviceName;
            std::string productKey;
            std::string productName;
            /**
             * 设备所属产品的型号。
             */
            std::string productModel;
            /**
             * 设备的昵称
             */
            std::string nickName;
            /**
             * 产品下设备的联网方式，可取值： NET_LORA（表示LoRa）；NET_CELLULAR（表示2G/3G/4G/5G蜂窝网）；NET_WIFI（表示Wi-Fi）；NET_ZIGBEE（表示ZigBee）；NET_ETHERNET（表示以太网）；NET_OTHER（表示其他网络类型）。
             */
            NetType netType = NetType::NET_UNKNOWN;
            /**
             * DEVICE:普通设备
             */
            std::string thingType;
            /**
             * 设备状态。0（表示未激活）；1（表示在线）；3（表示离线）；8（表示禁用）。
             */
            DeviceStatus status = DeviceStatus::OFFLINE;
            /**
             * 设备和用户的关系，可取值：0（表示分享者），1（表示拥有者）。
             */
            OwnedType owned = OwnedType::ALL;
            /**
             * 设备的节点类型，可取值包括：DEVICE，GATEWAY。
             */
            NodeType nodeType = NodeType::DEVICE;
            /**
             * gmtModified
             */
            uint64_t gmtModified;
            /**
             * 设备当前所在的机房
             */
            std::string region;
            /**
             * 只有owned=0有值，分享权限列表，live：直播，control：设备控制，record：录像回看，ptz：云台控制，voiceIntercom：语音对讲，setting：高级设置，notification：消息通知
             */
            std::vector<std::string> sharePermissionList;
            /**
             * 分组id
             */
            uint64_t groupId = 0;

            Json::Value toJson() const override;
            void fromJson(const Json::Value &json) override;
        };
        REGISTER_SERIALIZE_OBJECT(DeviceInfo);

        struct DeviceList : public Serializable
        {
            uint32_t total;
            uint32_t pageNo;
            uint32_t pageSize;
            std::vector<DeviceInfo> data;

            Json::Value toJson() const override;
            void fromJson(const Json::Value &json) override;
        };
        REGISTER_SERIALIZE_OBJECT(DeviceList);

        struct DeviceListResp : public rtx::GatewayResp<DeviceList>
        {
        };
        REGISTER_SERIALIZE_OBJECT(DeviceListResp);

        struct DeviceGroupListReq : public Serializable
        {
            /**
             * 该参数仅调用客户端API时生效，主要用于确认请求发起者的系统参数，使用生活物联网平台提供的账号SDK时该值会自动生成。
             */
            std::string iotToken;
            /**
             * 当前页码，从1开始。
             */
            uint32_t pageNo = 1;
            /**
             * 分页大小，大于等于1，小于等于100。
             */
            uint32_t pageSize = 100;

            Json::Value toJson() const override;
            void fromJson(const Json::Value &json) override;
        };
        REGISTER_SERIALIZE_OBJECT(DeviceGroupListReq);

        struct DevicGroupInfo : public Serializable
        {
            /**
             * 分组id
             */
            uint64_t groupId;
            /**
             * 设备组的名称
             */
            std::string name;

            Json::Value toJson() const override;
            void fromJson(const Json::Value &json) override;
        };
        REGISTER_SERIALIZE_OBJECT(DevicGroupInfo);

        struct DeviceGroupList : public Serializable
        {
            uint32_t total;
            uint32_t pageNo;
            uint32_t pageSize;
            std::vector<DevicGroupInfo> items;

            Json::Value toJson() const override;
            void fromJson(const Json::Value &json) override;
        };
        REGISTER_SERIALIZE_OBJECT(DeviceGroupList);

        struct DeviceGroupListResp : public rtx::GatewayResp<DeviceGroupList>
        {
        };
        REGISTER_SERIALIZE_OBJECT(DeviceGroupListResp);

        struct GatewaySubDeviceListReq : public Serializable
        {
            std::string iotToken;
            std::string iotId;
            uint32_t pageNo = 1;
            uint32_t pageSize = 100;
            uint64_t groupId = 0;

            Json::Value toJson() const override;
            void fromJson(const Json::Value &json) override;
        };
        REGISTER_SERIALIZE_OBJECT(GatewaySubDeviceListReq);

        struct GatewaySubDeviceInfo : public Serializable
        {
            std::string iotId;
            std::string productKey;
            std::string deviceName;
            std::string nickName;
            std::string status;
            std::string owned;
            uint64_t gmtModified = 0;
            std::string region;
            std::vector<std::string> sharePermissionList;
            uint64_t groupId = 0;

            Json::Value toJson() const override;
            void fromJson(const Json::Value &json) override;
        };
        REGISTER_SERIALIZE_OBJECT(GatewaySubDeviceInfo);

        struct GatewaySubDeviceList : public Serializable
        {
            uint32_t total = 0;
            uint32_t pageNo = 0;
            uint32_t pageSize = 0;
            std::vector<GatewaySubDeviceInfo> data;

            Json::Value toJson() const override;
            void fromJson(const Json::Value &json) override;
        };
        REGISTER_SERIALIZE_OBJECT(GatewaySubDeviceList);

        struct GatewaySubDeviceListResp : public rtx::GatewayResp<GatewaySubDeviceList>
        {
        };
        REGISTER_SERIALIZE_OBJECT(GatewaySubDeviceListResp);

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        struct DeviceEntityAttributeValue : public Serializable
        {
            /**
             * id描述实体属性内容， 例如 1000:直播策略
             */
            int32_t id = 0;
            /**
             * 值
             */
            std::string value;

            Json::Value toJson() const override;
            void fromJson(const Json::Value &json) override;
        };
        REGISTER_SERIALIZE_OBJECT(DeviceEntityAttributeValue);

        struct DeviceEntityMapData : public Serializable
        {
            /**
             * key为属性id的字符串形式，例如 "1000"
             */
            std::map<std::string, DeviceEntityAttributeValue> attributeMap;
            /**
             * 最后更新时间
             */
            int64_t maxUpdateTimeValue = 0;

            Json::Value toJson() const override;
            void fromJson(const Json::Value &json) override;
        };
        REGISTER_SERIALIZE_OBJECT(DeviceEntityMapData);

        struct DeviceEntityGetReq : public Serializable
        {
            std::string iotToken;
            /**
             * 平台为设备颁发的ID，设备的唯一标识符。
             */
            std::string iotId;
            /**
             * id描述实体属性内容， 例如 1000:直播策略
             */
            std::vector<int32_t> attributeIdList;
            /**
             * 最近一次更新的时间，用于差量获取
             */
            int64_t lastUpdateTime = 0;
            /**
             * 实体类型， 默认0，0：设备维度类型，2：用户设备类型
             */
            int32_t entityType = 0;

            Json::Value toJson() const override;
            void fromJson(const Json::Value &json) override;
        };
        REGISTER_SERIALIZE_OBJECT(DeviceEntityGetReq);

        struct DeviceEntityGetResp : public rtx::GatewayResp<DeviceEntityMapData>
        {
        };
        REGISTER_SERIALIZE_OBJECT(DeviceEntityGetResp);

        class AccountDevice
        {
        private:
            std::string gatewayDomain;
            std::string appKey;
            std::string appSecret;
            std::string clientUniqueKey;

        public:
            AccountDevice(const std::string &gatewayDomain, const std::string &appKey, const std::string &appSecret, const std::string &clientUniqueKey);
            ~AccountDevice();

            std::shared_ptr<DeviceListResp> deviceList(const DeviceListReq &deviceListReq);
            std::shared_ptr<DeviceGroupListResp> deviceGroupList(const DeviceGroupListReq &request);
            std::shared_ptr<GatewaySubDeviceListResp> gatewaySubDeviceList(const GatewaySubDeviceListReq &request);
            // 用户获取设备实体属性，例如 attributeIdList=[1000] 获取直播策略
            std::shared_ptr<DeviceEntityGetResp> getDeviceEntity(const DeviceEntityGetReq &request);
        };

    }
}