package controller

import (
	"encoding/json"
	. "netease_control_center/globals"
	"netease_control_center/interfaces/eventPoint"
	"netease_control_center/interfaces/http"
	"netease_control_center/interfaces/innerTask"
	"netease_control_center/interfaces/log"
	"netease_control_center/interfaces/schedule"
	"netease_control_center/interfaces/vui"
	"netease_control_center/interfaces/vui/cvui"
	"netease_control_center/modules/hardware/mcu_leds/atservice"
	"netease_control_center/modules/player"
	"netease_control_center/modules/storage"
	"time"
)

func DbusYunxinSysMsgControl(data []byte) {
	log.Println(log.DebugLog, "Sys msg:", string(data))
	var msg YunxinSysmsg
	if err := json.Unmarshal(data, &msg); err != nil {
		log.Println(log.DebugLog, "1Decode yunxin msg err:", err)
		return
	}

	if msg.Content.FromAccount != YunxinServerAccount {
		log.Println(log.DebugLog, "Server account not eq ", YunxinServerAccount)
		return
	}

	if len(msg.Content.Attach) == 0 {
		log.Println(log.DebugLog, "Recv server msg == nil, do nothing")
		return
	} else {
		log.Println(log.DebugLog, "Has recv server notice:", msg.Content.Attach)
	}

	var cmd YunxinServerCmd
	if err := json.Unmarshal([]byte(msg.Content.Attach), &cmd); err != nil {
		log.Println(log.DebugLog, "!!decode server msg err, ", err)
		return
	}

	eventPoint.EpRecord("A224", map[string]interface{}{"msgid": cmd.MsgId, "sourceos": eventPoint.EpOs_Server})

	switch cmd.CmdId {
	case YxSCmd_InBtOnWifiOff:
		schedule.SendSCmd(schedule.SCMD_SuperTask_Enter_btOnWifiOff)

	case YxSCmd_IotWifiParingResult:
		var tmp struct {
			Tts string `json:"tts"`
		}
		if jsonerr := json.Unmarshal([]byte(cmd.Detail), &tmp); jsonerr == nil {
			Iot_Wifiparing_end(tmp.Tts)
		}
	case YxSCmd_RefreshCfglist:
		http.UpdateCfgList()

	case YxSCmd_MscTest:
		tmpdata := []byte(cmd.Detail)
		MscSuccessCommand(&tmpdata, uint32(len(tmpdata)))

	case YxScmd_Res_Refresh:
		cvui.UpdateResFromServer()

	case YxSCmd_Upgrade:
		log.Println(log.DebugLog, "Do upgrade!")
		OTACheckNewVersion(false, false)

	case YxSCmd_AlarmChange:
		// alarm change todo
		DbusRefleshAlarmClocks()

	case YxSCmd_RemindChange:
		DbusRefleshReminds()

	case YxSCmd_SceneAlarmChange:
		DbusRefleshSceneAlarm()

	case YxSCmd_Top3Rcmd:
		var tmpCmd struct {
			ServerDetailBase
		}
		err := json.Unmarshal([]byte(cmd.Detail), &tmpCmd)
		if err != nil {
			log.Println(log.ErrorLog, err.Error())
			break
		}
		switch Cmd(tmpCmd.Cmd) {
		case MSC_CMD_PLAY_LIST:
			var tmp struct {
				ServerMusicList
			}
			err := json.Unmarshal([]byte(cmd.Detail), &tmp.ServerMusicList)
			if err != nil {
				log.Println(log.ErrorLog, err.Error())
				break
			}
			if nil != tmp.MusicList.SongList && len(tmp.MusicList.SongList) > 0 {
				tmp.MusicList.SongList[0].Tts = &tmpCmd.Tts
			}
			log.Printf(log.DebugLog, "top3 list info:%+v\n", tmp.ServerMusicList)
			player.InsertSongstoPlayList(&tmp.ServerMusicList, false)
		case MSC_CMD_PLAY_MUSIC:
			var tmp struct {
				Data SongInfoDetail `json:"data"`
			}
			err := json.Unmarshal([]byte(cmd.Detail), &tmp)
			if err != nil {
				log.Println(log.ErrorLog, err.Error())
				break
			}
			list := createTopList(&tmp.Data)

			list.MusicList.SongList[0].Tts = &tmpCmd.Tts
			log.Printf(log.DebugLog, "top3 single info:%+v\n", *list)
			player.InsertSongstoPlayList(list, false)
		default:
			log.Println(log.DebugLog, "unknow cmd:", tmpCmd.Cmd)
		}
	case YxScmd_Tts_Delay:
		var tmp struct {
			Type        int       `json:"sessionType"`
			Tts         string    `json:"tts"`
			Delay       bool      `json:"delay"`
			TtsType     AdSrcType `json:"ttsType"`
			ServerParam string    `json:"serverParam"`
		}
		err := json.Unmarshal([]byte(cmd.Detail), &tmp)
		if err != nil {
			log.Println(log.ErrorLog, err.Error())
			break
		}

		tmpconfig := player.GetDefaultNoticePlayerParams()
		tmpconfig.Keep = false
		tmpconfig.NeedRepeat = true
		tmpconfig.SrcType = tmp.TtsType
		tmpconfig.Tts = tmp.Tts
		tmpconfig.LedOn = schedule.DirectLed{EffectId: atservice.GUIDE_EFFECT_ID_EXEC_CMD, Action: atservice.GUIDE_ACTION_START}
		tmpconfig.LedOff = schedule.DirectLed{EffectId: atservice.GUIDE_EFFECT_ID_EXEC_CMD, Action: atservice.GUIDE_ACTION_STOP}
		switch tmp.Type {
		case Type_Create_Session:
			tmpconfig.SpecialCmd = innerTask.ICmdPack(innerTask.ICmd_Create_Session_With_Server_Param, tmp.ServerParam)
		case Type_Not_Create_Session:
			tmpconfig.SpecialCmd = ""
		default:
			log.Println(log.WarningLog, "err type:", tmp.Type)
		}

		tmpconfig.BeforeExecFunc = func() {
			go http.InformMsgToServer(http.Type_Inform_TtsDelay, tmp.Tts)
		}

		tmpconfig.SpecialFunc = func(arg schedule.TtsPlayerArg) {
			//检查是否网络缓存播放失败
			if arg.StopReason == schedule.NoticeStopReason_Error {
				go MscToastFile(vui.SoundNotice_Song_Get_Timeout.GetPath(), CONST_AUDIO_ID, false, false, nil)
			}
		}

		if tmp.Delay {
			innerTask.ICmdFunc(innerTask.ICmd_Set_Comfirm_Info, &tmpconfig)
		} else {
			player.NoticePlayerSendSCmd2(schedule.SCMD_SuperTask_Tts_Ctrl_Play, tmpconfig)
		}
	case YxSCmd_ReBindUserid:
		log.Println(log.DebugLog, "Get rebind user msg:", cmd.Detail)
		CheckServerBindUser()
		return
		var tmp struct {
			Userid string `json:"userid"`
			Op     int    `json:"op"`
		}
		if err := json.Unmarshal([]byte(cmd.Detail), &tmp); err == nil {
			//only deal with unbinding account
			if tmp.Op == 2 {
				//todo
				log.Println(log.DebugLog, "//todo wait server give binduser check api!")
				return
				storage.Config_set(MODULE_CONTROLLER, SQL_KEY_BINDUSER, "")
				BindUser = ""
				SendUUIDToVE()
				log.Println(log.DebugLog, "Unbind user account!")
			} else {
				log.Println(log.DebugLog, "Bind user account!")
			}
		} else {
			log.Println(log.DebugLog, "Decode data err!", err)
		}

	case YxSCmd_UploadLog:
		log.Println(log.DebugLog, "Upload log!")
		var tmp struct {
			FeedbackId int64 `json:"feedbackId"`
			Type       int64 `json:"type"`
		}

		if err := json.Unmarshal([]byte(cmd.Detail), &tmp); err == nil {
			UploadLog(tmp.Type, tmp.FeedbackId)
		} else {
			log.Println(log.DebugLog, "Decode data err!", err)
		}

	case YxSCmd_HeartListChange:
		log.Println(log.DebugLog, "YxSCmd_HeartListChange do nothing!")
	case YxSCmd_HeartSongChange:
		var tmp struct {
			Op int `json:"op"`
		}

		if err := json.Unmarshal([]byte(cmd.Detail), &tmp); err == nil {
			log.Println(log.DebugLog, "YxSCmd_HeartSongChange operation:", tmp)
			switch tmp.Op {
			case 1: //add
				MscToastTts("已收藏", CONST_AUDIO_ID, false, false, func(params *schedule.NoticePlayerParams) {
					tmpfunc := params.BeforeExecFunc
					params.BeforeExecFunc = func() {
						if tmpfunc != nil {
							tmpfunc()
						}

						player.SoundEffectPlayCmd(CMD_SE_PLAY, vui.SoundNotice_Scaozuofankui001.GetPath())
						time.Sleep(100 * time.Millisecond)
					}
					params.BeforeSpecialFunc = nil

					params.IconIn = vui.IconLed_IconChaozuo005
					params.IconOut = vui.IconLed_DoNothing
				})

			case 2: //cancel
				MscToastTts("已取消收藏", CONST_AUDIO_ID, false, false, func(params *schedule.NoticePlayerParams) {
					tmpfunc := params.BeforeExecFunc
					params.BeforeExecFunc = func() {
						if tmpfunc != nil {
							tmpfunc()
						}

						player.SoundEffectPlayCmd(CMD_SE_PLAY, vui.SoundNotice_Scaozuofankui001.GetPath())
						time.Sleep(100 * time.Millisecond)
					}
				})

			default:
				log.Println(log.DebugLog, "Unknow!!", tmp.Op)
			}
		} else {
			log.Println(log.DebugLog, "Decode data err!", err)
		}

	case YxSCmd_ChangeAccountMode:
		log.Println(log.DebugLog, "Change account mode!")

		schedule.SendSCmdStruct(schedule.SCmdStruct{SCmd: schedule.SCMD_MusicPlayer_Pause, Arg: []interface{}{schedule.PlayerArg{NotShowIcon: true}}, ExecCb: func(cb schedule.SCmdStructExecCb) {
			tmp := GetCurVboxBroadcastSt(false)
			tmp.PlayerStPtr.ContinuousTaskSt = MUSIC_ST_IDLE
			TrigBroadcastStatus(tmp)
			player.ResetWifiPlayer()
		}})

	default:
		log.Println(log.DebugLog, "Unknow server sysmsg cmd:", cmd.CmdId)
		//player.NoticePlayerSendSCmd(schedule.SCMD_SuperTask_Tts_Play, fmt.Sprintln("出现错误, 未知服务端命令: ", cmd.CmdId), AdSrcType_TTS, TTS_LEVEL_1, false, false)
	}
}

func createTopList(songDetail *SongInfoDetail) *ServerMusicList {
	if nil == songDetail {
		return nil
	}
	var tmp ServerMusicList

	tmp.MusicList.Type = SINGLE_SONG
	tmp.MusicList.Id = ""
	tmp.MusicList.Index = 0
	tmp.MusicList.Url = songDetail.Url
	tmp.MusicList.SongList = make([]SongInfo, 1)

	tmp.MusicList.SongList[0] = songDetail.SongInfo
	tmp.MusicList.SongList[0].Single = true

	tmp.PlayMode = MODE_NULL
	tmp.MusicList.Gain = songDetail.Gain

	return &tmp
}
