#ifndef DEVICE_CTRL_WBS_H
#define DEVICE_CTRL_WBS_H
#include <utility>

#include "wbs/wbs_config.pb.h"
#include "common/utils/json_util.h"
#include "device_group.h"
#include "app/bean.h"
#include "common/utils/biz_lock.h"

namespace zsy
{
    class DeviceGroup;

    struct PlayVoiceParam
    {
        std::string id;
        std::string groupSn;
        std::string barrierSn;
        std::string content;
        uint8_t times;
    };

    inline void from_json(const nlohmann::json &j, PlayVoiceParam &o)
    {
        JSON_FIELD(id);
        JSON_FIELD(groupSn);
        JSON_FIELD(barrierSn);
        JSON_FIELD(content);
        JSON_FIELD(times);
    }

    struct OpenDoorParam
    {
        std::string id;
        std::string groupSn;
        std::string barrierSn;
    };

    inline void from_json(const nlohmann::json &j, OpenDoorParam &o)
    {
        JSON_FIELD(id);
        JSON_FIELD(groupSn);
        JSON_FIELD(barrierSn);
    }

    struct ObtainTruckDataParam
    {
        std::string id;
        std::string groupSn;
        std::string barrierSn;
        std::string orderId;
    };

    inline void from_json(const nlohmann::json &j, ObtainTruckDataParam &o)
    {
        JSON_FIELD(id);
        JSON_FIELD(groupSn);
        JSON_FIELD(barrierSn);
        JSON_FIELD(orderId);
    }

    struct ObtainTruckDataResult
    {
        std::string id;
        std::string orderId;
        std::string sn;
        std::string stationSn;
        std::string groupSn;
        std::string barrierSn;
        std::string bodyImage;
        std::string frontImage;
        int32_t weight;
        bool success;
    };

    inline void to_json(nlohmann::json &j, const ObtainTruckDataResult &o)
    {
        j = nlohmann::json{
            {"id", o.id},
            {"orderId", o.orderId},
            {"sn", o.sn},
            {"stationSn", o.stationSn},
            {"groupSn", o.groupSn},
            {"barrierSn", o.barrierSn},
            {"bodyImage", o.bodyImage},
            {"frontImage", o.frontImage},
            {"weight", o.weight},
            {"success", o.success}
        };
    }

    class Wbs : public Bean
    {
        inline static std::shared_ptr<Wbs> WBS;
        inline static std::shared_mutex WBS_MTX;
        WbsConfig config;
        std::shared_ptr<BizLock> bizLock;


        enum class DeviceType
        {
            BARRIER,
            VIDICON,
            SPKBOX,
            LOADOMETER,
        };

        std::unordered_map<std::string, std::shared_ptr<DeviceGroup> > deviceGroups;

    public:
        explicit Wbs(const WbsConfig &config);

        void playVoice(const PlayVoiceParam &param);

        void openDoor(const OpenDoorParam &param);

        void obtainTruckData(const ObtainTruckDataParam &param);

        std::string name() const noexcept override;

        std::string sn() const noexcept override;

        static void init();

        static void destroy();

        static std::shared_ptr<Wbs> get();

        ~Wbs() override = default;
    };
} // zsy

#endif //DEVICE_CTRL_WBS_H