package controller

import (
	"encoding/json"
	"fmt"
	"netease_control_center/globals"
	"netease_control_center/interfaces/http"
	. "netease_control_center/interfaces/innerTask"
	"netease_control_center/interfaces/log"
	"netease_control_center/interfaces/schedule"
	"netease_control_center/modules/player"
	"sync"
	"time"
)

var (
	iCmdParams     *schedule.NoticePlayerParams = nil
	iCmdParamsLock sync.Mutex
)

func init() {
	ICmdFunc = execInnterCmd
}

func execInnterCmd(cmd ICmd, arg ...interface{}) {
	defer func() {
		if err := recover(); err != nil {
			log.Println(log.ErrorLog, err)
		}
	}()
	log.Println(log.DebugLog, "Begin to exec inner cmd:", cmd, arg)
	switch cmd {
	case ICmd_Start_Nil:
		log.Println(log.DebugLog, "Nil ICmd, do nothing!")

	case ICmd_Create_Session_With_Server_Param:
		serverParam := arg[0].(string)
		ScheduleNewVoiceSession(VoiceSession_Type_Confirm, "", serverParam)

	case ICmd_Create_Session_With_Device_Param:
		deviceParam := arg[0].(string)
		ScheduleNewVoiceSession(VoiceSession_Type_Confirm, deviceParam, "")

	case ICmd_Set_Comfirm_Info:
		iCmdParamsLock.Lock()
		iCmdParams = arg[0].(*schedule.NoticePlayerParams)
		iCmdParamsLock.Unlock()
	case ICmd_Trig_Exec:
		iCmdParamsLock.Lock()
		if nil != iCmdParams {
			player.NoticePlayerSendSCmd2(schedule.SCMD_SuperTask_Tts_Ctrl_Play, *iCmdParams)
			iCmdParams = nil
		}
		iCmdParamsLock.Unlock()
	case ICmd_Enter_Scene:
		if sceneid, ok := arg[0].(string); ok && len(sceneid) > 0 {
			schedule.SceneRequestPlay(sceneid)
		}

	case ICmd_Toast_Tts:
		if tts, ok := arg[0].(string); ok && len(tts) > 0 {
			MscToastTts(tts, globals.CONST_AUDIO_ID, false, false, nil)
		}

	case ICmd_ConfirmSession_Deal:
		// arg:
		// 0,int,delay time (ms)
		// 1,string, the type of ConfirmVoiceSessionParam
		// 2,confirm type, yes\no\delay

		var delaytime time.Duration
		var param ConfirmVoiceSessionParam
		var confirmtype string

		if tmpdelay, ok := arg[0].(int); ok {
			delaytime = time.Duration(tmpdelay) * time.Millisecond
		} else {
			log.Println(log.DebugLog, "Decode delay time error!")
			return
		}

		if tmpstring, ok := arg[1].(string); ok {
			if err := json.Unmarshal([]byte(tmpstring), &param); err != nil {
				log.Println(log.DebugLog, "Json error:", err)
				return
			}
		} else {
			log.Println(log.DebugLog, "Decode param error!")
			return
		}

		if tmpstring, ok := arg[2].(string); ok {
			confirmtype = tmpstring
		} else {
			log.Println(log.DebugLog, "Decode param error!")
			return
		}

		switch param.Type {
		case ConfirmVoiceSessionParam_Type_Scene:
			log.Printf(log.DebugLog, "Get arg:%+v\n", param)
			log.Println(log.DebugLog, "Cur delay vocie session: ConfirmVoiceSessionParam_Type_Scene, delay:", delaytime, " id:", param.Delay, "type:", confirmtype)
			switch confirmtype {
			case "yes":
				schedule.SceneRequestPlay(param.Yes)

			case "no":
				MscToastTts(param.No, globals.CONST_AUDIO_ID, true, false, nil)

			case "delay":
				if delaytime > 0 {
					tts := fmt.Sprintf("知道了,%d分钟后进入场景", int64(delaytime.Minutes()))
					MscToastTts(tts, globals.CONST_AUDIO_ID, true, false, nil)
					time.AfterFunc(delaytime, func() {
						log.Println(log.DebugLog, "Timeout, begin to exec scene id:", param.Delay)
						tmpscene := schedule.GetCurSScene()
						if tmpscene != nil && tmpscene.Scene.Id == param.Delay {
							log.Println(log.DebugLog, "Scene id is eq cur scene id, do not start!")
						} else {
							EnterAlarmScene(param.Delay)
						}
					})
				} else {
					//delay time 0, do now
					log.Println(log.DebugLog, "Delay time is 0, do now!")
					schedule.SceneRequestPlay(param.Delay)
				}
			}
		}

	default:
		log.Println(log.ErrorLog, "Do not support cur cmd", cmd, arg)
	}
}

func EnterAlarmScene(sceneid string) {
	var scenereq http.HttpReqSceneById
	var scenersp http.HttpRspSceneById

	scenereq.SceneId = sceneid

	if code, _, err := http.HttpPostAuto(scenereq, &scenersp); code == 1000 && err == nil {
		if scenersp.IsUserConfirm {
			log.Println(log.DebugLog, "Cur scene need user confirm!")
			tmpconfig := player.GetDefaultNoticePlayerParams()
			tmpconfig.SrcType = globals.AdSrcType_TTS
			tmpconfig.NeedRepeat = true
			if len(scenersp.ConfirmEnterTts.Tts) > 0 {
				tmpconfig.Tts = scenersp.ConfirmEnterTts.Tts
			} else {
				tmpconfig.Tts = "是否进入场景" + scenersp.Name
			}
			var param ConfirmVoiceSessionParam
			param.Type = ConfirmVoiceSessionParam_Type_Scene
			param.Yes = sceneid
			param.No = "本次场景已取消"
			param.Delay = sceneid
			tmpconfig.SpecialCmd = ICmdPack(ICmd_Create_Session_With_Device_Param, param.String())
			player.NoticePlayerSendSCmd2(schedule.SCMD_SuperTask_Tts_Ctrl_Play, tmpconfig)
		} else {
			log.Println(log.DebugLog, "Cur scene do not need user confirm!")
			schedule.SceneRequestPlay(http.Scene(scenersp))
		}
	}
}
