package controller

import (
	"context"
	"fmt"
	"netease_control_center/globals"
	"netease_control_center/interfaces/http"
	"netease_control_center/interfaces/log"
	. "netease_control_center/interfaces/schedule"
	"netease_control_center/utils"
	"sort"
	"strconv"
	"time"
)

var (
	curtaskno                                        = -1
	scenetast_remind_ctx, scenetast_remind_ctxcancel = context.WithCancel(context.Background())
)

type Sremind_info struct {
	Time   time.Time
	Remark string
}

type Sremind_infos []Sremind_info

func (c Sremind_infos) Len() int {
	return len(c)
}
func (c Sremind_infos) Swap(i, j int) {
	c[i], c[j] = c[j], c[i]
}
func (c Sremind_infos) Less(i, j int) bool {
	return c[i].Time.Before(c[j].Time)
}

func init() {
	RegisteSceneTask_Remind()
}

func registeSceneTask_Remind_Play(startType PlayerStartType, position int, hd SSceneHd, taskno int) {
	curtaskno = taskno
	scenetast_remind_ctxcancel()
	scenetast_remind_ctx, scenetast_remind_ctxcancel = context.WithCancel(*(hd.GetCtx()))

	var req http.HttpReqRefreshReminds
	var res http.HttpRspRefreshReminds

	if code, _, err := http.HttpPostAuto(req, &res); code == 1000 && err == nil {
		var tmp Sremind_infos
		for _, v := range res.RemindsList {
			switch v.Type {
			case globals.RemindInfo_Type_Once, globals.RemindInfo_Type_EveryDay:
				goto _storage

			case globals.RemindInfo_Type_WorkDay:
				if time.Monday <= time.Now().Weekday() && time.Now().Weekday() <= time.Friday {
					goto _storage
				}

			case globals.RemindInfo_Type_Weekend:
				if time.Now().Weekday() == time.Saturday || time.Now().Weekday() == time.Sunday {
					goto _storage
				}

			case globals.RemindInfo_Type_EveryWeek:
				if utils.StringContainsIntNumber(v.VboxDate.DayofWeek, ",", int(time.Now().Weekday())) == true {
					goto _storage
				} else {
					log.Println(log.DebugLog, "week not match!")
				}

			case globals.RemindInfo_Type_EveryMonth:
				if utils.StringContainsIntNumber(v.VboxDate.Month, ",", int(time.Now().Month())) == true {
					if utils.StringContainsIntNumber(v.VboxDate.DayofMonth, ",", int(time.Now().Day())) == true {
						goto _storage
					} else {
						log.Printf(log.DebugLog, "day not match!%+v\n", v)
					}
				} else {
					log.Printf(log.DebugLog, "Month not match:%+v\n", v)
				}

			case globals.RemindInfo_Type_EveryYear:
				if utils.StringContainsIntNumber(v.VboxDate.Year, ",", time.Now().Year()) == true {
					if utils.StringContainsIntNumber(v.VboxDate.Month, ",", int(time.Now().Month())) == true {
						if utils.StringContainsIntNumber(v.VboxDate.DayofMonth, ",", int(time.Now().Day())) == true {
							goto _storage
						} else {
							log.Printf(log.DebugLog, "day not match!%+v\n", v)
						}
					} else {
						log.Printf(log.DebugLog, "Month not match:%+v\n", v)
					}
				} else {
					log.Printf(log.DebugLog, "Year not match!%+v\n", v)
				}
			default:
				continue
			}
			continue
		_storage:
			var tmpsremind_info Sremind_info
			nw := time.Now().Local()
			hour, _ := strconv.Atoi(v.VboxDate.Hour)
			minute, _ := strconv.Atoi(v.VboxDate.Minute)
			second, _ := strconv.Atoi(v.VboxDate.Second)
			tmpsremind_info.Time = time.Date(nw.Year(), nw.Month(), nw.Day(), hour, minute, second, 0, nw.Location())
			log.Printf(log.DebugLog, "\n%+v\n", tmpsremind_info)
			tmpsremind_info.Remark = v.Remark
			tmp = append(tmp, tmpsremind_info)
		}
		sort.Sort(tmp)
		log.Printf(log.DebugLog, "Get final list:%+v", tmp)
		if len(tmp) > 0 {
			var playtts string
			for k, v := range tmp {
				if k < 999 {
					if len(v.Remark) > 0 {
						playtts += fmt.Sprintln("将在", v.Time.Local().Format("15点04分"), "提醒您", v.Remark, ",")
					} else {
						playtts += fmt.Sprintln("在", v.Time.Local().Format("15点04分"), "有一个提醒", ",")
					}
				}
			}
			PlayNoticeAsync(globals.AdSrcType_TTS, playtts, globals.CONST_AUDIO_ID, true, scenetast_remind_ctx, func(id uint32, reason NoticeStopReason) {
				log.Println(log.DebugLog, "Notice exit:", reason)
				hd.Finish(taskno, false)
			})
		} else {
			//PlayNoticeAsync(globals.AdSrcType_TTS, "今天没有提醒", true, scenetast_remind_ctx, func(id uint32, reason NoticeStopReason) {
			//	log.Println(log.DebugLog, "Notice exit:", reason)
			//	hd.Finish(taskno, false)
			//})

			go hd.Finish(taskno, false)
		}
	} else {
		log.Println(log.DebugLog, "request server err for remind:", code, err)
		go hd.Finish(taskno, true)
	}
}

func RegisteSceneTask_Remind() {
	var tmp RegistedSceneTask
	tmp.GetType = func() SStaskType {
		return SStaskType_Once
	}

	tmp.GetId = func() SSTaskId {
		return SSTaskId_PlayNotices
	}

	tmp.PlayNext = func(hd SSceneHd) {
		hd.Finish(curtaskno, true)
	}

	tmp.PlayPre = func(hd SSceneHd) {
		hd.Finish(curtaskno, true)
	}

	tmp.Play = registeSceneTask_Remind_Play

	tmp.Pause = func(hd SSceneHd) {
		scenetast_remind_ctxcancel()
		log.Println(log.DebugLog, "Pause, Do nothing! depend on ctx!")
	}

	tmp.Stop = func(hd SSceneHd) {
		scenetast_remind_ctxcancel()
		log.Println(log.DebugLog, "Stop, Do nothing! depend on ctx")
	}

	if err := RegisteSceneTask(tmp); err == nil {
		scenetast_remind_ctxcancel()
		log.Println(log.DebugLog, "Begin to registe scene task remind success!")
	}
}
