package gameapi

import (
	"../log"
	"../mod"
	"../nt"
	pb "../protos"
	"encoding/json"
	"go.uber.org/zap"
	"strconv"
	"time"
)

/*
	游戏每日任务
*/

const (
	TASK_ALL_FINISHED = 0 //所有任务都已完成
	TASK_FINISHED     = 1 //任务已完成
	TASK_UNFINISHED   = 2 //任务未完成
)

type TaskHeader struct {
	Tasks     []Gametask `json:"tasks"`
	Guid      uint64     `json:"guid"`
	ValidDate string     `json:"validDate"` //有效日期
}

type Gametask struct {
	TaskId    int      `json:"taskId"` //任务ID
	GameId    int      `json:"gameId"`
	GameParam []string `json:"gameParam"`
	Name      string   `json:"name"`     //任务名称
	Target    int      `json:"target"`   //任务目标局数
	Finished  int      `json:"finished"` //已完成的局数
	Received  int      `json:"received"` //待领取次数
	Reward    int64    `json:"reward"`   //奖励金币
	State     int      `json:"state"`    //领取状态
	Limit     int64    `json:"limit"`    //玩家进入游戏 有限制
	Total     int      `json:"total"`    //总共已完成的局数
}

//获取游戏任务
func GetGameTaskByGuid(guid uint64, task *TaskHeader) bool {

	jsons, err := mod.GetGameTask(strconv.FormatUint(guid, 10))
	if err != nil {
			log.Debug("getGameTaskByGuid mod.GetGameTask err", zap.Uint64("guid", guid), zap.Error(err))
			return false
	}

	if len(jsons) == 0 { //初始化玩家 每日游戏任务
		if !resetGameTask(guid, task) {
			log.Debug("init user gametask failed")
			return false
		} else {
			log.Debug("init user gametask success")
			return true
		}
	}

	if err := json.Unmarshal([]byte(jsons), task); err != nil {
		log.Debug("getGameTaskByGuid json.Unmarshal err", zap.Error(err))
		return false
	}

	if !isToday(task.ValidDate) { //跨天清任务

		if !resetGameTask(guid, task) {
			return false
		}

	} else {
		if !UpdateGameTaskByChange(guid, task) {
			return false
		}
	}

	return true
}

func UpdateGameTaskByChange(guid uint64, task *TaskHeader) bool {

	newTask := nt.DynConf.GameTasks //动态配置
	//配置修改了
	//for i := 0; i< len(newTask); i++ {
	//	for j := 0; j< len(task.Tasks); j++ {
	//		if newTask[i].TaskId == int32(task.Tasks[j].TaskId) {
	//			if task.Tasks[j].Received < int(newTask[i].Received) {
	//
	//			}
	//			task.Tasks[j].Received = int(newTask[i].Received)
	//			task.Tasks[j].Limit = newTask[i].Limit
	//			task.Tasks[j].Name = newTask[i].Name
	//			task.Tasks[j].Reward = newTask[i].Reward
	//			task.Tasks[j].GameParam = newTask[i].GameParam
	//			task.Tasks[j].GameId = int(newTask[i].GameId)
	//			task.Tasks[j].Target = int(newTask[i].Target)
	//		}
	//	}
	//}
	//添加新的配置
	var newTaskArr []Gametask //暂时保存的游戏任务
	for i := 0; i < len(newTask); i++ {

		hasExisted := false
		for j := 0; j < len(task.Tasks); j++ {
			if newTask[i].TaskId == int32(task.Tasks[j].TaskId) {
				hasExisted = true //已存在 就不添加
				break
			}
		}

		if !hasExisted {
			var item Gametask
			item.TaskId = int(newTask[i].TaskId)
			item.Received = int(newTask[i].Received)
			item.Limit = newTask[i].Limit
			item.Name = newTask[i].Name
			item.Reward = newTask[i].Reward
			item.GameParam = newTask[i].GameParam
			item.GameId = int(newTask[i].GameId)
			item.State = int(newTask[i].State)
			item.Finished = int(newTask[i].Finished)
			item.Target = int(newTask[i].Target)
			newTaskArr = append(newTaskArr, item)
		}
	}

	for n := 0; n < len(newTaskArr); n++ {
		task.Tasks = append(task.Tasks, newTaskArr[n])
		log.Debug("UpdateGameTaskByChange new task", zap.Uint64("Guid", guid), zap.Any("newtask", newTaskArr[n]))
	}

	taskJson, err := json.Marshal(task)
	if err != nil {
		log.Debug("UpdateGameTaskByChange json.Marshal err", zap.Uint64("Guid", guid), zap.Error(err))
		return false
	}
	if err := mod.UpdateGameTask(strconv.FormatUint(guid, 10), taskJson); err != nil {
		log.Error("UpdateGameTaskByChange mod.UpdateGameTask err", zap.Uint64("Guid", guid), zap.Error(err))
		return false
	}

	return true
}

//是否是当天
func isToday(date string) bool {
	if time.Now().Format("2006-01-02") == date {
		return true
	} else {
		return false
	}
}

//隔天清空任务
func resetGameTask(guid uint64, task *TaskHeader) bool {

	conf := nt.DynConf.GameTasks //从动态配置里面取
	task.ValidDate = time.Now().Format("2006-01-02")
	task.Guid = guid

	var taskArr []Gametask
	for i := 0; i < len(conf); i++ { //load入场限制
		var item Gametask
		gameConf, has := FindGameConfBygameId(int64(conf[i].GameId)) //查找游戏配置
		if !has {
			log.Debug("resetGameTask null,please check conf of gameTask",zap.Int32("gameid",conf[i].GameId), zap.Any("gameParam", conf[i].GameParam))
		}
		item.Limit = gameConf.GetMinLimit()
		item.Reward = conf[i].Reward
		item.Received = int(conf[i].Received)
		item.Finished = int(conf[i].Finished)
		item.Target = int(conf[i].Target)
		item.TaskId = int(conf[i].TaskId)
		item.Name = conf[i].Name
		item.State = TASK_UNFINISHED
		item.GameParam = conf[i].GameParam
		item.GameId = int(conf[i].GameId)
		item.Total = 0 //已完成的总局数
		taskArr = append(taskArr, item)
	}

	task.Tasks = taskArr

	taskJson, err := json.Marshal(task)
	if err != nil {
		log.Debug("cleanGameTask json.Marshal err", zap.Uint64("Guid", guid), zap.Error(err))
		return false
	}
	if err := mod.UpdateGameTask(strconv.FormatUint(guid, 10), taskJson); err != nil {
		log.Error("cleanGameTask mod.UpdateGameTask err", zap.Uint64("Guid", guid), zap.Error(err))
		return false
	}
	return true
}

//加钱
func addMoneyByReward(guid uint64, amount int64) (newBlance int64, b bool) {

	balance, err := mod.GetUserAttr(guid, "balance")
	if err != nil {
		log.Error("addMoneyByReward mod.GetUserAttr err", zap.Uint64("guid", guid), zap.Int64("amount", amount))
		return 0, false
	}

	oldBalance, err := strconv.ParseInt(balance, 10, 64)
	if err != nil {
		log.Error("addMoneyByReward strconv.ParseInt err", zap.Uint64("guid", guid), zap.Int64("amount", amount))
		return 0, false
	}
	log.Debug("redis update balance", zap.Int64("oldbalance", oldBalance))
	newBalance, err := mod.AddUserBalance(guid, amount)
	log.Debug("redis update balance", zap.Int64("newBalance", newBalance))
	if err != nil {
		log.Error("addMoneyByReward mod.AddUserBalance err", zap.Uint64("guid", guid), zap.Int64("amount", amount))
		return 0, false
	}

	log.Info("gameTask addMoneyByReward success", zap.Uint64("guid", guid), zap.Int64("oldBalance", oldBalance), zap.Int64("newBalance", newBalance))
	return newBalance, true
}

//更新玩家的游戏任务数据 下分时返回统计数据
func UpdateReward(guid uint64, validDate string, taskMap map[string]int) {

	log.Debug("UpdateReward", zap.Uint64("guid", guid), zap.Any("taskMap", taskMap))
	var taskList TaskHeader
	if !isToday(validDate) { //跨天清任务
		if !resetGameTask(guid, &taskList) {
			return
		}
	} else {
		if !GetGameTaskByGuid(guid, &taskList) {
			log.Debug("UpdateReward failed")
			return
		}
	}

	for k, v := range taskMap {
		for i := 0; i < len(taskList.Tasks); i++ {
			if strconv.FormatInt(int64(taskList.Tasks[i].TaskId), 10) == k && taskList.Tasks[i].State != TASK_ALL_FINISHED {
				taskList.Tasks[i].Finished += v - taskList.Tasks[i].Total
				if taskList.Tasks[i].Finished >= taskList.Tasks[i].Target {
					taskList.Tasks[i].State = TASK_FINISHED
				}
				taskList.Tasks[i].Total = v
				log.Debug("task add finished", zap.Any("task", taskList.Tasks[i]))
				break
			}
		}
	}

	jsons, err := json.Marshal(taskList)
	if err != nil {
		log.Debug("receiveReward json.Marshal err", zap.Uint64("guid", guid), zap.Any("taskList", taskList))
		return
	}

	if err := mod.UpdateGameTask(strconv.FormatUint(guid, 10), jsons); err != nil {
		log.Error("receiveReward UpdateGameTask err", zap.Uint64("guid", guid), zap.Any("taskList", taskList))
		return
	}

}

//领取奖励
func ReceiveReward(guid uint64, TaskId int, task *pb.GameTask) (newBlance int64, reward int64, b bool) {

	log.Debug("receiveReward", zap.Uint64("guid", guid), zap.Int("taskId", TaskId))
	var taskList TaskHeader
	if !GetGameTaskByGuid(guid, &taskList) {
		return 0, 0, false
	}

	var item *Gametask
	for i := 0; i < len(taskList.Tasks); i++ {
		if taskList.Tasks[i].TaskId == TaskId {
			item = &taskList.Tasks[i]
			break
		}
	}

	if item == nil {
		log.Debug("receiveReward not find task", zap.Uint64("guid", guid), zap.Int("taskId", TaskId))
		return 0, 0, false
	}

	if item.State != TASK_FINISHED { //任务未完成直接返回
		return 0, 0, false
	}

	if item.Finished >= item.Target && item.Received > 0 { // 已完成的任务数 >= 任务目标数 并且 任务完成次数 > 0

		newBlan, isOk := addMoneyByReward(guid, item.Reward)
		if isOk { //加钱

			if item.Received == 1 { //让已完成任务数和目标数一样
				item.Received -= 1
			} else {
				item.Finished -= item.Target
				item.Received -= 1
			}

			if item.Finished >= item.Target {
				if item.Received == 0 {
					item.State = TASK_ALL_FINISHED
					item.Finished = item.Target
				} else {
					item.State = TASK_FINISHED
				}
			} else {
				item.State = TASK_UNFINISHED
			}

			task.TaskId = int32(item.TaskId)
			task.State = int32(item.State)
			task.Target = int32(item.Target)
			task.Finished = int32(item.Finished)
			task.GameId = int32(item.GameId)
			task.GameParam = item.GameParam
			task.Reward = item.Reward
			task.Name = item.Name
			task.Limit = item.Limit
			task.Received = int32(item.Received)
			log.Debug("ReceiveReward task changed ", zap.Any("newtask", task))

			jsons, err := json.Marshal(taskList)
			if err != nil {
				log.Debug("receiveReward json.Marshal err", zap.Uint64("guid", guid), zap.Int("TaskId", TaskId))
				return 0, 0, false
			}

			if err := mod.UpdateGameTask(strconv.FormatUint(guid, 10), jsons); err != nil {
				log.Error("receiveReward UpdateGameTask err", zap.Uint64("guid", guid), zap.Int("TaskId", TaskId))
				return 0, 0, false
			}

			return newBlan, item.Reward, true
		} else { //加钱失败
			return 0, 0, false
		}

	} else {
		return 0, 0, false
	}
}
