package task

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/go-redis/redis/v8"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"log-server/global"
	"log-server/model/log/request"
	"log-server/model/task"
	"log-server/model/task/control"
	request2 "log-server/model/task/request"
	"log-server/model/typeManage"
	"log-server/service/cache"
	"log-server/utils"
	"strconv"
	"strings"
	"time"
)

type SyncData struct {
	GameTask GameTask
	cache    cache.Cache
	common   Common
	Person   typeManage.ResponsiblePerson
}

func (s *SyncData) SyncXmyGameData(date string) (mps map[int]control.XmyPayRequestReplyData, err error) {
	xmyUrl := "http://api.sheepsdk.17xmy.com/foreign/api/get_youhua_data.php"
	xmyParams := map[string]string{
		"start_day": date,
		"end_day":   date,
	}
	requestData := new(control.XmyReply)
	xmyByteData, err := utils.HttpGet(xmyUrl, xmyParams)
	if err != nil {
		return
	}
	_ = json.Unmarshal(xmyByteData, &requestData)
	mps = map[int]control.XmyPayRequestReplyData{}
	for _, data := range requestData.Data.List {
		gameId, _ := strconv.Atoi(data.GameId)
		mps[gameId] = data
	}
	return
}

func (s *SyncData) SyncXmyFreeData(date string, gameId int) (num int, err error) {
	xmyFreeUrl := "http://rtd.kfzs.com/fake.php"
	xmyFreeParams := map[string]string{
		"day":     date,
		"game_id": strconv.Itoa(gameId),
	}
	requestData := new(control.XmyFreeReply)
	xmyByteData, err := utils.HttpGet(xmyFreeUrl, xmyFreeParams)
	if err != nil {
		return
	}
	_ = json.Unmarshal(xmyByteData, &requestData)
	if len(requestData.Data) != 0 {
		num, _ = strconv.Atoi(requestData.Data[0].Num)
	}
	return
}

func (s *SyncData) SyncWslGameData(date string) (mps map[string]int, err error) {
	wslUrl := "http://148.70.251.170/wsl-A/get_sheep_pay.php"
	wslParams := map[string]string{
		"times": date,
	}
	var requestData []control.WslReply
	wslByteData, err := utils.HttpGet(wslUrl, wslParams)
	if err != nil {
		return
	}
	_ = json.Unmarshal(wslByteData, &requestData)
	mps = map[string]int{}
	for _, data := range requestData {
		num, _ := strconv.Atoi(data.Money)
		mps[data.GameId] = num
	}
	return
}

var taskStatistics = "%s:taskStatistics"

func (s *SyncData) SyncRoomData(date string, gameIdInt int) (ts request.TaskStatistics, err error) {
	ctx := context.Background()
	key := fmt.Sprintf(taskStatistics, date)
	gameIdStr := strconv.Itoa(gameIdInt)
	data, err := global.GVA_REDIS.HGet(ctx, key, gameIdStr).Result()
	if err != nil {
		if err == redis.Nil {
			global.GVA_LOG.Info("SyncRoomData not data", zap.Error(err))
		} else {
			global.GVA_LOG.Error("SyncRoomData fail", zap.Error(err))
			return
		}
	}
	_ = json.Unmarshal([]byte(data), &ts)
	return
}

// 获取任务完成数据
func (s *SyncData) CompleteTaskData(date string) (mps map[int]task.GameTargetComplete, err error) {
	db := global.GVA_DB.Table("game_target_complete")
	db = db.Where("create_date = ?", date)
	var apiList []task.GameTargetComplete
	mps = map[int]task.GameTargetComplete{}
	err = db.Order("id desc").Find(&apiList).Error
	for _, api := range apiList {
		mps[api.TaskId] = api
	}
	return
}

// 同步每天的任务基础数据
func (s *SyncData) EveryDaySyncTaskData() {
	db := global.GVA_DB.Model(&task.GameTask{})
	var apiList []task.GameTask
	db = db.Where("is_del = ?", -1)
	db = db.Where("status = ?", 1)
	err := db.Order("id desc").Find(&apiList).Error
	if err != nil {
		global.GVA_LOG.Error("EveryDaySyncTaskData fail", zap.Error(err))
		return
	}
	date := time.Now().Add(+time.Hour * 24)
	var gameTargetCompletes []*task.GameTargetComplete
	for _, gameTask := range apiList {
		if !errors.Is(global.GVA_DB.Where("task_id = ?", gameTask.TaskId).Where("create_date = ?", date).First(&task.GameTargetComplete{}).Error, gorm.ErrRecordNotFound) {
			continue
		}
		gameTargetComplete := s.GameTask.CreateGameTargetCompleteModel(gameTask, date)
		gameTargetCompletes = append(gameTargetCompletes, gameTargetComplete)
	}
	err = global.GVA_DB.Model(&task.GameTargetComplete{}).Omit("update_time", "game_rate", "is_complete").Create(gameTargetCompletes).Error
	if err != nil {
		global.GVA_LOG.Error("create GameTargetComplete fail", zap.Error(err))
		return
	}
	return
}

// 定时同步机房群控、小绵羊数据
func (s *SyncData) SyncTaskData() {
	db := global.GVA_DB.Model(&task.GameTask{})
	var apiList []task.GameTask
	db = db.Where("is_del = ?", -1)
	db = db.Where("status = ?", 1)
	err := db.Order("id desc").Find(&apiList).Error
	if err != nil {
		global.GVA_LOG.Error("EveryDaySyncTaskData fail", zap.Error(err))
		return
	}
	if len(apiList) == 0 {
		global.GVA_LOG.Info("没有任务数据")
		return
	}
	date := time.Now().Format("2006-01-02")
	xmyGameData, err := s.SyncXmyGameData(date)
	if err != nil {
		global.GVA_LOG.Error("SyncTaskData get xmy data fail", zap.Error(err))
		return
	}
	completeTaskData, err := s.CompleteTaskData(date)
	if err != nil {
		global.GVA_LOG.Error("CompleteTaskData get data fail", zap.Error(err))
		return
	}
	wslData, err := s.SyncWslGameData(date)
	if err != nil {
		global.GVA_LOG.Error("SyncWslGameData get wsl data fail", zap.Error(err))
		return
	}
	for _, gameTask := range apiList {
		var gameTarget task.GameTargetComplete
		roomData, _ := s.SyncRoomData(date, gameTask.TaskId)

		if gameTask.GameIdXmy != "" {
			gameIdXmy, _ := strconv.Atoi(gameTask.GameIdXmy)
			xmyGameInfo := xmyGameData[gameIdXmy]
			gameTarget.NewComplete, _ = strconv.Atoi(xmyGameInfo.UserNum)
			gameTarget.PayComplete, _ = strconv.Atoi(xmyGameInfo.Cnt)
			gameTarget.RetainedComplete, _ = strconv.Atoi(xmyGameInfo.ActiveUserNum)
			f, _ := strconv.ParseFloat(xmyGameInfo.Amount, 64)
			gameTarget.Amount = int(f)
			num, _ := s.SyncXmyFreeData(date, gameIdXmy)
			if num != 0 {
				gameTarget.PayTarget = num
				if gameTarget.PayTarget > completeTaskData[gameTask.TaskId].PayTarget {
					lastPayAddUpdateTimeKey := fmt.Sprintf(LastPayAddUpdateTimeKey, date, gameTask.TaskId)
					_ = s.cache.SetCacheStr(context.Background(), lastPayAddUpdateTimeKey, time.Now().Unix())
					// 本次加付费目标数据
					lastPayAddNumKey := fmt.Sprintf(LastPayAddNumKey, date, gameTask.TaskId)
					_ = s.cache.SetCacheStr(context.Background(), lastPayAddNumKey, gameTarget.PayTarget-completeTaskData[gameTask.TaskId].PayTarget)
					payErrAddNumKey := fmt.Sprintf(PayErrAddNumKey, date, gameTask.TaskId)
					diffNum := gameTarget.PayTarget - completeTaskData[gameTask.TaskId].PayTarget
					s.common.SaveGameAddFee(diffNum, gameTarget.PayTarget, gameTask.TaskName)
					go s.common.FreeSendMsg(diffNum, gameTarget.PayTarget, gameTask.TaskId, gameTask.TaskName, gameTask.User)
					// 如果当前付费目标完成，加入一下逻辑
					if completeTaskData[gameTask.TaskId].PayTarget <= completeTaskData[gameTask.TaskId].PayComplete {
						lastPayCompletedUpdateTimeKey := fmt.Sprintf(LastPayCompletedUpdateTimeKey, date, gameTask.TaskId)
						_ = s.cache.SetCacheStr(context.Background(), lastPayCompletedUpdateTimeKey, time.Now().Unix())
						_ = s.cache.SetCacheStr(context.Background(), payErrAddNumKey, gameTarget.PayTarget-completeTaskData[gameTask.TaskId].PayTarget)
					} else {
						n, _ := s.cache.GetCacheNum(context.Background(), payErrAddNumKey)
						_ = s.cache.SetCacheStr(context.Background(), payErrAddNumKey, gameTarget.PayTarget-completeTaskData[gameTask.TaskId].PayTarget+n)
					}
				}
			}

		} else {
			gameTarget.NewComplete = roomData.NewCompleteLocal
			gameTarget.PayComplete = roomData.PayCompleteLocal
			gameTarget.RetainedComplete = roomData.NewCompleteLocal + roomData.RetainedCompleteLocal
			gameTarget.Amount = gameTask.PayPrice * roomData.PayCompleteLocal
			if gameTarget.RetainedComplete < roomData.RetainedComplete {
				gameTarget.RetainedComplete = roomData.RetainedComplete
			}
		}
		gameTarget.GameRate = roomData.GameRate
		if (gameTask.GamePortId == 5 && gameTask.LoginMethod == 2) || gameTask.LoginMethod == 7 {
			// 魅族游戏id处理
			GameId := gameTask.MzGameId + "-" + gameTask.MzChannel
			// 青雀账号游戏id处理
			if gameTask.LoginMethod == 7 {
				taskId := strconv.Itoa(gameTask.TaskId)
				GameId = "rose-" + taskId
				gameTarget.PayComplete = roomData.PayComplete
			}
			if _, ok := wslData[GameId]; ok {
				gameTarget.PayTarget = wslData[GameId]
				if gameTarget.PayTarget > completeTaskData[gameTask.TaskId].PayTarget {
					lastPayAddUpdateTimeKey := fmt.Sprintf(LastPayAddUpdateTimeKey, date, gameTask.TaskId)
					_ = s.cache.SetCacheStr(context.Background(), lastPayAddUpdateTimeKey, time.Now().Unix())
					// 本次加付费目标数据
					lastPayAddNumKey := fmt.Sprintf(LastPayAddNumKey, date, gameTask.TaskId)
					_ = s.cache.SetCacheStr(context.Background(), lastPayAddNumKey, gameTarget.PayTarget-completeTaskData[gameTask.TaskId].PayTarget)
					payErrAddNumKey := fmt.Sprintf(PayErrAddNumKey, date, gameTask.TaskId)
					diffNum := gameTarget.PayTarget - completeTaskData[gameTask.TaskId].PayTarget
					s.common.SaveGameAddFee(diffNum, gameTarget.PayTarget, gameTask.TaskName)
					go s.common.FreeSendMsg(diffNum, gameTarget.PayTarget, gameTask.TaskId, gameTask.TaskName, gameTask.User)
					// 如果当前付费目标完成，加入一下逻辑
					if completeTaskData[gameTask.TaskId].PayTarget <= completeTaskData[gameTask.TaskId].PayComplete {
						lastPayCompletedUpdateTimeKey := fmt.Sprintf(LastPayCompletedUpdateTimeKey, date, gameTask.TaskId)
						_ = s.cache.SetCacheStr(context.Background(), lastPayCompletedUpdateTimeKey, time.Now().Unix())
						_ = s.cache.SetCacheStr(context.Background(), payErrAddNumKey, gameTarget.PayTarget-completeTaskData[gameTask.TaskId].PayTarget)
					} else {
						n, _ := s.cache.GetCacheNum(context.Background(), payErrAddNumKey)
						_ = s.cache.SetCacheStr(context.Background(), payErrAddNumKey, gameTarget.PayTarget-completeTaskData[gameTask.TaskId].PayTarget+n)
					}
				}
			}
		}
		gameTarget.IsComplete = -1
		if gameTarget.RetainedComplete+completeTaskData[gameTask.TaskId].HandRetainedComplete >= completeTaskData[gameTask.TaskId].RetainedTarget && gameTarget.PayComplete >= completeTaskData[gameTask.TaskId].PayTarget && gameTarget.NewComplete+completeTaskData[gameTask.TaskId].HandNewComplete >= completeTaskData[gameTask.TaskId].NewTarget {
			gameTarget.IsComplete = 1
		}
		global.GVA_DB.Model(&task.GameTargetComplete{}).Where("task_id = ?", gameTask.TaskId).Where("create_date = ?", date).Omit("create_date", "update_time", "task_id").Updates(gameTarget)
	}
	return
}

func (s *SyncData) DayTargetDataStatistics() {
	date := time.Now().Add(-time.Hour * 24).Format("2006-01-02")
	request1 := request2.GameTaskStatisticsRequest{
		GroupKey: "user,gt.game_port_id",
		Date:     date,
	}
	gameTargets, err := s.GameTask.EveryDayTargetData(date, request1)
	if err != nil {
		global.GVA_LOG.Error("DayTargetDataStatistics 统计数据失败", zap.Error(err))
		return
	}
	if len(gameTargets) == 0 {
		global.GVA_LOG.Info("没有数据统计", zap.Error(err))
		return
	}
	var gameTargetDates []task.GameTargetStatistics
	for _, gameTarget := range gameTargets {
		var gameTargetDate task.GameTargetStatistics
		gameTargetDate.PayTarget = gameTarget.PayTarget
		gameTargetDate.NewTarget = gameTarget.NewTarget
		gameTargetDate.RetainedTarget = gameTarget.RetainedTarget
		gameTargetDate.PayComplete = gameTarget.PayComplete
		gameTargetDate.NewComplete = gameTarget.NewComplete + gameTarget.HandNewComplete
		gameTargetDate.RetainedComplete = gameTarget.RetainedComplete + gameTarget.HandRetainedComplete
		gameTargetDate.Amount = gameTarget.Amount
		gameTargetDate.GamePortId = gameTarget.GamePortId
		gameTargetDate.User = gameTarget.User
		gameTargetDate.TaskDate = gameTarget.CreateDate
		if !errors.Is(global.GVA_DB.Where("user = ?", gameTarget.User).Where("task_date = ?", gameTarget.CreateDate).Where("game_port_id = ?", gameTarget.GamePortId).First(&task.GameTargetStatistics{}).Error, gorm.ErrRecordNotFound) {
			err := global.GVA_DB.Where("user = ?", gameTarget.User).Where("task_date = ?", gameTarget.CreateDate).Where("game_port_id = ?", gameTarget.GamePortId).Omit("update_time", "task_date", "user", "game_port_id", "task_month", "task_year").Updates(&gameTargetDate).Error
			if err != nil {
				global.GVA_LOG.Error("DayTargetDataStatistics 更新统计数据失败", zap.Error(err))
			}
			continue
		}
		year, month, _ := time.Now().Date()
		gameTargetDate.TaskMonth = int(month)
		gameTargetDate.TaskYear = year
		gameTargetDates = append(gameTargetDates, gameTargetDate)
	}
	if len(gameTargetDates) < 1 {
		return
	}
	global.GVA_DB.Omit("update_time").Create(gameTargetDates)
}

var LastMsgSendTimeKey = "%s:lastMsgSendTime"                                                // 上次活跃发送消息时间
var LastNewCompletedKey = "%s:msgSendInfo:%d:lastNewCompleted"                               // 最后新增完成数量
var LastPayCompletedKey = "%s:msgSendInfo:%d:lastPayCompleted"                               // 最后支付完成数量
var LastRetainedCompletedKey = "%s:msgSendInfo:%d:lastRetainedCompleted"                     // 最后留存完成数量
var LastNewCompletedUpdateTimeKey = "%s:msgSendInfo:%d:lastNewCompletedUpdateTime"           // 最后新增完成更新时间
var LastPayCompletedUpdateTimeKey = "%s:msgSendInfo:%d:lastPayCompletedUpdateTime"           // 最后支付完成更新时间
var LastRetainedCompletedUpdateTimeKey = "%s:msgSendInfo:%d:lastRetainedCompletedUpdateTime" // 最后留存完成更新时间
var LastPayAddUpdateTimeKey = "%s:msgSendInfo:%d:lastPayAddUpdateTime"                       // 最后加付费时间
var LastPayAddNumKey = "%s:msgSendInfo:%d:lastPayAddNum"                                     // 最后加付费数量
var PayErrAddNumKey = "%s:msgSendInfo:%d:PayErrAddNum"                                       // 支付异常累加数量
var TaskCompletedStatusKey = "%s:taskCompletedStatus"                                        // 任务完成状态-1,1
var LastFreeMsgSendTimeKey = "%s:lastFreeMsgSendTime"                                        // 上次付费发送消息时间
var LastDirectorMsgSendTimeKey = "%s:lastDirectorMsgSendTime:%d"                             // 上次负责人活跃发送消息时间
var LastFreeDirectorMsgSendTimeKey = "%s:lastFreeDirectorMsgSendTime:%d"                     // 上次负责人付费发送消息时间

type CompletedInfo struct {
	AlsoTarget       int //剩余数量
	Rate             int //时间段做的任务数
	TimeRate         int // 完成任务数据更新时间
	TaskId           int
	AddPayUpdateTime int
}

// 获取未完成的任务数据
func (s *SyncData) TaskNoCompleteDate(date string) (completesInfo []task.GameTargetComplete, err error) {
	db := global.GVA_DB.Table("game_target_complete")
	db = db.Where("is_complete = ?", -1)
	db = db.Where("create_date = ?", date)
	err = db.Find(&completesInfo).Error
	if err != nil {
		return
	}
	return
}

func (s *SyncData) TaskMsgSendInitData(ctx context.Context, completesInfo []task.GameTargetComplete, ctime int64, date, taskCompletedStatusKey, lastMsgSendTimeKey string) {
	for _, complete := range completesInfo {
		lastNewCompletedKey := fmt.Sprintf(LastNewCompletedKey, date, complete.TaskId)
		lastPayCompletedKey := fmt.Sprintf(LastPayCompletedKey, date, complete.TaskId)
		lastRetainedCompletedKey := fmt.Sprintf(LastRetainedCompletedKey, date, complete.TaskId)
		lastPayCompletedUpdateTimeKey := fmt.Sprintf(LastPayCompletedUpdateTimeKey, date, complete.TaskId)
		lastNewCompletedUpdateTimeKey := fmt.Sprintf(LastNewCompletedUpdateTimeKey, date, complete.TaskId)
		lastRetainedCompletedUpdateTimeKey := fmt.Sprintf(LastRetainedCompletedUpdateTimeKey, date, complete.TaskId)

		lastNewCompleted := complete.NewComplete + complete.HandNewComplete //上次新增完成数
		_ = s.cache.SetCacheStr(ctx, lastNewCompletedKey, lastNewCompleted)
		lastPayCompleted := complete.PayComplete + complete.HandPayComplete //上次支付完成数
		_ = s.cache.SetCacheStr(ctx, lastPayCompletedKey, lastPayCompleted)
		lastRetainedCompleted := complete.RetainedComplete + complete.HandRetainedComplete //上次活跃完成数
		_ = s.cache.SetCacheStr(ctx, lastRetainedCompletedKey, lastRetainedCompleted)
		//lastNewCompletedUpdateTime := complete.NewComplete //上次新增完成更新时间
		_ = s.cache.SetCacheStr(ctx, lastNewCompletedUpdateTimeKey, ctime)
		//lastPayCompletedUpdateTime := complete.NewComplete //上次支付完成更新时间
		_ = s.cache.SetCacheStr(ctx, lastPayCompletedUpdateTimeKey, ctime)
		//lastRetainedCompletedUpdateTime := complete.NewComplete //上次留存完成更新时间
		_ = s.cache.SetCacheStr(ctx, lastRetainedCompletedUpdateTimeKey, ctime)
		//lastPayAddUpdateTime := complete.NewComplete //上次付费增加更新时间

	}
	_ = s.cache.SetCacheStr(ctx, taskCompletedStatusKey, -1)
	_ = s.cache.SetCacheStr(ctx, lastMsgSendTimeKey, time.Now().Unix())
}

func (s *SyncData) TaskMsgSendRetainedData(ctx context.Context, completesInfo []task.GameTargetComplete, ctime int64, date, lastMsgSendTimeKey string) {
	var mps = make(map[int]map[string]CompletedInfo)
	lastMsgSendTime, _ := s.cache.GetCacheNum(ctx, lastMsgSendTimeKey)
	for _, complete := range completesInfo {
		lastNewCompletedKey := fmt.Sprintf(LastNewCompletedKey, date, complete.TaskId)
		lastRetainedCompletedKey := fmt.Sprintf(LastRetainedCompletedKey, date, complete.TaskId)
		lastNewCompletedUpdateTimeKey := fmt.Sprintf(LastNewCompletedUpdateTimeKey, date, complete.TaskId)
		lastRetainedCompletedUpdateTimeKey := fmt.Sprintf(LastRetainedCompletedUpdateTimeKey, date, complete.TaskId)
		currentNewCompleted := complete.NewComplete + complete.HandNewComplete
		currentRetainedCompleted := complete.RetainedComplete + complete.HandRetainedComplete
		var RateMp = make(map[string]CompletedInfo)
		var newBool = false
		var retainedBoll = false
		// 处理新增
		if complete.NewTarget > currentNewCompleted {
			lastNewCompleted, _ := s.cache.GetCacheNum(ctx, lastNewCompletedKey)
			alsoNewTarget := complete.NewTarget - currentNewCompleted
			newRate := 0
			lastNewCompletedUpdateTime, _ := s.cache.GetCacheNum(ctx, lastNewCompletedUpdateTimeKey)
			timeRate := int(ctime) - lastNewCompletedUpdateTime
			if lastNewCompleted < currentNewCompleted {
				newRate = currentNewCompleted - lastNewCompleted
				_ = s.cache.SetCacheStr(ctx, lastNewCompletedKey, currentNewCompleted)
				_ = s.cache.SetCacheStr(ctx, lastNewCompletedUpdateTimeKey, ctime) //上次新增完成更新时间
			}
			RateMp["newRate"] = CompletedInfo{
				AlsoTarget: alsoNewTarget,
				Rate:       newRate,
				TimeRate:   timeRate,
				TaskId:     complete.TaskId,
			}
		} else {
			newBool = true
			// 如果当前新增为0，或者完成也更新时间
			_ = s.cache.SetCacheStr(ctx, lastNewCompletedUpdateTimeKey, ctime) //上次新增完成更新时间
		}
		// 处理留存
		if complete.RetainedTarget > currentRetainedCompleted {
			lastRetainedCompleted, _ := s.cache.GetCacheNum(ctx, lastRetainedCompletedKey)
			alsoRetainedTarget := complete.RetainedTarget - currentRetainedCompleted
			retainedRate := 0
			lastRetainedCompletedUpdateTime, _ := s.cache.GetCacheNum(ctx, lastRetainedCompletedUpdateTimeKey)
			timeRate := int(ctime) - lastRetainedCompletedUpdateTime
			if lastRetainedCompleted < currentRetainedCompleted {
				retainedRate = currentRetainedCompleted - lastRetainedCompleted
				_ = s.cache.SetCacheStr(ctx, lastRetainedCompletedKey, currentRetainedCompleted)
				_ = s.cache.SetCacheStr(ctx, lastRetainedCompletedUpdateTimeKey, ctime) //上次留存完成更新时间
			}
			RateMp["retainedRate"] = CompletedInfo{
				AlsoTarget: alsoRetainedTarget,
				Rate:       retainedRate,
				TimeRate:   timeRate,
				TaskId:     complete.TaskId,
			}
		} else {
			retainedBoll = true
			// 如果当前留存为0，或者完成也更新时间
			_ = s.cache.SetCacheStr(ctx, lastRetainedCompletedUpdateTimeKey, ctime) //上次留存完成更新时间
		}
		if !newBool || !retainedBoll {
			mps[complete.TaskId] = RateMp
		}
	}

	var taskStatistics = "%s:taskStatistics"
	var retained = "# 活跃播报 "
	if len(mps) == 0 {
		global.GVA_LOG.Warn(retained)
	}
	retained += fmt.Sprintf("<font color=\"warning\">%s</font>", time.Now().Format("2006-01-02 15:04:05"))
	var errMsg = "**以下游戏目标效率为零:**"
	var errMsgZ = ""
	var sendMsg = map[string]string{}
	var errSendMsg = map[string]string{}
	var m int // 时间内
	m = (int(ctime) - lastMsgSendTime) / 60
	for taskId, data := range mps {
		key := fmt.Sprintf(taskStatistics, date)
		gameIdStr := strconv.Itoa(taskId)
		gameTask, err := global.GVA_REDIS.HGet(ctx, key, gameIdStr).Result()
		if err != nil {
			if err == redis.Nil {
				continue
			} else {
				global.GVA_LOG.Error("TaskMsgSendRetainedData获取缓存任务数据失败", zap.Error(err))
				continue
			}
		}
		var taskStatistics request.TaskStatistics
		_ = json.Unmarshal([]byte(gameTask), &taskStatistics)
		var eMsg = "" //单条异常数据
		var isNew = false
		var nm int      //新增时间内
		var rm int      //存时间内
		var rate string //效率
		var newErr = false
		var retainedErr = false
		var name = taskStatistics.Remark
		if info, ok := data["newRate"]; ok {
			sendMsg[name] += "\n"
			sendMsg[name] += taskStatistics.GameName
			sendMsg[name] += ",新增差"
			//sendMsg[name] += strconv.Itoa(info.AlsoTarget)
			sendMsg[name] += fmt.Sprintf("<font color=\"warning\">%d</font>", info.AlsoTarget)
			isNew = true
			if info.TimeRate > 60*60*24 {
				lastNewCompletedUpdateTimeKey := fmt.Sprintf(LastNewCompletedUpdateTimeKey, date, info.TaskId)
				_ = s.cache.SetCacheStr(ctx, lastNewCompletedUpdateTimeKey, ctime) //上次新增完成更新时间
				nm = 1
			} else {
				nm = info.TimeRate / 60
			}
			rate = strconv.Itoa(info.Rate)
			if info.Rate == 0 {
				newErr = true
			}
		}
		if info, ok := data["retainedRate"]; ok {
			if !isNew {
				sendMsg[name] += "\n"
				sendMsg[name] += taskStatistics.GameName
				rate = strconv.Itoa(info.Rate)
				sendMsg[name] += "活跃差"
			} else {
				rate += "/" + strconv.Itoa(info.Rate)
				sendMsg[name] += ",活跃差"
			}
			if info.TimeRate > 60*60*24 {
				lastRetainedCompletedUpdateTimeKey := fmt.Sprintf(LastRetainedCompletedUpdateTimeKey, date, info.TaskId)
				_ = s.cache.SetCacheStr(ctx, lastRetainedCompletedUpdateTimeKey, ctime) //上次留存完成更新时间
				rm = 1
			} else {
				rm = info.TimeRate / 60
			}

			//sendMsg[name] += strconv.Itoa(info.AlsoTarget)
			sendMsg[name] += fmt.Sprintf("<font color=\"warning\">%d</font>", info.AlsoTarget)
			if info.Rate == 0 {
				retainedErr = true
			}
		}

		// 5分钟数据没动报异常数据
		if newErr && nm > 4 {
			eMsg += "\n"
			eMsg += taskStatistics.GameName
			eMsg += ",新增"
			if nm >= 60 {
				eMsg += "("
				eMsg += strconv.Itoa(nm / 60)
				eMsg += "小时内)"
			} else {
				eMsg += "("
				eMsg += strconv.Itoa(nm)
				eMsg += "分钟内)"
			}
		}
		if retainedErr && rm > 4 {
			if !newErr {
				eMsg += "\n"
				eMsg += taskStatistics.GameName
			}
			eMsg += ",活跃"
			if rm >= 60 {
				eMsg += "("
				eMsg += strconv.Itoa(rm / 60)
				eMsg += "小时内)"
			} else {
				eMsg += "("
				eMsg += strconv.Itoa(rm)
				eMsg += "分钟内)"
			}
		}
		if eMsg != "" {
			errMsgZ += eMsg
			errSendMsg[name] += eMsg
		}
		sendMsg[name] += ","
		if m >= 60 {
			sendMsg[name] += strconv.Itoa(m / 60)
			sendMsg[name] += "小时内完成"
		} else {
			sendMsg[name] += strconv.Itoa(m)
			sendMsg[name] += "分钟内完成"
		}
		//sendMsg[name] += rate
		sendMsg[name] += fmt.Sprintf("<font color=\"warning\">%s</font>", rate)
	}
	hour := time.Now().Hour()
	msg := ""
	mpsPerson, _ := s.Person.GetUserInfo()
	//b1 ,_ := json.Marshal(mpsPerson)
	//global.GVA_LOG.Warn(string(b1))
	var mobile []string
	if hour >= 16 {
		if len(sendMsg) == 0 {
			return
		}
		if len(mps) != 0 && len(errSendMsg) != 0 {
			for name, _ := range errSendMsg {
				mobile = append(mobile, mpsPerson[name])
			}
		}
		for name, msg := range sendMsg {
			retained += "\n"
			retained += "**" + name + "**"
			retained += msg
		}
		msg = retained
		if errMsgZ != "" {
			msg += "\n"
			//msg += errMsg + errMsgZ
			msg += fmt.Sprintf("<font color=\"warning\">%s</font>", errMsg+errMsgZ)
		}
	} else {
		if errMsgZ != "" {

			//msg += errMsg + errMsgZ

		}
		if len(mps) != 0 && len(errSendMsg) != 0 {
			msg += "# 活跃播报 "
			msg += errMsg
			for name, m := range errSendMsg {
				mobile = append(mobile, mpsPerson[name])
				msg += "\n"
				msg += "**" + name + "**"
				msg += fmt.Sprintf("<font color=\"warning\">%s</font>", m)
			}
		}
	}
	//global.GVA_LOG.Warn(msg)
	_ = s.cache.SetCacheStr(ctx, lastMsgSendTimeKey, time.Now().Unix())
	if msg == "" {
		return
	}
	url := global.GVA_CONFIG.SendUrl.ComputerSendUrl
	var sendData SendMsg
	sendData.MsgType = "markdown"
	sendData.Markdown.Content = msg
	s.SendMsgData(url, sendData)

	if len(mobile) != 0 {
		var sendTextData SendTextMsg
		sendTextData.MsgType = "text"
		sendTextData.Text.MentionedMobileList = mobile
		//b ,_ := json.Marshal(sendTextData)
		//global.GVA_LOG.Warn(string(b))
		s.SendMsgData(url, sendTextData)
	}
}

func (s *SyncData) TaskMsgSendFreeData(ctx context.Context, completesInfo []task.GameTargetComplete, ctime int64, date, lastFreeMsgSendTimeKey string, isOne bool) {
	var RateMp = make(map[int]CompletedInfo)
	lastFreeMsgSendTime, _ := s.cache.GetCacheNum(ctx, lastFreeMsgSendTimeKey)
	for _, complete := range completesInfo {
		lastPayCompletedKey := fmt.Sprintf(LastPayCompletedKey, date, complete.TaskId)
		lastPayCompletedUpdateTimeKey := fmt.Sprintf(LastPayCompletedUpdateTimeKey, date, complete.TaskId)
		lastPayAddUpdateTimeKey := fmt.Sprintf(LastPayAddUpdateTimeKey, date, complete.TaskId)
		currentPayCompleted := complete.PayComplete + complete.HandPayComplete
		// 付费处理
		if complete.PayTarget != 0 && complete.PayTarget > currentPayCompleted {
			lastPayCompleted, _ := s.cache.GetCacheNum(ctx, lastPayCompletedKey)
			alsoPayTarget := complete.PayTarget - currentPayCompleted
			payRate := 0
			lastPayCompletedUpdateTime, _ := s.cache.GetCacheNum(ctx, lastPayCompletedUpdateTimeKey)
			lastPayAddUpdateTime, _ := s.cache.GetCacheNum(ctx, lastPayAddUpdateTimeKey)
			timeRate := int(ctime) - lastPayCompletedUpdateTime
			if lastPayCompleted < currentPayCompleted {
				payRate = currentPayCompleted - lastPayCompleted
				_ = s.cache.SetCacheStr(ctx, lastPayCompletedKey, currentPayCompleted)
				_ = s.cache.SetCacheStr(ctx, lastPayCompletedUpdateTimeKey, ctime) //上次付费更新时间
			}
			RateMp[complete.TaskId] = CompletedInfo{
				AlsoTarget:       alsoPayTarget,
				Rate:             payRate,
				TimeRate:         timeRate,
				TaskId:           complete.TaskId,
				AddPayUpdateTime: lastPayAddUpdateTime,
			}
		} else {
			// 如果当前付费为0，或者完成也更新时间
			_ = s.cache.SetCacheStr(ctx, lastPayCompletedUpdateTimeKey, ctime) //上次付费更新时间
		}
	}
	if isOne {
		_ = s.cache.SetCacheStr(ctx, lastFreeMsgSendTimeKey, time.Now().Unix())
		return
	}
	if len(RateMp) == 0 {
		global.GVA_LOG.Info("TaskMsgSendFreeData没有查询到未完成付费数据")
		return
	}
	var taskStatistics = "%s:taskStatistics"
	var retained = "付费播报 "
	retained += fmt.Sprintf("<font color=\"warning\">%s</font>", time.Now().Format("2006-01-02 15:04:05"))
	var errMsg = "**以下游戏付费效率为零:**"
	var errMsgZ = ""
	var sendMsg = map[string]string{}
	var m int //时间内
	m = (int(ctime) - lastFreeMsgSendTime) / 60
	mpsPerson, _ := s.Person.GetUserInfo()
	var mobile []string
	for taskId, data := range RateMp {
		if data.AlsoTarget <= 0 {
			continue
		}
		key := fmt.Sprintf(taskStatistics, date)
		gameIdStr := strconv.Itoa(taskId)
		gameTask, err := global.GVA_REDIS.HGet(ctx, key, gameIdStr).Result()
		if err != nil {
			if err == redis.Nil {
				continue
			} else {
				global.GVA_LOG.Error("TaskMsgSendRetainedData获取缓存任务数据失败", zap.Error(err))
				continue
			}
		}
		var taskStatistics request.TaskStatistics
		_ = json.Unmarshal([]byte(gameTask), &taskStatistics)

		var name = taskStatistics.Remark
		sendMsg[name] += "\n"
		sendMsg[name] += taskStatistics.GameName
		sendMsg[name] += ",付费差"
		//sendMsg[name] += strconv.Itoa(data.AlsoTarget)
		sendMsg[name] += fmt.Sprintf("<font color=\"warning\">%d</font>", data.AlsoTarget)

		if data.TimeRate > 60*60*24 {
			lastPayCompletedUpdateTimeKey := fmt.Sprintf(LastPayCompletedUpdateTimeKey, date, data.TaskId)
			_ = s.cache.SetCacheStr(ctx, lastPayCompletedUpdateTimeKey, ctime) //上次付费更新时间
			data.TimeRate = 60 * 60 * 2
		}
		// 5分钟数据没动报异常数据
		if data.TimeRate/60 >= 2 {
			if data.Rate == 0 {
				lastPayAddNumKey := fmt.Sprintf(LastPayAddNumKey, date, data.TaskId)
				payErrAddNumKey := fmt.Sprintf(PayErrAddNumKey, date, data.TaskId)
				numErr, _ := s.cache.GetCacheNum(context.Background(), payErrAddNumKey)
				lastAddFeeNumErr, _ := s.cache.GetCacheNum(context.Background(), lastPayAddNumKey)
				errMsgZ += "\n"
				errMsgZ += taskStatistics.GameName
				errMsgZ += "("
				if data.TimeRate/60 >= 60 {
					errMsgZ += strconv.Itoa(data.TimeRate / 60 / 60)
					errMsgZ += "小时内(+" + strconv.Itoa(numErr) + "))"
				} else {
					errMsgZ += strconv.Itoa(data.TimeRate / 60)
					errMsgZ += "分钟内(+" + strconv.Itoa(numErr) + "))"
				}
				errMsgZ += ","
				errMsgZ += "最后加付费时间 "
				t := time.Unix(int64(data.AddPayUpdateTime), 0)
				errMsgZ += t.Format("15:04:05")
				errMsgZ += "(+" + strconv.Itoa(lastAddFeeNumErr) + ")"
				if _, ok := mpsPerson[name]; ok {
					mobile = append(mobile, mpsPerson[name])
				}
			}
		}
		sendMsg[name] += ","
		if m >= 60 {
			sendMsg[name] += strconv.Itoa(m / 60)
			sendMsg[name] += "分钟内完成"
		} else {
			sendMsg[name] += strconv.Itoa(m)
			sendMsg[name] += "分钟内完成"
		}
		//sendMsg[name] += strconv.Itoa(data.Rate)
		sendMsg[name] += fmt.Sprintf("<font color=\"warning\">%d</font>", data.Rate)
	}
	if len(sendMsg) == 0 {
		return
	}
	for name, msg := range sendMsg {
		retained += "\n"
		retained += name
		retained += msg
	}
	msg := retained
	if errMsgZ != "" {
		msg += "\n"
		//msg += errMsg + errMsgZ
		msg += fmt.Sprintf("<font color=\"warning\">%s</font>", errMsg+errMsgZ)
	}
	_ = s.cache.SetCacheStr(ctx, lastFreeMsgSendTimeKey, time.Now().Unix())
	url := global.GVA_CONFIG.SendUrl.ComputerSendUrl
	var sendData SendMsg
	sendData.MsgType = "markdown"
	sendData.Markdown.Content = msg
	s.SendMsgData(url, sendData)
	if len(mobile) != 0 {
		var sendTextData SendTextMsg
		sendTextData.MsgType = "text"
		sendTextData.Text.MentionedMobileList = mobile
		s.SendMsgData(url, sendTextData)
	}
	return
}

func (s *SyncData) SendMsgData(url string, params interface{}) {
	_, _ = utils.HttpPost(url, params)
	return
}

//活跃新增数据推送
func (s *SyncData) TaskMsgSend() {
	date := time.Now().Format("2006-01-02")
	ctx := context.Background()
	taskCompletedStatusKey := fmt.Sprintf(TaskCompletedStatusKey, date)
	taskCompletedStatus, _ := s.cache.GetCacheNum(ctx, taskCompletedStatusKey)
	if taskCompletedStatus == 1 {
		return
	}
	completesInfo, err := s.TaskNoCompleteDate(date)
	if err != nil {
		global.GVA_LOG.Error("TaskMsgSend查询任务数据报错", zap.Error(err))
	}
	if len(completesInfo) == 0 {
		global.GVA_LOG.Info("TaskMsgSend没有查询到未完成数据")
	}
	lastMsgSendTimeKey := fmt.Sprintf(LastMsgSendTimeKey, date)
	b, err := s.cache.ExistsKey(context.Background(), lastMsgSendTimeKey)
	if err != nil {
		global.GVA_LOG.Error("TaskMsgSend查询任务数据报错", zap.Error(err))
		return
	}
	ctime := time.Now().Unix()
	if !b {
		s.TaskMsgSendInitData(ctx, completesInfo, ctime, date, taskCompletedStatusKey, lastMsgSendTimeKey)
	} else {
		lastMsgSendTime, _ := s.cache.GetCacheNum(ctx, lastMsgSendTimeKey)
		if int(ctime)-lastMsgSendTime < 60 {
			global.GVA_LOG.Error("TaskMsgSend上次数据发送时间还没到5分钟", zap.Error(err))
			return
		}
		//s.TaskMsgSendRetainedData(ctx, completesInfo, ctime, date, lastMsgSendTimeKey)
		s.TaskMsgSendRetainedDataUpdate(ctx, completesInfo, ctime, date, lastMsgSendTimeKey)
	}
}

//活跃新增数据推送
func (s *SyncData) TaskFreeMsgSend() {
	date := time.Now().Format("2006-01-02")
	ctx := context.Background()
	taskCompletedStatusKey := fmt.Sprintf(TaskCompletedStatusKey, date)
	taskCompletedStatus, _ := s.cache.GetCacheNum(ctx, taskCompletedStatusKey)
	if taskCompletedStatus == 1 {
		return
	}
	completesInfo, err := s.TaskNoCompleteDate(date)
	if err != nil {
		global.GVA_LOG.Error("TaskMsgSend查询任务数据报错", zap.Error(err))
	}
	if len(completesInfo) == 0 {
		global.GVA_LOG.Info("TaskMsgSend没有查询到未完成数据")
	}
	lastFreeMsgSendTimeKey := fmt.Sprintf(LastFreeMsgSendTimeKey, date)

	ctime := time.Now().Unix()
	lastFreeMsgSendTime, _ := s.cache.GetCacheNum(ctx, lastFreeMsgSendTimeKey)
	if int(ctime)-lastFreeMsgSendTime < 60 {
		global.GVA_LOG.Error("TaskMsgSend上次数据发送时间还没到5分钟", zap.Error(err))
		return
	}
	var isOne = false
	if lastFreeMsgSendTime == 0 {
		isOne = true
	}
	//s.TaskMsgSendFreeData(ctx, completesInfo, ctime, date, lastFreeMsgSendTimeKey, isOne)
	s.TaskMsgSendFreeDataUpdate(ctx, completesInfo, ctime, date, lastFreeMsgSendTimeKey, isOne)
}

func (s *SyncData) CheckTaskCompletedInfo() {
	date := time.Now().Format("2006-01-02")
	ctx := context.Background()
	taskCompletedStatusKey := fmt.Sprintf(TaskCompletedStatusKey, date)
	completesInfo, err := s.TaskNoCompleteDate(date)
	if err != nil {
		global.GVA_LOG.Error("CheckTaskCompletedInfo查询任务数据报错", zap.Error(err))
		return
	}
	status, _ := s.cache.GetCacheNum(ctx, taskCompletedStatusKey)
	if status == 1 {
		global.GVA_LOG.Info("任务已完成")
		return
	}
	if len(completesInfo) == 0 {
		global.GVA_LOG.Info("TaskMsgSend没有查询到未完成数据")
		time.Sleep(time.Second * 10)
		_ = s.cache.SetCacheStr(ctx, taskCompletedStatusKey, 1)
		msg := "# 监控报警 "
		msg += fmt.Sprintf("<font color=\"warning\">%s</font>", time.Now().Format("2006-01-02 15:04:05"))
		msg += "\n"
		msg += "今日任务目标已完成"
		url := global.GVA_CONFIG.SendUrl.ComputerSendUrl
		var sendData SendMsg
		sendData.MsgType = "markdown"
		sendData.Markdown.Content = msg
		s.SendMsgData(url, sendData)
	}
}

func (s *SyncData) TaskMsgSendRetainedDataUpdate(ctx context.Context, completesInfo []task.GameTargetComplete, ctime int64, date, lastMsgSendTimeKey string) {
	var mps = make(map[int]map[string]CompletedInfo)
	lastMsgSendTime, _ := s.cache.GetCacheNum(ctx, lastMsgSendTimeKey)
	for _, complete := range completesInfo {
		lastNewCompletedKey := fmt.Sprintf(LastNewCompletedKey, date, complete.TaskId)
		lastRetainedCompletedKey := fmt.Sprintf(LastRetainedCompletedKey, date, complete.TaskId)
		lastNewCompletedUpdateTimeKey := fmt.Sprintf(LastNewCompletedUpdateTimeKey, date, complete.TaskId)
		lastRetainedCompletedUpdateTimeKey := fmt.Sprintf(LastRetainedCompletedUpdateTimeKey, date, complete.TaskId)
		currentNewCompleted := complete.NewComplete + complete.HandNewComplete
		currentRetainedCompleted := complete.RetainedComplete + complete.HandRetainedComplete
		var RateMp = make(map[string]CompletedInfo)
		var newBool = false
		var retainedBoll = false
		// 处理新增
		if complete.NewTarget > currentNewCompleted {
			lastNewCompleted, _ := s.cache.GetCacheNum(ctx, lastNewCompletedKey)
			alsoNewTarget := complete.NewTarget - currentNewCompleted
			newRate := 0
			lastNewCompletedUpdateTime, _ := s.cache.GetCacheNum(ctx, lastNewCompletedUpdateTimeKey)
			timeRate := int(ctime) - lastNewCompletedUpdateTime
			if lastNewCompleted < currentNewCompleted {
				newRate = currentNewCompleted - lastNewCompleted
				_ = s.cache.SetCacheStr(ctx, lastNewCompletedKey, currentNewCompleted)
				_ = s.cache.SetCacheStr(ctx, lastNewCompletedUpdateTimeKey, ctime) //上次新增完成更新时间
			}
			RateMp["newRate"] = CompletedInfo{
				AlsoTarget: alsoNewTarget,
				Rate:       newRate,
				TimeRate:   timeRate,
				TaskId:     complete.TaskId,
			}
		} else {
			newBool = true
			// 如果当前新增为0，或者完成也更新时间
			_ = s.cache.SetCacheStr(ctx, lastNewCompletedUpdateTimeKey, ctime) //上次新增完成更新时间
		}
		// 处理留存
		if complete.RetainedTarget > currentRetainedCompleted {
			lastRetainedCompleted, _ := s.cache.GetCacheNum(ctx, lastRetainedCompletedKey)
			alsoRetainedTarget := complete.RetainedTarget - currentRetainedCompleted
			retainedRate := 0
			lastRetainedCompletedUpdateTime, _ := s.cache.GetCacheNum(ctx, lastRetainedCompletedUpdateTimeKey)
			timeRate := int(ctime) - lastRetainedCompletedUpdateTime
			if lastRetainedCompleted < currentRetainedCompleted {
				retainedRate = currentRetainedCompleted - lastRetainedCompleted
				_ = s.cache.SetCacheStr(ctx, lastRetainedCompletedKey, currentRetainedCompleted)
				_ = s.cache.SetCacheStr(ctx, lastRetainedCompletedUpdateTimeKey, ctime) //上次留存完成更新时间
			}
			RateMp["retainedRate"] = CompletedInfo{
				AlsoTarget: alsoRetainedTarget,
				Rate:       retainedRate,
				TimeRate:   timeRate,
				TaskId:     complete.TaskId,
			}
		} else {
			retainedBoll = true
			// 如果当前留存为0，或者完成也更新时间
			_ = s.cache.SetCacheStr(ctx, lastRetainedCompletedUpdateTimeKey, ctime) //上次留存完成更新时间
		}
		if !newBool || !retainedBoll {
			mps[complete.TaskId] = RateMp
		}
	}

	var taskStatistics = "%s:taskStatistics"
	var retained = "# 活跃播报 "
	if len(mps) == 0 {
		global.GVA_LOG.Warn(retained)
	}
	//b, _ := json.Marshal(mps)
	//global.GVA_LOG.Warn(string(b))
	mpsPerson, _ := s.Person.GetUserInfoData()
	retained += fmt.Sprintf("<font color=\"warning\">%s</font>", time.Now().Format("2006-01-02 15:04:05"))
	var errMsg = "**以下游戏目标效率为零:**"
	var errMsgZ = ""
	var sendMsg = make(map[string]string, len(mpsPerson))
	var errSendMsg = make(map[string]string, len(mpsPerson))
	var PErrSendMsg = make(map[string]string, len(mpsPerson))
	var m int // 时间内
	m = (int(ctime) - lastMsgSendTime) / 60
	for taskId, data := range mps {
		key := fmt.Sprintf(taskStatistics, date)
		gameIdStr := strconv.Itoa(taskId)
		gameTask, err := global.GVA_REDIS.HGet(ctx, key, gameIdStr).Result()
		if err != nil {
			if err == redis.Nil {
				continue
			} else {
				global.GVA_LOG.Error("TaskMsgSendRetainedData获取缓存任务数据失败", zap.Error(err))
				continue
			}
		}
		var taskStatistics request.TaskStatistics
		_ = json.Unmarshal([]byte(gameTask), &taskStatistics)
		var eMsg = "" //单条异常数据
		var isNew = false
		var nm int      //新增时间内
		var rm int      //存时间内
		var rate string //效率
		var newErr = false
		var retainedErr = false
		var name = taskStatistics.Remark
		if info, ok := data["newRate"]; ok {
			sendMsg[name] += "\n"
			sendMsg[name] += taskStatistics.GameName
			sendMsg[name] += ",新增差"
			//sendMsg[name] += strconv.Itoa(info.AlsoTarget)
			sendMsg[name] += fmt.Sprintf("<font color=\"warning\">%d</font>", info.AlsoTarget)
			isNew = true
			if info.TimeRate > 60*60*24 {
				lastNewCompletedUpdateTimeKey := fmt.Sprintf(LastNewCompletedUpdateTimeKey, date, info.TaskId)
				_ = s.cache.SetCacheStr(ctx, lastNewCompletedUpdateTimeKey, ctime) //上次新增完成更新时间
				nm = 1
			} else {
				nm = info.TimeRate / 60
			}
			rate = strconv.Itoa(info.Rate)
			if info.Rate == 0 {
				newErr = true
			}
		}
		if info, ok := data["retainedRate"]; ok {
			if !isNew {
				sendMsg[name] += "\n"
				sendMsg[name] += taskStatistics.GameName
				rate = strconv.Itoa(info.Rate)
				sendMsg[name] += "活跃差"
			} else {
				rate += "/" + strconv.Itoa(info.Rate)
				sendMsg[name] += ",活跃差"
			}
			if info.TimeRate > 60*60*24 {
				lastRetainedCompletedUpdateTimeKey := fmt.Sprintf(LastRetainedCompletedUpdateTimeKey, date, info.TaskId)
				_ = s.cache.SetCacheStr(ctx, lastRetainedCompletedUpdateTimeKey, ctime) //上次留存完成更新时间
				rm = 1
			} else {
				rm = info.TimeRate / 60
			}

			//sendMsg[name] += strconv.Itoa(info.AlsoTarget)
			sendMsg[name] += fmt.Sprintf("<font color=\"warning\">%d</font>", info.AlsoTarget)
			if info.Rate == 0 {
				retainedErr = true
			}
		}
		oneErrM := ""
		// 5分钟数据没动报异常数据
		if newErr && nm > 4 {
			eMsg += "\n"
			eMsg += s.StrMontage(nm, taskStatistics.GameName, ",新增", 0)
			if nm >= 60 {
				oneErrM += s.StrMontage(nm, taskStatistics.GameName, ",新增", data["newRate"].AlsoTarget)
			}
		}
		if retainedErr && rm > 4 {
			if !newErr {
				eMsg += "\n"
				eMsg += s.StrMontage(rm, taskStatistics.GameName, ",活跃", 0)
				if rm >= 60 {
					oneErrM += s.StrMontage(rm, taskStatistics.GameName, ",活跃", data["retainedRate"].AlsoTarget)
				}
			} else {
				eMsg += s.StrMontage(rm, "", ",活跃", 0)
				if rm >= 60 {
					if oneErrM != "" {
						oneErrM += s.StrMontage(rm, "", ",活跃", data["retainedRate"].AlsoTarget)
					} else {
						eMsg += "\n"
						eMsg += s.StrMontage(rm, taskStatistics.GameName, ",活跃", 0)
					}

				}
			}
		}
		if eMsg != "" {
			errMsgZ += eMsg
			errSendMsg[name] += eMsg
		}
		if oneErrM != "" {
			PErrSendMsg[name] += oneErrM
			PErrSendMsg[name] += "\n"
		}
		sendMsg[name] += ","
		if m >= 60 {
			sendMsg[name] += strconv.Itoa(m / 60)
			sendMsg[name] += "小时内完成"
		} else {
			sendMsg[name] += strconv.Itoa(m)
			sendMsg[name] += "分钟内完成"
		}
		//sendMsg[name] += rate
		sendMsg[name] += fmt.Sprintf("<font color=\"warning\">%s</font>", rate)
	}
	hour := time.Now().Hour()
	msg := ""

	//b1 ,_ := json.Marshal(mpsPerson)
	//global.GVA_LOG.Warn(string(b1))
	msgType := "# 活跃异常 "
	var mobile []string
	if hour >= 16 {
		if len(sendMsg) == 0 {
			return
		}
		if len(mps) != 0 && len(errSendMsg) != 0 {
			for name, _ := range errSendMsg {
				mobile = append(mobile, mpsPerson[name].MobilePhoneNumber)
			}
		}
		for name, msg := range sendMsg {
			retained += "\n"
			retained += "**" + name + "**"
			retained += msg
		}
		msg = retained
		if errMsgZ != "" {
			msg += "\n"
			//msg += errMsg + errMsgZ
			msg += fmt.Sprintf("<font color=\"warning\">%s</font>", errMsg+errMsgZ)
		}

		go s.TaskMsgSendDirector(ctx, msgType, PErrSendMsg, mpsPerson, hour, date, 60, false)
	} else {
		if errMsgZ != "" {
			//msg += errMsg + errMsgZ
		}
		if len(mps) != 0 && len(errSendMsg) != 0 {
			msg += "# 活跃播报 "
			msg += errMsg
			for name, m := range errSendMsg {
				mobile = append(mobile, mpsPerson[name].MobilePhoneNumber)
				msg += "\n"
				msg += "**" + name + "**"
				msg += fmt.Sprintf("<font color=\"warning\">%s</font>", m)
			}
		}
		go s.TaskMsgSendDirector(ctx, msgType, PErrSendMsg, mpsPerson, hour, date, 60, false)
	}
	//global.GVA_LOG.Warn(msg)
	_ = s.cache.SetCacheStr(ctx, lastMsgSendTimeKey, time.Now().Unix())
	if msg == "" {
		return
	}
	url := global.GVA_CONFIG.SendUrl.ComputerSendUrl
	var sendData SendMsg
	sendData.MsgType = "markdown"
	sendData.Markdown.Content = msg
	s.SendMsgData(url, sendData)

	if len(mobile) != 0 {
		var sendTextData SendTextMsg
		sendTextData.MsgType = "text"
		sendTextData.Text.MentionedMobileList = mobile
		//b ,_ := json.Marshal(sendTextData)
		//global.GVA_LOG.Warn(string(b))
		s.SendMsgData(url, sendTextData)
	}
}

// 数据拼接
func (s *SyncData) StrMontage(minute int, taskName, strType string, diff int) (msg string) {
	if taskName != "" {
		msg += taskName
	}
	msg += strType
	if minute >= 60 {
		msg += "("
		msg += strconv.Itoa(minute / 60)
		msg += "小时内)"
	} else {
		msg += "("
		msg += strconv.Itoa(minute)
		msg += "分钟内)"
	}
	if diff > 0 {
		msg += ",剩余 " + strconv.Itoa(diff)
	}
	return msg
}

func (s *SyncData) TaskMsgSendDirector(ctx context.Context, msgType string, sendMsg map[string]string, mpsPerson map[string]typeManage.ResponsiblePerson, hour int, date string, lt int, isFree bool) {
	for pName, pMsg := range sendMsg {
		lastTimeKey := ""
		if isFree {
			lastTimeKey = fmt.Sprintf(LastFreeDirectorMsgSendTimeKey, date, mpsPerson[pName].Id)
		} else {
			lastTimeKey = fmt.Sprintf(LastDirectorMsgSendTimeKey, date, mpsPerson[pName].Id)
		}
		lastTime, _ := s.cache.GetCacheNum(ctx, lastTimeKey)
		if lastTime == 0 {
			lastTime = int(time.Now().Unix()) - 60*61
		}
		lttime := int(time.Now().Unix()) - lastTime
		if hour >= mpsPerson[pName].StartTime && lttime/60 >= lt {
			var personMsg = msgType //"# 活跃异常 "
			personMsg += "\n"
			personMsg += fmt.Sprintf("<font color=\"warning\">%s</font>", pMsg)
			url := mpsPerson[pName].Url
			var sendPersonData SendMsg
			sendPersonData.MsgType = "markdown"
			sendPersonData.Markdown.Content = personMsg
			global.GVA_LOG.Warn(personMsg)
			s.SendMsgData(url, sendPersonData)
			if mpsPerson[pName].Custodians != "" {
				custodiansMsg := fmt.Sprintf("<font color=\"warning\">%s的任务</font>", pName)
				custodiansMsg += "\n"
				custodiansMsg += personMsg
				var custodiansData SendMsg
				custodiansData.MsgType = "markdown"
				custodiansData.Markdown.Content = custodiansMsg
				urlCustodians := mpsPerson[mpsPerson[pName].Custodians].Url
				s.SendMsgData(urlCustodians, custodiansData)
			}
			_ = s.cache.SetCacheStr(ctx, lastTimeKey, time.Now().Unix())
		}
	}
}

func (s *SyncData) TaskMsgSendFreeDataUpdate(ctx context.Context, completesInfo []task.GameTargetComplete, ctime int64, date, lastFreeMsgSendTimeKey string, isOne bool) {
	var RateMp = make(map[int]CompletedInfo)
	lastFreeMsgSendTime, _ := s.cache.GetCacheNum(ctx, lastFreeMsgSendTimeKey)
	for _, complete := range completesInfo {
		lastPayCompletedKey := fmt.Sprintf(LastPayCompletedKey, date, complete.TaskId)
		lastPayCompletedUpdateTimeKey := fmt.Sprintf(LastPayCompletedUpdateTimeKey, date, complete.TaskId)
		lastPayAddUpdateTimeKey := fmt.Sprintf(LastPayAddUpdateTimeKey, date, complete.TaskId)
		currentPayCompleted := complete.PayComplete + complete.HandPayComplete
		payErrAddNumKey := fmt.Sprintf(PayErrAddNumKey, date, complete.TaskId)
		// 付费处理
		if complete.PayTarget != 0 && complete.PayTarget > currentPayCompleted {
			lastPayCompleted, _ := s.cache.GetCacheNum(ctx, lastPayCompletedKey)
			alsoPayTarget := complete.PayTarget - currentPayCompleted

			payRate := 0
			lastPayCompletedUpdateTime, _ := s.cache.GetCacheNum(ctx, lastPayCompletedUpdateTimeKey)
			lastPayAddUpdateTime, _ := s.cache.GetCacheNum(ctx, lastPayAddUpdateTimeKey)
			timeRate := int(ctime) - lastPayCompletedUpdateTime
			if lastPayCompleted < currentPayCompleted {
				payRate = currentPayCompleted - lastPayCompleted
				// 如有效率就初始发累加的付费数量
				_ = s.cache.SetCacheStr(ctx, payErrAddNumKey, 0)
				_ = s.cache.SetCacheStr(ctx, lastPayCompletedKey, currentPayCompleted)
				_ = s.cache.SetCacheStr(ctx, lastPayCompletedUpdateTimeKey, ctime) //上次付费更新时间
			}
			RateMp[complete.TaskId] = CompletedInfo{
				AlsoTarget:       alsoPayTarget,
				Rate:             payRate,
				TimeRate:         timeRate,
				TaskId:           complete.TaskId,
				AddPayUpdateTime: lastPayAddUpdateTime,
			}
		} else {
			// 如果当前付费为0，或者完成也更新时间
			_ = s.cache.SetCacheStr(ctx, lastPayCompletedUpdateTimeKey, ctime) //上次付费更新时间
		}
	}
	if isOne {
		_ = s.cache.SetCacheStr(ctx, lastFreeMsgSendTimeKey, time.Now().Unix())
		return
	}
	if len(RateMp) == 0 {
		global.GVA_LOG.Info("TaskMsgSendFreeData没有查询到未完成付费数据")
		return
	}
	var taskStatistics = "%s:taskStatistics"
	var retained = "# 付费播报 "
	retained += fmt.Sprintf("<font color=\"warning\">%s</font>", time.Now().Format("2006-01-02 15:04:05"))
	var errMsg = "**以下游戏付费效率为零:**"
	var errMsgZ = ""
	var sendMsg = map[string]string{}
	var m int //时间内
	m = (int(ctime) - lastFreeMsgSendTime) / 60
	mpsPerson, _ := s.Person.GetUserInfoData()
	var PErrSendMsg = make(map[string]string, len(mpsPerson))
	var mobile []string
	for taskId, data := range RateMp {
		if data.AlsoTarget <= 0 {
			continue
		}
		key := fmt.Sprintf(taskStatistics, date)
		gameIdStr := strconv.Itoa(taskId)
		gameTask, err := global.GVA_REDIS.HGet(ctx, key, gameIdStr).Result()
		if err != nil {
			if err == redis.Nil {
				continue
			} else {
				global.GVA_LOG.Error("TaskMsgSendRetainedData获取缓存任务数据失败", zap.Error(err))
				continue
			}
		}
		var taskStatistics request.TaskStatistics
		_ = json.Unmarshal([]byte(gameTask), &taskStatistics)

		var name = taskStatistics.Remark
		sendMsg[name] += "\n"
		sendMsg[name] += taskStatistics.GameName
		sendMsg[name] += ",付费差"
		//sendMsg[name] += strconv.Itoa(data.AlsoTarget)
		sendMsg[name] += fmt.Sprintf("<font color=\"warning\">%d</font>", data.AlsoTarget)

		if data.TimeRate > 60*60*24 {
			lastPayCompletedUpdateTimeKey := fmt.Sprintf(LastPayCompletedUpdateTimeKey, date, data.TaskId)
			_ = s.cache.SetCacheStr(ctx, lastPayCompletedUpdateTimeKey, ctime) //上次付费更新时间
			data.TimeRate = 60 * 60 * 2
		}
		// 单条异常记录
		oneErrM := ""
		// 5分钟数据没动报异常数据
		if data.TimeRate/60 >= 2 {
			if data.Rate == 0 {
				lastPayAddNumKey := fmt.Sprintf(LastPayAddNumKey, date, data.TaskId)
				payErrAddNumKey := fmt.Sprintf(PayErrAddNumKey, date, data.TaskId)
				numErr, _ := s.cache.GetCacheNum(context.Background(), payErrAddNumKey)
				lastAddFeeNumErr, _ := s.cache.GetCacheNum(context.Background(), lastPayAddNumKey)

				oneErrM += taskStatistics.GameName
				oneErrM += "("
				if data.TimeRate/60 >= 60 {
					oneErrM += strconv.Itoa(data.TimeRate / 60 / 60)
					oneErrM += "小时内(+" + strconv.Itoa(numErr) + "))"
				} else {
					oneErrM += strconv.Itoa(data.TimeRate / 60)
					oneErrM += "分钟内(+" + strconv.Itoa(numErr) + "))"
				}
				oneErrM += ","
				oneErrM += "最后加付费时间 "
				t := time.Unix(int64(data.AddPayUpdateTime), 0)
				oneErrM += t.Format("15:04:05")
				oneErrM += "(+" + strconv.Itoa(lastAddFeeNumErr) + ")"
				errMsgZ += "\n"
				errMsgZ += oneErrM
				if _, ok := mpsPerson[name]; ok {
					mobile = append(mobile, mpsPerson[name].MobilePhoneNumber)
				}
				if data.TimeRate/60 >= 30 {
					PErrSendMsg[name] += s.StrMontage(data.TimeRate/60, taskStatistics.GameName, ",付费", data.AlsoTarget)
					PErrSendMsg[name] += ","
					PErrSendMsg[name] += "最后加付费时间 "
					PErrSendMsg[name] += t.Format("15:04:05")
					PErrSendMsg[name] += "(+" + strconv.Itoa(lastAddFeeNumErr) + ")"
					PErrSendMsg[name] += "\n"
				}
			}
		}

		sendMsg[name] += ","
		if m >= 60 {
			sendMsg[name] += strconv.Itoa(m / 60)
			sendMsg[name] += "小时内完成"
		} else {
			sendMsg[name] += strconv.Itoa(m)
			sendMsg[name] += "分钟内完成"
		}
		//sendMsg[name] += strconv.Itoa(data.Rate)
		sendMsg[name] += fmt.Sprintf("<font color=\"warning\">%d</font>", data.Rate)
	}
	if len(sendMsg) == 0 {
		return
	}
	hour := time.Now().Hour()
	msgType := "# 付费异常 "
	go s.TaskMsgSendDirector(ctx, msgType, PErrSendMsg, mpsPerson, hour, date, 30, true)
	msg := retained
	for name, msg1 := range sendMsg {
		msg += "\n"
		msg += name
		msg += msg1
	}
	if errMsgZ != "" {
		msg += "\n"
		//msg += errMsg + errMsgZ
		msg += fmt.Sprintf("<font color=\"warning\">%s</font>", errMsg+errMsgZ)
	}
	//global.GVA_LOG.Warn(msg)
	_ = s.cache.SetCacheStr(ctx, lastFreeMsgSendTimeKey, time.Now().Unix())
	url := global.GVA_CONFIG.SendUrl.ComputerSendUrl
	var sendData SendMsg
	sendData.MsgType = "markdown"
	sendData.Markdown.Content = msg
	s.SendMsgData(url, sendData)
	if len(mobile) != 0 {
		var sendTextData SendTextMsg
		sendTextData.MsgType = "text"
		sendTextData.Text.MentionedMobileList = mobile
		s.SendMsgData(url, sendTextData)
	}
	return
}

// 加付费通知 common
//func (s *SyncData) FreeSendMsg(num, target int, taskName, director string) {
//	hour := time.Now().Hour()
//	if hour < 8 || num < 20 {
//		return
//	}
//	person, err := s.Person.GetUserInfoByName(director)
//	if err != nil {
//		global.GVA_LOG.Error("FreeSendMsg获取用户数据失败"+director, zap.Error(err))
//	}
//	if person.PushStatus != 1 {
//		return
//	}
//	personMsg := "# 加付费"
//	personMsg += fmt.Sprintf("<font color=\"warning\">%s</font>", time.Now().Format("2006-01-02 15:04:05"))
//	personMsg += "\n"
//	personMsg += taskName
//	personMsg += fmt.Sprintf("<font color=\"warning\"> 加付费 %d, 当前付费目标 %d</font>", num, target)
//	url := person.Url
//	var sendData SendMsg
//	sendData.MsgType = "markdown"
//	sendData.Markdown.Content = personMsg
//	s.SendMsgData(url, sendData)
//}

type TaskIdXmy struct {
	TaskId    int    `json:"task_id"`
	GameIdXmy string `json:"game_id_xmy"`
}

func (s *SyncData) getTaskData() []TaskIdXmy {
	db := global.GVA_DB.Table("game_task").Where("status=?", 1)
	var count int64
	db.Count(&count)
	var data = make([]TaskIdXmy, count)
	db.Find(&data)
	return data
}

type ArpuInfo struct {
	Arpu        string `json:"arpu"`
	GameId      string `json:"game_id"`
	GameName    string `json:"game_name"`
	SheepGameId string `json:"sheep_game_id"`
}

func (s *SyncData) SyncArpu() {
	url := global.GVA_CONFIG.SendUrl.GetUrlArpu
	jfparams := map[string]string{}
	jfbyteData, err := utils.HttpGet(url, jfparams)
	if err != nil {
		global.GVA_LOG.Error("SyncArpu获取arpu值失败", zap.Error(err))
	}
	var arpuInfo []ArpuInfo
	_ = json.Unmarshal(jfbyteData, &arpuInfo)
	mps := make(map[string]int, len(arpuInfo))
	for _, data := range arpuInfo {
		s := strings.Split(data.Arpu, ".")
		arpu, _ := strconv.Atoi(s[0])
		mps[data.SheepGameId] = arpu
	}
	data := s.getTaskData()
	for _, taskInfo := range data {
		if taskInfo.GameIdXmy != "" {
			if _, ok := mps[taskInfo.GameIdXmy]; ok {
				err := global.GVA_DB.Table("game_target_complete").Where("task_id = ?", taskInfo.TaskId).Where("create_date = ?", time.Now().Format("2006-01-02")).Update("aupr", mps[taskInfo.GameIdXmy]).Error
				if err != nil {
					global.GVA_LOG.Error("SyncArpu更新game_target_complete失败", zap.Error(err))
				}
			}
		}
	}
}

func (s *SyncData) RemindSendOne() {
	//url := "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=89460a48-e1a1-4181-86c0-533bad342628"
	url := global.GVA_CONFIG.SendUrl.SendUrlOne
	content := "请查看腾讯游戏是否有付费目标"
	mobile := []string{global.GVA_CONFIG.SendUrl.TxSendMobile}
	s.common.RemindSend(url, content, mobile)
}
