package mqttClient

import (
	"PPOSUtils/utils"
	"encoding/json"
	"errors"
	"fmt"

	//"fmt"
	"time"
)

//func NewCmdRequest(deviceCode string) *CmdRequest {
//	return &CmdRequest{
//		deviceCode: deviceCode,
//	}
//}

type CmdRequest struct {
	id         string
	deviceCode string
	//
	mqttPubID    string
	mqttHost     string
	mqttUsername string
	mqttPassword string
	subClient    *MqttClient
	pubClient    *MqttClient
	cmdHanderMap map[string]func(deviceID string, mp utils.Mp) error
}

func (that *CmdRequest) Pub(mp utils.Mp) error {

	_id := fmt.Sprintf("%s-%d", that.mqttPubID, time.Now().UnixNano())
	_response := NewCmdResponse(that.deviceCode, _id)
	defer _response.close()
	if _err := _response.SubMQTT(that.mqttPubID, that.mqttHost, that.mqttUsername, that.mqttPassword); _err != nil {
		return _err
	}
	//
	mp.Set("id", _id)
	mp.Set("deviceID", that.deviceCode)
	mp.Set("ct", utils.ToString(time.Now().Unix()))
	mp.Set("rt", utils.ToString(time.Now().Unix()+5))
	_data, _ := json.Marshal(mp)
	if _err := that.pubClient.PubMsg(that.deviceCode, _data); _err != nil {
		return errors.New("指令发送失败:" + _err.Error())
	}
	//
	if _err := _response.GetResult(); _err != nil {
		return _err
	}
	return nil
}

func (that *CmdRequest) pubResponse(status, msg string) error {
	//响应
	_data := map[string]interface{}{
		"id":       that.id,
		"deviceID": that.deviceCode,
		"status":   status,
		"msg":      msg,
	}
	_reqJson, _err := json.Marshal(_data)
	if _err != nil {
		return _err
	}
	_topic := that.deviceCode + "#response"
	if _err := that.pubClient.PubMsg(_topic, _reqJson); _err != nil {
		return _err
	}
	return nil
}

func (that *CmdRequest) cmd(mp utils.Mp) error {
	_slice := []string{
		"id",
		"deviceID",
		"ct",
		"rt",
		"cmdType",
	}
	for _, _v := range _slice {
		if !mp.Has(_v) {
			return errors.New("指令格式错误，缺少字段A:" + _v)
		}
	}
	if time.Now().Unix() > utils.ToInt64(mp.Get("rt")) {
		return errors.New("指令已过期")
	}
	that.id = utils.ToString(mp.Get("id"))
	//执行指令
	_cmdType := utils.ToString(mp.Get("cmdType"))
	if _hander, _ok := that.cmdHanderMap[_cmdType]; _ok {
		if _err := _hander(that.deviceCode, mp); _err != nil {
			return that.pubResponse("0", _err.Error())
		}
	}
	return that.pubResponse("1", "SUCCESS")
}
