package main

//screen操作相关
import (
	"context"
	"encoding/json"
	"lc/common/mqtt"
	"lc/common/protocol"
	"lc/common/util"
	"lc/edge/led_screen/clt_client"
	"strconv"
	"strings"
	"time"
)

type LedDevice struct {
	LedInfo
	playing   string //当前播放节目 没有用到
	ctx       context.Context
	cancel    context.CancelFunc
	downQueue *util.MlQueue
	//upQueue		   *util.MlQueue
	mapTopicHandle map[string]func(m mqtt.Message)
}

func (l *LedDevice) GetCltUrl(ctlurl string) string {
	return l.BaseURL + ctlurl
}

func NewLedDevice(info LedInfo) *LedDevice {
	ctx, cancel := context.WithCancel(context.Background())
	dev := LedDevice{
		info,
		"",
		ctx,
		cancel,
		util.NewQueue(100),
		//util.NewQueue(50),
		make(map[string]func(m mqtt.Message)),
	}
	dev.SetTopicHandle()
	dev.MQTTSubscribe()
	go dev.Handle()
	return &dev
}

func (l *LedDevice) SetTopicHandle() {
	l.mapTopicHandle[protocol.TP_LED_SET_PGMS] = l.PublishProgram          //发布节目
	l.mapTopicHandle[protocol.TP_LED_QUERY_PGMS] = l.ListPrograms          //查询节目
	l.mapTopicHandle[protocol.TP_LED_DELETE] = l.DeleteProgram             //删除节目
	l.mapTopicHandle[protocol.TP_LED_CLEAN] = l.CleanAll                   //清除所有节目
	l.mapTopicHandle[protocol.TP_LED_QUERY_INFO] = l.QueryInfo             //查询屏信息
	l.mapTopicHandle[protocol.TP_LED_SWITCH] = l.SwitchProgram             //切换节目
	l.mapTopicHandle[protocol.TP_LED_SNAPSHOT] = l.SnapShot                //快照
	l.mapTopicHandle[protocol.TP_LED_QUERY_SCHEDULE] = l.GetSchedule       //获取排程
	l.mapTopicHandle[protocol.TP_LED_SET_SCHEDULE] = l.SetSchedule         //发布排程
	l.mapTopicHandle[protocol.TP_LED_QUERY_POWERSTATUS] = l.PowerStatus    //电源状态
	l.mapTopicHandle[protocol.TP_LED_SET_CMD] = l.ControlPower             //控制电源
	l.mapTopicHandle[protocol.TP_LED_QUERY_RESOLUTION] = l.Resolution      //屏幕参数
	l.mapTopicHandle[protocol.TP_LED_QUERY_VOLUME] = l.GetVolume           //查询音量
	l.mapTopicHandle[protocol.TP_LED_SET_VOLUME] = l.SetVolume             //设置音量
	l.mapTopicHandle[protocol.TP_LED_QUERY_BRIGHTCOLOR] = l.GetBrightColor //查询亮度和色温
	l.mapTopicHandle[protocol.TP_LED_SET_BRIGHTNESS] = l.SetBright         //设置亮度和色温

}

func (l *LedDevice) MQTTSubscribe() {
	GetMQTTMgr().Subscribe(GetTopic(l.SN, "down"), mqtt.AtMostOnce, l.HandleMessage, ToCloud)
}

func (l *LedDevice) HandleMessage(m mqtt.Message) {
	l.downQueue.Put(m)
}

func (l *LedDevice) Handle() {
	//timer := time.NewTicker(1 * time.Minute)
	timer := time.NewTicker(10 * time.Second)
	for {
		select {
		case <-l.ctx.Done():
			return
		case <-timer.C: //心跳，检查在线状态， 每隔1分钟执行一次
			url := l.GetCltUrl(clt_client.POWERS_TATUS)
			_, err := clt_client.GetClient().CommonGet(url)
			if err != nil {
				l.CheckOnline(l, uint8(1))
				continue
			}
			l.CheckOnline(l, uint8(0))
			l.LedData(l)
		default:
			if m, ok, _ := l.downQueue.Get(); ok {
				if mm, ok := m.(mqtt.Message); ok {
					action := strings.Split(mm.Topic(), "/")[4]
					if fn, ok := l.mapTopicHandle[action]; ok {
						fn(mm)
					}
				}
			} else {
				time.Sleep(50 * time.Millisecond)
			}
		}
	}
}

func (l *LedDevice) CheckOnline(dev *LedDevice, online uint8) {
	var obj protocol.Pack_LedState
	if str, err := obj.EnCode(dev.SN, appConfig.GID, GetNextUint64(), util.MlNow(), online); err == nil {
		topic := appConfig.Tenant + "/cltled/" + dev.SN + "/up/" + protocol.TP_LED_STATE + "/" + strconv.Itoa(int(GetNextUint64()))
		//fmt.Printf("topic = %v str=%v \n", topic, str)
		GetMQTTMgr().Publish(topic, []byte(str), mqtt.AtMostOnce, ToCloud)
	}
}

// LedData 上报信息屏详细信息
func (l *LedDevice) LedData(dev *LedDevice) {
	var data protocol.CltledData
	//电源状态
	res, _ := clt_client.GetClient().CommonGet(l.GetCltUrl(clt_client.POWERS_TATUS))
	json.Unmarshal(res, &data)
	//音量
	res, _ = clt_client.GetClient().CommonGet(l.GetCltUrl(clt_client.GET_VOLUME))
	json.Unmarshal(res, &data)
	//亮度色温
	res, _ = clt_client.GetClient().CommonGet(l.GetCltUrl(clt_client.GET_BRIGHTCOLOR))
	json.Unmarshal(res, &data)
	//开关机时间
	res, _ = clt_client.GetClient().CommonGet(l.GetCltUrl(clt_client.GET_SCHEDULE))
	json.Unmarshal(res, &data)
	//分辨率
	res, _ = clt_client.GetClient().CommonGet(l.GetCltUrl(clt_client.RESOLUTION))
	json.Unmarshal(res, &data)

	//当前节目
	res, _ = clt_client.GetClient().CommonGet(l.GetCltUrl(clt_client.LIST_PROGRAMS))
	resMap := make(map[string]map[string]interface{})
	json.Unmarshal(res, &resMap)
	payingName, ok := resMap["playing"]["name"]
	if ok {
		if s, ok := payingName.(string); ok {
			data.Playing = s
		}
	}
	var obj protocol.Pack_LedCltledData
	if str, err := obj.EnCode(dev.SN, appConfig.GID, GetNextUint64(), &data); err == nil {
		topic := appConfig.Tenant + "/cltled/" + dev.SN + "/up/" + protocol.TP_LED_DATA + "/" + strconv.Itoa(int(GetNextUint64()))
		GetMQTTMgr().Publish(topic, []byte(str), mqtt.AtMostOnce, ToCloud)
	}
}

func GetNextUint64() uint64 {
	u64, _ := IDGen.NextId()
	return uint64(u64)
}

//===============POST=====

// PublishProgram 平台发布节目
func (l *LedDevice) PublishProgram(m mqtt.Message) {

	clt_client.GetClient().PublishProgram(m, l.BaseURL)
	//获取结果 并 响应云端
	l.ListPrograms(m)
}

func (l *LedDevice) SetSchedule(m mqtt.Message) {
	url := l.GetCltUrl(clt_client.SET_SCHEDULE)
	l.DoCommonPost(url, "func SetSchedule", m)
	l.GetSchedule(m)
}

// ControlPower 控制电源
func (l *LedDevice) ControlPower(m mqtt.Message) {
	url := l.GetCltUrl(clt_client.CONTROL_POWER)
	l.DoCommonPost(url, "func ControlPower", m)
	l.PowerStatus(m)
}

func (l *LedDevice) DoCommonPost(url, funcName string, m mqtt.Message) {
	clt_client.GetClient().CommonPost(m.Payload(), url)
}

//==========================GET==================================GET

// ListPrograms 查询所有节目以及当前播放的节目
func (l *LedDevice) ListPrograms(m mqtt.Message) {
	url := l.GetCltUrl(clt_client.LIST_PROGRAMS)
	l.DoCommonGet(url, "func ListPrograms", m)
}

// QueryInfo 查询屏通用信息
func (l *LedDevice) QueryInfo(m mqtt.Message) {
	url := l.GetCltUrl(clt_client.QUERY_INFO)
	l.DoCommonGet(url, "func QueryInfo", m)
}

// PowerStatus 获取电源状态
func (l *LedDevice) PowerStatus(m mqtt.Message) {
	url := l.GetCltUrl(clt_client.POWERS_TATUS)
	l.DoCommonGet(url, "get power status", m)
}

// Resolution 查询屏幕参数
func (l *LedDevice) Resolution(m mqtt.Message) {
	url := l.GetCltUrl(clt_client.RESOLUTION)
	l.DoCommonGet(url, "func Resolution", m)
}

// GetSchedule 查询电源排程
func (l *LedDevice) GetSchedule(m mqtt.Message) {
	url := l.GetCltUrl(clt_client.GET_SCHEDULE)
	l.DoCommonGet(url, "func GetSchedule", m)
}

// GetBrightColor GetBrightnessColorTemperature 查询亮度和色温
func (l *LedDevice) GetBrightColor(m mqtt.Message) {
	url := l.GetCltUrl(clt_client.GET_BRIGHTCOLOR)
	l.DoCommonGet(url, "func GetBrightnessColorTemperature", m)
}

// GetVolume 查询音量
func (l *LedDevice) GetVolume(m mqtt.Message) {
	url := l.GetCltUrl(clt_client.GET_VOLUME)
	l.DoCommonGet(url, "func GetVolume", m)
}

// SnapShot 截屏
func (l *LedDevice) SnapShot(m mqtt.Message) {
	url := l.GetCltUrl(clt_client.SNAPSHOT)
	shot := clt_client.GetClient().SnapShot(url)
	GetMQTTMgr().Publish(getUpTopic(m.Topic()), shot, mqtt.AtMostOnce, ToCloud)
}

func (l *LedDevice) DoCommonGet(url, funcName string, m mqtt.Message) {
	resp, _ := clt_client.GetClient().CommonGet(url)
	GetMQTTMgr().Publish(getUpTopic(m.Topic()), resp, mqtt.AtMostOnce, ToCloud)
}

//================================PUT

// SwitchProgram 切换节目
func (l *LedDevice) SwitchProgram(m mqtt.Message) {
	clt_client.GetClient().SwitchProgram(m, l.BaseURL)
	l.SnapShot(m)
}

// SetBright 调节屏幕亮度
func (l *LedDevice) SetBright(m mqtt.Message) {
	url := l.GetCltUrl(clt_client.SET_BRIGHT)
	clt_client.GetClient().CommonPut(m.Payload(), url)
	l.GetBrightColor(m)
}

// SetVolume 设置音量
func (l *LedDevice) SetVolume(m mqtt.Message) {
	url := l.GetCltUrl(clt_client.SET_VOLUME)
	clt_client.GetClient().CommonPut(m.Payload(), url)
	l.GetVolume(m)
}

//=============DELETE=====

// DeleteProgram 删除节目
func (l *LedDevice) DeleteProgram(m mqtt.Message) {
	clt_client.GetClient().DelPrograms(m, l.BaseURL)
	//获取结果 并 响应云端
	l.ListPrograms(m)
}

// CleanAll 清除所有节目
func (l *LedDevice) CleanAll(m mqtt.Message) {
	clt_client.GetClient().CleanAll(l.BaseURL)
	//获取结果 并 响应云端
	l.ListPrograms(m)
}
