package mqttClient

import (
	"PPOSUtils/utils"
	"errors"
	"fmt"
	"time"
)

func NewCmdResponse(deviceCode, id string) *CmdResponse {
	return &CmdResponse{
		deviceCode:   deviceCode,
		id:           id,
		responseChan: make(chan utils.Mp, 10),
	}
}

type CmdResponse struct {
	deviceCode   string
	id           string
	responseChan chan utils.Mp
	client       *MqttClient
	topic        string
}

func (that *CmdResponse) GetResult() error {
	_i := 0
	for {
		_i++
		fmt.Println(" get response times: ", _i)
		if _i > 3 {
			return errors.New("指令已发送，等待响应超时")
		}
		_timer := time.NewTimer(time.Duration(1) * time.Second)
		select {
		case _data := <-that.responseChan:
			if !_timer.Stop() {
				<-_timer.C
			}
			_slice := []string{
				"id",
				"deviceID",
				"status",
				"msg",
			}
			for _, _v := range _slice {
				if !_data.Has(_v) {
					return errors.New("指令响应格式错误，缺少字段B:" + _v)
				}
			}
			_id := utils.ToString(_data.Get("id"))
			_deviceID := utils.ToString(_data.Get("deviceID"))
			_msg := utils.ToString(_data["msg"])
			if _id == that.id && _deviceID == that.deviceCode {
				if _data["status"] == "1" {
					return nil
				} else {
					return errors.New("指令发送失败:" + _msg)
				}
			}
		case <-_timer.C:
		}
	}
}

func (that *CmdResponse) SubMQTT(mqttPubID, mqttHost, mqttUsername, mqttPassword string) error {
	_id := fmt.Sprintf("%s-%d", mqttPubID, time.Now().UnixNano())
	//订阅设备响应
	_mqttClient := NewMqttClient(mqttHost, mqttUsername, mqttPassword)
	if _err := _mqttClient.Conn(_id); _err != nil {
		return errors.New("MQTT链接失败:" + _err.Error())
	}
	that.topic = that.deviceCode + "#response"
	that.client = _mqttClient
	//
	_handler := NewMqttSubMessage(func(deviceID, topic, msgID string, data utils.Mp) {
		that.responseChan <- data
	})
	//
	if _err := _mqttClient.SubMsg(that.topic, _handler); _err != nil {
		return errors.New("MQTT订阅失败:" + _err.Error())
	}
	return nil
}

func (that *CmdResponse) close() {
	close(that.responseChan)
	if that.client != nil {
		_topic := that.deviceCode + "-response"
		that.client.UnSubMsg(_topic)
		that.client.Close()
	}
}
