package controller

/*
#include <uvdbus/smart_sound.h>
*/
import "C"
import (
	"encoding/json"
	"netease_control_center/globals"
	"netease_control_center/interfaces"
	"netease_control_center/interfaces/http"
	"netease_control_center/interfaces/log"
	"netease_control_center/interfaces/schedule"
	"strconv"
	"strings"
	"time"
)

var (
	alarmCtrlMsg         *string = nil
	alarmCtrlUuid        *string = nil
	remindCtrlMsg        *string = nil
	remindCtrlUuid       *string = nil
	deleteRemindsCtrlMsg *string = nil
	deleteRemindCtrlUuid *string = nil
	deleteAlarmsCtrlMsg  *string = nil
	deleteAlarmCtrlUuid  *string = nil
)

func DbusRefleshSceneAlarm() {
	var req http.HttpReqRefreshScene
	var res http.HttpRspRefreshScene

	if code, _, err := http.HttpPostAuto(req, &res); code == 1000 && err == nil {
		var tmpres struct {
			Data *http.HttpRspRefreshScene `json:"data"`
		}
		tmpres.Data = &res
		if data, err := json.Marshal(tmpres); err == nil {
			interfaces.SendCommand(globals.MODULE_CONTROLLER, globals.MODULE_ALARM, uint32(C.CMD_SESSION_ALARM_SYNC), &data)
		} else {
			log.Println(log.DebugLog, "Json encode err ", err)
		}
	} else {
		log.Println(log.DebugLog, "Http req scene alarm fail ", code, err)
	}
}

func DbusRefleshAlarmClocks() {
	var req http.HttpReqGetRefleshedAlarmList
	var res http.HttpRspGetRefleshedAlarmList

	if code, _, err := http.HttpPostAuto(req, &res); code == 1000 && err == nil {
		if data, err := json.Marshal(res); err == nil {
			interfaces.SendCommand(globals.MODULE_CONTROLLER, globals.MODULE_ALARM, uint32(C.CMD_ALARM_SYNC_RSP), &data)
		} else {
			log.Println(log.DebugLog, "Json encode err ", err)
		}
	} else {
		log.Println(log.DebugLog, "Http req alarm fail ", code, err)
	}
}

func DbusRefleshReminds() {
	var req http.HttpReqRefreshReminds
	var res http.HttpRspRefreshReminds

	if code, _, err := http.HttpPostAuto(req, &res); code == 1000 && err == nil {
		if data, err := json.Marshal(res); err == nil {
			log.Println(log.DebugLog, "will send remind:", string(data))
			interfaces.SendCommand(globals.MODULE_CONTROLLER, globals.MODULE_ALARM, uint32(C.CMD_REMAIND_SYNC_RSP), &data)
		} else {
			log.Println(log.DebugLog, "Json encode err ", err)
		}
	} else {
		log.Println(log.DebugLog, "Http req alarm fail ", code, err)
	}
}

func TellServerAlarmClockRing(id uint64, tts string) {
	var req http.HttpReqAlarmClockRing
	var res http.HttpRspAlarmClockRing

	req.Id = id
	req.InformType = 101
	req.Tts = tts

	if code, _, err := http.HttpPostAuto(req, &res); code == 1000 && err == nil {
		log.Println(log.DebugLog, "has told server alarm ring, id:", id)
	} else {
		log.Println(log.DebugLog, "Http tells alarm fail ", code, err, id)
	}
}

func TellServerRemindRing(id uint64, tts string) {
	var req http.HttpReqRemindRing
	var res http.HttpRspRemindRing

	req.Id = id
	req.InformType = 102
	req.Tts = tts

	if code, _, err := http.HttpPostAuto(req, &res); code == 1000 && err == nil {
		log.Println(log.DebugLog, "has told server remind ring, id:", id)
	} else {
		log.Println(log.DebugLog, "Http tells remind ring fail ", code, err, id)
	}
}

func DbusSendAlarmClocks(alarmclocks []globals.AlarmClockInfo) error {
	var tmp globals.DbusAlarmClockInfo
	tmp.Data = alarmclocks
	if data, err := json.Marshal(tmp); err == nil {
		interfaces.SendCommand(globals.MODULE_CONTROLLER, globals.MODULE_ALARM, uint32(C.CMD_ALARM_SYNC_RSP), &data)
		return nil
	} else {
		log.Println(log.DebugLog, "Json encode err ", err)
		return err
	}
}

func DbusSendAlarmClock(alarmclock globals.AlarmClockInfo) error {
	var tmp globals.DbusAlarmClockInfo
	alarmclockarry := make([]globals.AlarmClockInfo, 1)
	alarmclockarry[0] = alarmclock
	tmp.Data = alarmclockarry
	log.Printf(log.DebugLog, "Set alarm %#v\n", alarmclock)
	if data, err := json.Marshal(tmp); err == nil {
		interfaces.SendCommand(globals.MODULE_CONTROLLER, globals.MODULE_ALARM, uint32(C.CMD_ALARM_ADD), &data)
		return nil
	} else {
		log.Println(log.DebugLog, "Json encode err ", err)
		return err
	}
}

func DbusSendRemind(remind globals.RemindInfo) error {
	var tmp globals.DbusRemindInfo
	remindarry := make([]globals.RemindInfo, 1)
	remindarry[0] = remind
	tmp.Data = remindarry
	log.Printf(log.DebugLog, "Set alarm %#v\n", remind)
	if data, err := json.Marshal(tmp); err == nil {
		interfaces.SendCommand(globals.MODULE_CONTROLLER, globals.MODULE_ALARM, uint32(C.CMD_REMAIND_ADD), &data)
		return nil
	} else {
		log.Println(log.DebugLog, "Json encode err ", err)
		return err
	}
}

func DbusDelAlarmClocks(ids string) {
	idsstring := strings.Split(ids, ",")
	if len(idsstring) == 0 {
		return
	}

	idsint := make([]uint64, len(idsstring))
	for k, v := range idsstring {
		idsint[k], _ = strconv.ParseUint(v, 10, 64)
	}

	DbusDelAlarmClocksArray(idsint)
}

func DbusDelAlarmClocksArray(alarmarr []uint64) {
	var tmp globals.DbusDelAlarms
	tmp.Type = globals.AlarmType_AlarmClock
	tmp.Ids = alarmarr

	if data, err := json.Marshal(tmp); err == nil {
		interfaces.SendCommand(globals.MODULE_CONTROLLER, globals.MODULE_ALARM, uint32(C.CMD_ALARM_REMOVE), &data)
	} else {
		log.Println(log.DebugLog, "json error ", err)
	}
}

func DbusDelAllAlarmClocks() {
	interfaces.JustSendBusCmd(globals.MODULE_CONTROLLER, globals.MODULE_ALARM, uint32(C.CMD_ALARM_REMOVEALL))
}

func DbusDelRemindsArray(remindarr []uint64) {
	var tmp globals.DbusDelAlarms
	tmp.Type = globals.AlarmType_Alert
	tmp.Ids = remindarr

	if data, err := json.Marshal(tmp); err == nil {
		interfaces.SendCommand(globals.MODULE_CONTROLLER, globals.MODULE_ALARM, uint32(C.CMD_REMAIND_REMOVE), &data)
	} else {
		log.Println(log.DebugLog, "json error ", err)
	}
}
func DbusDelAllReminds() {
	interfaces.JustSendBusCmd(globals.MODULE_CONTROLLER, globals.MODULE_ALARM, uint32(C.CMD_REMAIND_REMOVEALL))
}

func TellServerDelAlarmClocksUintArray(arr []uint64) {
	if len(arr) == 0 {
		return
	}

	issstring := make([]string, len(arr))
	for k, v := range arr {
		issstring[k] = strconv.FormatUint(v, 10)
	}
	arg := strings.Join(issstring, ",")

	var req http.HttpReqMultiDelAlarms
	var res http.HttpRspMultiDelAlarms
	req.Ids = arg

	http.HttpPostAuto(req, &res)
}

func TellServerDelRemindsUintArray(arr []uint64) {
	if len(arr) == 0 {
		return
	}

	issstring := make([]string, len(arr))
	for k, v := range arr {
		issstring[k] = strconv.FormatUint(v, 10)
	}
	arg := strings.Join(issstring, ",")

	var req http.HttpReqBatchDeleteReminds
	var res http.HttpRspBatchDeleteReminds
	req.Ids = arg

	http.HttpPostAuto(req, &res)
}

func UpdateServerAlarmClockStatus(ids []uint64) {
	idstring := make([]string, len(ids))
	for k, v := range ids {
		idstring[k] = strconv.FormatUint(v, 10)
	}

	tobesent := strings.Join(idstring, ",")
	var req http.HttpReqUpdateAlarmClocks
	var res http.HttpRspUpdateAlarmClocks
	req.Ids = tobesent
	//by server asked set 2 = confirmed
	req.Status = 2
	//todo req.status ???
	http.HttpPostAuto(req, &res)
}

func UpdateServerRemindsStatus(ids []uint64) {
	idstring := make([]string, len(ids))
	for k, v := range ids {
		idstring[k] = strconv.FormatUint(v, 10)
	}

	tobesent := strings.Join(idstring, ",")
	var req http.HttpReqBatchUpdateReminds
	var res http.HttpRspBatchUpdateReminds
	req.Ids = tobesent
	req.Status = 2
	//todo req.status ???
	http.HttpPostAuto(req, &res)
}

func SendHolidayinfo(year uint32) {
	var req http.HttpReqGetHoliday
	var res http.HttpRspGetHoliday
	req.Year = year

	if code, _, err := http.HttpPostAuto(req, &res); code == 1000 && err == nil {
		if data, err := json.Marshal(res); err == nil {
			interfaces.SendCommand(globals.MODULE_CONTROLLER, globals.MODULE_ALARM, uint32(C.CMD_WORKDAY_DB_RSP), &data)
		} else {
			log.Println(log.DebugLog, "Json encode err ", err)
		}
	} else {
		log.Println(log.DebugLog, "Http req holiday fail ", code, err)
	}
}

func DbusAlarmCmdDeal(buscmd uint32, data []byte) {
	log.Println(log.DebugLog, "In alarm module buscmd:", buscmd, " data:", string(data))
	switch buscmd {
	case uint32(C.CMD_WORKDAY_DB_REQ):
		if globals.InternetConnect == true {
			var tmp struct {
				Year uint32 `json:"year"`
			}
			if err := json.Unmarshal(data, &tmp); err == nil {
				SendHolidayinfo(tmp.Year)
			} else {
				log.Println(log.DebugLog, "json decode err:", err)
			}
		}

	case uint32(C.CMD_ALARM_SYNC_REQ):
		if globals.InternetConnect == true {
			DbusRefleshAlarmClocks()
		}

	case uint32(C.CMD_REMAIND_SYNC_REQ):
		if globals.InternetConnect == true {
			DbusRefleshReminds()
		}

	case uint32(C.CMD_ASSISTANT_NOTIFY):
		var tmp struct {
			CmdId uint32            `json:"cmd"`
			Type  globals.AlarmType `json:"type"`
			Ids   []uint64          `json:"ids"`
		}

		if err := json.Unmarshal(data, &tmp); err == nil {
			switch tmp.CmdId {
			case uint32(C.CMD_ALARM_REMOVEALL):
				if deleteAlarmsCtrlMsg != nil && nil != deleteAlarmCtrlUuid {
					MscToastTts(*deleteAlarmsCtrlMsg, *deleteAlarmCtrlUuid, true, false, nil)
					//player.NoticePlayerSendSCmd(schedule.SCMD_SuperTask_Tts_Play, *deleteAlarmsCtrlMsg, *deleteAlarmCtrlUuid,
					//	globals.AdSrcType_TTS, globals.TTS_LEVEL_1, true, false)
					deleteAlarmsCtrlMsg = nil
					deleteAlarmCtrlUuid = nil
				} else {
					MscToastTts(globals.TTS_REMOVE_ALARM_ALL, globals.CONST_AUDIO_ID, false, false, nil)
					//player.NoticePlayerSendSCmd(schedule.SCMD_SuperTask_Tts_Play, globals.TTS_REMOVE_ALARM_ALL, globals.CONST_AUDIO_ID,
					//	globals.AdSrcType_TTS, globals.TTS_LEVEL_1, true, false)
				}

				DbusRefleshAlarmClocks()

			case uint32(C.CMD_REMAIND_REMOVEALL):
				if deleteRemindsCtrlMsg != nil && nil != deleteRemindCtrlUuid {
					MscToastTts(*deleteRemindsCtrlMsg, *deleteRemindCtrlUuid, true, false, nil)
					//player.NoticePlayerSendSCmd(schedule.SCMD_SuperTask_Tts_Play, *deleteRemindsCtrlMsg, *deleteRemindCtrlUuid,
					//	globals.AdSrcType_TTS, globals.TTS_LEVEL_1, true, false)
					deleteRemindsCtrlMsg = nil
					deleteRemindCtrlUuid = nil
				} else {
					MscToastTts(globals.TTS_REMOVE_REMIND_ALL, globals.CONST_AUDIO_ID, false, false, nil)

					//player.NoticePlayerSendSCmd(schedule.SCMD_SuperTask_Tts_Play, globals.TTS_REMOVE_REMIND_ALL, globals.CONST_AUDIO_ID,
					//	globals.AdSrcType_TTS, globals.TTS_LEVEL_1, true, false)
				}
				DbusRefleshReminds()

			case uint32(C.CMD_ALARM_ADD):
				if nil != alarmCtrlMsg && nil != alarmCtrlUuid {
					MscToastTts(*alarmCtrlMsg, *alarmCtrlUuid, true, false, nil)

					//player.NoticePlayerSendSCmd(schedule.SCMD_SuperTask_Tts_Play, *alarmCtrlMsg, *alarmCtrlUuid,
					//	globals.AdSrcType_TTS, globals.TTS_LEVEL_1, true, false)
					alarmCtrlMsg = nil
					alarmCtrlUuid = nil
				} else {
					log.Println(log.ErrorLog, "toast msg maybe nil, do not play", alarmCtrlMsg, alarmCtrlUuid)
				}
				UpdateServerAlarmClockStatus(tmp.Ids)

			case uint32(C.CMD_ALARM_REMOVE):
				if nil != alarmCtrlMsg && nil != alarmCtrlUuid {
					MscToastTts(*alarmCtrlMsg, *alarmCtrlUuid, true, false, nil)

					//player.NoticePlayerSendSCmd(schedule.SCMD_SuperTask_Tts_Play, *alarmCtrlMsg, *alarmCtrlUuid,
					//	globals.AdSrcType_TTS, globals.TTS_LEVEL_1, true, false)
					alarmCtrlMsg = nil
					alarmCtrlUuid = nil
				}
				TellServerDelAlarmClocksUintArray(tmp.Ids)

			case uint32(C.CMD_REMAIND_ADD):
				if remindCtrlMsg != nil && nil != remindCtrlUuid {
					MscToastTts(*remindCtrlMsg, *remindCtrlUuid, true, false, nil)

					//player.NoticePlayerSendSCmd(schedule.SCMD_SuperTask_Tts_Play, *remindCtrlMsg, *remindCtrlUuid,
					//	globals.AdSrcType_TTS, globals.TTS_LEVEL_1, true, false)
					remindCtrlMsg = nil
					remindCtrlUuid = nil
				}
				UpdateServerRemindsStatus(tmp.Ids)

			case uint32(C.CMD_REMAIND_REMOVE):
				if remindCtrlMsg != nil && nil != remindCtrlUuid {
					MscToastTts(*remindCtrlMsg, *remindCtrlUuid, true, false, nil)

					//player.NoticePlayerSendSCmd(schedule.SCMD_SuperTask_Tts_Play, *remindCtrlMsg, *remindCtrlUuid,
					//	globals.AdSrcType_TTS, globals.TTS_LEVEL_1, true, false)
					remindCtrlMsg = nil
					remindCtrlUuid = nil
				}
				TellServerDelRemindsUintArray(tmp.Ids)
			}
		} else {
			log.Println(log.DebugLog, "json err:", err)
		}

	case uint32(C.CMD_ASSISTANT_RUNNING):
		log.Println(log.DebugLog, "Alarm/Agency running....")
		var tmp struct {
			Data []globals.DbusAlarmRemind `json:"data"`
		}
		if err := json.Unmarshal(data, &tmp); err == nil {
			log.Println(log.DebugLog, tmp)
			if len(tmp.Data) > 0 {
				tmp.Data[0].ComingTime = time.Now().Local()
				tmp.Data[0].SCmdTime = time.Now()
				switch tmp.Data[0].Type {
				case 0:
					//alarm
					time.Sleep(50 * time.Millisecond)
					schedule.SendSCmd(schedule.SCMD_SuperTask_Alarm_Ring, tmp.Data[0])
					go TellServerAlarmClockRing(tmp.Data[0].Id, alarmVui(0))

				case 1:
					//remind
					schedule.SendSCmd(schedule.SCMD_SuperTask_Remind_Ring, tmp.Data[0])
				case 2:
					//scene alarm
					EnterAlarmScene(tmp.Data[0].Tts)
				}
			}
		} else {
			log.Println(log.DebugLog, "Decode alarm module data err!", err)
		}

	}
}

func MakeAlarmDataTest() {
	var alarmarr []globals.AlarmClockInfo

	for i := 0; i < 7; i++ {
		var alarm globals.AlarmClockInfo
		alarm.Id = uint64(i)
		alarm.Type = i + 1
		//alarm.AlarmTime = uint64(time.Now().UTC().Add(time.Duration(i+2)*time.Second).Unix() * 1000)
		alarmarr = append(alarmarr, alarm)
	}
	log.Println(log.DebugLog, "Send alarms")
	log.Printf(log.DebugLog, "%#v", alarmarr)
	DbusSendAlarmClocks(alarmarr)
}
