package log

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"
	"log-server/model/log/request"
	"log-server/model/log/response"
	loging2 "log-server/service/log/loging"
	"math"
	"strconv"
	"time"
)

type ServiceStatisticsLog struct {
	loging2.LogicalLog
}

var StatisticsCompletedKey = "%s:StatisticsCompleted"
var taskStatistics = "%s:taskStatistics"
var ComputerNum = "%s:ComputerNum"
var TaskType = []int{0, 1}

func (s *ServiceStatisticsLog) CreateStatisticsLog() {
	key := fmt.Sprintf(StatisticsCompletedKey, s.LogicalLog.CurrentDate())
	ctx := context.Background()
	b, err := s.LogicalLog.ExistsKey(ctx, key)
	if err != nil {
		global.GVA_LOG.Error("获取redis key失败!"+key, zap.Error(err))
		return
	}
	if b {
		global.GVA_LOG.Info("统计数据已完成!"+key, zap.Error(err))
		return
	}
	gameMps, err := s.LogicalLog.GetGameCache(context.Background(), s.YesterdayDate())
	if err != nil {
		global.GVA_LOG.Error("获取redis game list失败!", zap.Error(err))
		return
	}
	if len(gameMps) == 0 {
		global.GVA_LOG.Info("获取redis game list没有数据!")
		return
	}
	var statisticsLogs []*log.StatisticsLog
	for gameId, _ := range gameMps {
		for _, tt := range TaskType {
			gameIdInt, _ := strconv.Atoi(gameId)
			statisticsLogNew := new(log.StatisticsLog)
			statisticsLog := s.statisticsData(ctx, gameIdInt, tt, s.LogicalLog.YesterdayDate(), statisticsLogNew)
			if !errors.Is(global.GVA_DB.Where("create_date = ?", s.LogicalLog.YesterdayDate()).Where("game_id = ?", gameIdInt).First(&log.StatisticsLog{}).Error, gorm.ErrRecordNotFound) {
				// 已存在,跳过
				err = global.GVA_DB.Where("game_id", gameIdInt).Where("create_date = ?", s.LogicalLog.YesterdayDate()).Where("type = ?", tt).Updates(statisticsLog).Error
				if err != nil {
					global.GVA_LOG.Error("update StatisticsLogs失败!", zap.Error(err))
					continue
				}
				continue
			}
			statisticsLogs = append(statisticsLogs, statisticsLog)
		}
	}
	if len(statisticsLogs) == 0 {
		global.GVA_LOG.Info("statisticsLogsGameInfo没有数据!", zap.Error(err))
		global.GVA_REDIS.Set(ctx, key, 1, 24*time.Hour)
		return
	}
	err = global.GVA_DB.Create(statisticsLogs).Error
	if err != nil {
		global.GVA_LOG.Error("添加statisticsLogsGameInfo失败!", zap.Error(err))
		return
	}
	global.GVA_REDIS.Set(ctx, key, 1, 24*time.Hour)
	return
}

func (s *ServiceStatisticsLog) TodayCreateStatisticsGameInfoLog() {
	date := s.LogicalLog.CurrentDate()
	ctx := context.Background()
	gameMps, err := s.LogicalLog.GetGameCache(context.Background(), date)
	if err != nil {
		global.GVA_LOG.Error("获取redis game list失败!", zap.Error(err))
		return
	}
	if len(gameMps) == 0 {
		global.GVA_LOG.Info("获取redis game list没有数据!")
		return
	}
	var statisticsLogs []*log.StatisticsLog
	for gameId, _ := range gameMps {
		for _, tt := range TaskType {
			gameIdInt, _ := strconv.Atoi(gameId)
			statisticsLogNew := new(log.StatisticsLog)
			statisticsLog := s.statisticsData(ctx, gameIdInt, tt, date, statisticsLogNew)
			if !errors.Is(global.GVA_DB.Where("create_date = ?", date).Where("game_id = ?", gameIdInt).First(&log.StatisticsLog{}).Error, gorm.ErrRecordNotFound) {
				// 已存在,跳过
				err = global.GVA_DB.Where("game_id", gameIdInt).Where("create_date = ?", date).Where("type = ?", tt).Updates(statisticsLog).Error
				if err != nil {
					global.GVA_LOG.Error("update StatisticsLogs失败!", zap.Error(err))
					continue
				}
				continue
			}
			statisticsLogs = append(statisticsLogs, statisticsLog)
			if len(statisticsLogs) == 100 {
				err = global.GVA_DB.Create(statisticsLogs).Error
				if err != nil {
					global.GVA_LOG.Error("添加statisticsLogs失败!", zap.Error(err))
					return
				}
				statisticsLogs = []*log.StatisticsLog{}
			}
		}
	}
	if len(statisticsLogs) == 0 {
		global.GVA_LOG.Info("statisticsLogsGameInfo没有数据!", zap.Error(err))
		return
	}
	err = global.GVA_DB.Create(statisticsLogs).Error
	if err != nil {
		global.GVA_LOG.Error("添加statisticsLogsGameInfo失败!", zap.Error(err))
		return
	}
	return
}

func (s *ServiceStatisticsLog) TodayStatisticsLogList(ctx context.Context, api log.StatisticsLog, info request.PageInfo) (interface{}, int64, error) {
	db := global.GVA_DB.Model(&log.StatisticsLog{})
	if api.GameId != 0 {
		db = db.Where("game_id = ?", api.GameId)
	}
	db = db.Where("create_date = ?", s.CurrentDate())
	var total int64
	err := db.Count(&total).Error
	if err != nil {
		return nil, 0, err
	}
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var statisticsLogs []*log.StatisticsLog
	var statisticsLogs2 []*log.StatisticsLog
	db = db.Limit(limit).Offset(offset)
	err = db.Order("id").Find(&statisticsLogs).Error
	for _, gameInfo := range statisticsLogs {
		tt := gameInfo.Type
		gameIdInt := gameInfo.GameId
		statisticsLogNew := new(log.StatisticsLog)
		statisticsLog := s.statisticsData(ctx, gameIdInt, tt, s.LogicalLog.CurrentDate(), statisticsLogNew)
		statisticsLogs2 = append(statisticsLogs2, statisticsLog)
	}
	return statisticsLogs2, total, err
}

func (s *ServiceStatisticsLog) statisticsData(ctx context.Context, gameIdInt, tt int, date string, statisticsLog *log.StatisticsLog) *log.StatisticsLog {
	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("添加缓存数据失败TaskStatisticsDataCache", zap.Error(err))
		} else {
			global.GVA_LOG.Error("添加缓存数据失败TaskStatisticsDataCache", zap.Error(err))
			return nil
		}

	}
	var taskStatistics request.TaskStatistics
	_ = json.Unmarshal([]byte(data), &taskStatistics)
	pullAccountOk, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4100000", loging2.OkStatus, tt)
	pullAccountFail, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4100000", loging2.FailStatus, tt)
	ConstituencyFail, _ := s.LogicalLog.TypeLogGetNum(ctx, date, gameIdInt, "4604000", loging2.FailStatus, tt)
	ConstituencyOk, _ := s.LogicalLog.TypeLogGetNum(ctx, date, gameIdInt, "4604000", loging2.OkStatus, tt)
	StartProxyFail, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4200000", loging2.FailStatus, tt)
	StartProxyOk, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4200000", loging2.OkStatus, tt)
	SimulatorStartFail, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4300000", loging2.FailStatus, tt)
	SimulatorStartOk, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4300000", loging2.OkStatus, tt)
	NetworkCheckFail, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4400000", loging2.FailStatus, tt)
	NetworkCheckOk, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4400000", loging2.OkStatus, tt)
	GameStartFail, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4500000", loging2.FailStatus, tt)
	GameStartOk, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4500000", loging2.OkStatus, tt)
	xmyLoginFail, _ := s.LogicalLog.TypeLogGetNum(ctx, date, gameIdInt, "4601000", loging2.FailStatus, tt)
	xmyLoginOk, _ := s.LogicalLog.TypeLogGetNum(ctx, date, gameIdInt, "4601000", loging2.OkStatus, tt)
	wxLoginFail, _ := s.LogicalLog.TypeLogGetNum(ctx, date, gameIdInt, "4602000", loging2.FailStatus, tt)
	wxLoginOk, _ := s.LogicalLog.TypeLogGetNum(ctx, date, gameIdInt, "4602000", loging2.OkStatus, tt)
	mzLoginFail, _ := s.LogicalLog.TypeLogGetNum(ctx, date, gameIdInt, "4603000", loging2.FailStatus, tt)
	mzLoginOk, _ := s.LogicalLog.TypeLogGetNum(ctx, date, gameIdInt, "4603000", loging2.OkStatus, tt)
	LoginFail := xmyLoginFail + wxLoginFail + mzLoginFail
	LoginOk := xmyLoginOk + wxLoginOk + mzLoginOk
	EnterMainFail, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4700000", loging2.FailStatus, tt)
	EnterMainOk, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4700000", loging2.OkStatus, tt)
	FeeFail, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4800000", loging2.FailStatus, tt)
	FeeOk, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4800000", loging2.OkStatus, tt)
	ScriptStartFail, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4300000", loging2.FailStatus, tt)
	ScriptStartOk, _ := s.LogicalLog.NodeLogGetNum(ctx, date, gameIdInt, "4300000", loging2.OkStatus, tt)
	EnterGameFail, _ := s.LogicalLog.TypeLogGetNum(ctx, date, gameIdInt, "4605000", loging2.FailStatus, tt)
	EnterGameOk, _ := s.LogicalLog.TypeLogGetNum(ctx, date, gameIdInt, "4605000", loging2.OkStatus, tt)
	AuthenticationFail, _ := s.LogicalLog.TypeLogGetNum(ctx, date, gameIdInt, "4607000", loging2.FailStatus, tt)
	AuthenticationOk, _ := s.LogicalLog.TypeLogGetNum(ctx, date, gameIdInt, "4607000", loging2.OkStatus, tt)
	EnterStartGame, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4501000", loging2.NoLogStatus, tt)
	EnterAuthentication, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4607000", loging2.NoLogStatus, tt)
	EnterConstituency, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4604000", loging2.NoLogStatus, tt)
	EnterGame, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4605000", loging2.NoLogStatus, tt)
	EnterMain, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4701000", loging2.NoLogStatus, tt)
	EnterFee, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4800000", loging2.NoLogStatus, tt)
	EnterXmyLogin, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4601000", loging2.NoLogStatus, tt)
	EnterWxLogin, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4602000", loging2.NoLogStatus, tt)
	EnterMzLogin, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4603000", loging2.NoLogStatus, tt)
	BanOff1, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4601006", loging2.FailStatus, tt) // 小绵羊登录封号
	BanOff2, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4602008", loging2.FailStatus, tt) // 微信登录封号
	BanOff3, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4603006", loging2.FailStatus, tt) // 魅族登录封号
	BanOff4, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4701003", loging2.FailStatus, tt) // 主线封号
	Freeze, _ := s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4809904", loging2.NoLogStatus, tt) // 冻结
	BanOff := BanOff1 + BanOff2 + BanOff3 + BanOff4
	EnterLogin := EnterXmyLogin + EnterMzLogin + EnterWxLogin
	//statisticsLog.NewHaveRole, _ = s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4604004", loging2.NoLogStatus, tt) // 新增有角色
	//statisticsLog.RetainedNotRole, _ = s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4604003", loging2.NoLogStatus, tt) // 留存无角色
	statisticsLog.PullAccountOk = pullAccountOk
	statisticsLog.PullAccountFail = pullAccountFail
	statisticsLog.StartProxyFail = StartProxyFail
	statisticsLog.StartProxyOk = StartProxyOk
	statisticsLog.SimulatorStartFail = SimulatorStartFail
	statisticsLog.SimulatorStartOk = SimulatorStartOk
	statisticsLog.NetworkCheckFail = NetworkCheckFail
	statisticsLog.NetworkCheckOk = NetworkCheckOk
	statisticsLog.EnterMainFail = EnterMainFail
	statisticsLog.EnterMainOk = EnterMainOk
	statisticsLog.EnterGameFail = EnterGameFail
	statisticsLog.EnterGameOk = EnterGameOk
	statisticsLog.GameId = gameIdInt
	statisticsLog.ConstituencyFail = ConstituencyFail
	statisticsLog.ConstituencyOk = ConstituencyOk
	statisticsLog.FeeFail = FeeFail
	statisticsLog.FeeOk = FeeOk
	statisticsLog.GameStartFail = GameStartFail
	statisticsLog.GameStartOk = GameStartOk
	statisticsLog.LoginFail = LoginFail
	statisticsLog.LoginOk = LoginOk
	statisticsLog.XmyLoginFail = xmyLoginFail
	statisticsLog.XmyLoginOk = xmyLoginOk
	statisticsLog.WxLoginFail = wxLoginFail
	statisticsLog.WxLoginOk = wxLoginOk
	statisticsLog.MzLoginFail = mzLoginFail
	statisticsLog.MzLoginOk = mzLoginOk
	statisticsLog.ScriptStartFail = ScriptStartFail
	statisticsLog.ScriptStartOk = ScriptStartOk
	statisticsLog.AuthenticationFail = AuthenticationFail
	statisticsLog.AuthenticationOk = AuthenticationOk

	statisticsLog.EnterStartGame = EnterStartGame
	statisticsLog.EnterAuthentication = EnterAuthentication
	statisticsLog.EnterConstituency = EnterConstituency
	statisticsLog.EnterGame = EnterGame
	statisticsLog.EnterMain = EnterMain
	statisticsLog.EnterFee = EnterFee
	statisticsLog.EnterLogin = EnterLogin
	statisticsLog.BanOff = BanOff
	statisticsLog.Freeze = Freeze
	statisticsLog.Type = tt
	statisticsLog.CreateTime = time.Now().Format("2006-01-02 15:04:05")
	statisticsLog.CreateDate = date
	if tt == 1 {
		statisticsLog.NotRole, _ = s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4609901", loging2.NoLogStatus, tt)
		statisticsLog.HasRole = 0
		statisticsLog.IssuedAccount = taskStatistics.RetainedPullAccount
		statisticsLog.TargetNum = taskStatistics.RetainedTarget
		statisticsLog.TargetCompleteNum = taskStatistics.RetainedComplete
		statisticsLog.ScanningSuccessRate = 0
	} else {
		statisticsLog.NotRole = 0
		statisticsLog.HasRole, _ = s.LogicalLog.CodeLogGetNum(ctx, date, gameIdInt, "4609902", loging2.NoLogStatus, tt)
		statisticsLog.IssuedAccount = taskStatistics.NewPullAccount
		statisticsLog.TargetCompleteNum = taskStatistics.NewComplete
		statisticsLog.TargetNum = taskStatistics.NewTarget
		statisticsLog.NewScanningCode = taskStatistics.NewScanningCode
		if statisticsLog.NewScanningCode != 0 {
			statisticsLog.ScanningSuccessRate = float64(statisticsLog.TargetNum) / float64(statisticsLog.NewScanningCode) * 100
		}
	}
	statisticsLog.PayComplete = taskStatistics.PayComplete
	statisticsLog.PayTarget = taskStatistics.PayTarget
	statisticsLog.OrderCreate = taskStatistics.OrderCreate
	statisticsLog.OrderSuccess = taskStatistics.OrderSuccess
	statisticsLog.RetainedAccountNum = taskStatistics.RetainedAccountNum
	statisticsLog.FeeAccountNum = taskStatistics.FeeAccountNum
	statisticsLog.Operator = taskStatistics.Remark
	statisticsLog.GameName = taskStatistics.GameName
	if statisticsLog.IssuedAccount != 0 {
		statisticsLog.PullSuccessRate = float64(statisticsLog.PullAccountOk) / float64(statisticsLog.IssuedAccount) * 100
	}
	if statisticsLog.PullAccountOk != 0 {
		statisticsLog.StartSuccessRate = float64(statisticsLog.SimulatorStartOk) / float64(statisticsLog.PullAccountOk) * 100
	}
	if statisticsLog.GameStartOk != 0 {
		statisticsLog.MainSuccessRate = float64(statisticsLog.EnterMain) / float64(statisticsLog.GameStartOk) * 100
	}
	if statisticsLog.TargetNum != 0 {
		statisticsLog.TaskSuccessRate = float64(statisticsLog.EnterMain) / float64(statisticsLog.TargetNum) * 100
	}
	if statisticsLog.OrderCreate != 0 {
		statisticsLog.LocalOrderSuccessRate = float64(statisticsLog.FeeOk) / float64(statisticsLog.OrderCreate) * 100
	}

	return statisticsLog
}

func (s *ServiceStatisticsLog) OtherStatisticsLogList(ctx context.Context, api log.StatisticsLog, info request.PageInfo, order string, desc bool) (interface{}, int64, error) {
	date := api.CreateDate
	if date == "" {
		date = s.CurrentDate()
	}

	db := global.GVA_DB.Model(&log.StatisticsLog{})
	if api.GameId != 0 {
		db = db.Where("game_id = ?", api.GameId)
	}
	db = db.Where("create_date = ?", date)
	var total int64
	err := db.Count(&total).Error
	if err != nil {
		return nil, 0, err
	}
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var statisticsLogs []*log.StatisticsLog
	db = db.Limit(limit).Offset(offset)
	if order != "" {
		var OrderStr string
		// 设置有效排序key 防止sql注入
		// 感谢 Tom4t0 提交漏洞信息
		orderMap := make(map[string]bool, 7)
		orderMap["pull_success_rate"] = true
		orderMap["start_success_rate"] = true
		orderMap["main_success_rate"] = true
		orderMap["task_success_rate"] = true
		orderMap["scanning_success_rate"] = true
		orderMap["local_order_success_rate"] = true
		orderMap["game_id"] = true
		if orderMap[order] {
			if desc {
				OrderStr = order + " desc"
			} else {
				OrderStr = order
			}
		} else { // didn't matched any order key in `orderMap`
			global.GVA_LOG.Error("获取失败!", zap.Error(err))
			return statisticsLogs, total, err
		}

		err = db.Order(OrderStr).Find(&statisticsLogs).Error
	} else {
		err = db.Order("id").Find(&statisticsLogs).Error
	}
	if err != nil {
		return nil, 0, err
	}
	for _, statisticsLog := range statisticsLogs {
		statisticsLog.CreateDate = statisticsLog.CreateDate[:10]
	}
	return statisticsLogs, total, err
}

func (s *ServiceStatisticsLog) StatisticsNodeLogList(ctx context.Context, api log.StatisticsLog, info request.PageInfo, order string, desc bool) (interface{}, int64, error) {
	date := api.CreateDate
	if date == "" || date == s.CurrentDate() {
		apilist, total, err := s.TodayStatisticsLogList(ctx, api, info)
		return apilist, total, err
	}

	db := global.GVA_DB.Model(&log.StatisticsLog{})
	if api.GameId != 0 {
		db = db.Where("game_id = ?", api.GameId)
	}
	db = db.Where("create_date = ?", date)
	var total int64
	err := db.Count(&total).Error
	if err != nil {
		return nil, 0, err
	}
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var statisticsLogs []*log.StatisticsLog
	db = db.Limit(limit).Offset(offset)
	err = db.Order("id").Find(&statisticsLogs).Error
	if err != nil {
		return nil, 0, err
	}
	for _, statisticsLog := range statisticsLogs {
		statisticsLog.CreateDate = statisticsLog.CreateDate[:10]
	}
	return statisticsLogs, total, err
}

func (s *ServiceStatisticsLog) ResetStatisticsLog(ctx context.Context, gameId int, date string) {
	var total int64
	key := date + ":" + strconv.Itoa(gameId) + ":reset"
	global.GVA_REDIS.Set(ctx, key, 1, time.Minute*15)
	db := global.GVA_DB.Table("loging")
	db = db.Where("game_id = ?", gameId)
	err := db.Count(&total).Error
	if err != nil {
		global.GVA_LOG.Error("重置统计数据总数报错", zap.Error(err))
		return
	}
	limit := 100
	num := int(math.Ceil(float64(total) / float64(limit)))
	offset := 0
	err = s.LogicalLog.DelStatisticsNumCache(ctx, date, gameId)
	if err != nil {
		global.GVA_LOG.Error("重置统计数据删除缓存报错", zap.Error(err))
		return
	}
	err = s.LogicalLog.DelUuidCodeCache(ctx, date, gameId)
	if err != nil {
		global.GVA_LOG.Error("重置统计数据删除缓存报错2", zap.Error(err))
		return
	}
	global.GVA_LOG.Info("num = " + strconv.Itoa(num))
	for i := 0; i < num; i++ {
		global.GVA_LOG.Info("offset = " + strconv.Itoa(offset))
		var statisticsLogs []request.AddLogRequest
		db2 := global.GVA_DB.Table("loging")
		db2 = db2.Where("create_date = ?", date)
		db2 = db2.Where("game_id = ?", gameId)
		db2 = db2.Limit(limit).Offset(offset)
		err = db2.Order("id").Find(&statisticsLogs).Error
		for _, statisticsLog := range statisticsLogs {

			s.ResetStatisticsCache(ctx, statisticsLog, date)
		}
		offset += limit
	}
	global.GVA_LOG.Info("重置统计数据完成")
}

func (s *ServiceStatisticsLog) ResetStatisticsCache(c context.Context, api request.AddLogRequest, date string) {
	coding := strconv.Itoa(api.Coding)
	nodeCoding := coding[:3]
	status := coding[5:]
	noLogStatus := coding[3:5]
	var logical ServiceResetLoging
	switch nodeCoding {
	case "410":
		logical = new(loging2.ResetLog)
		break
	case "430":
		logical = new(loging2.ResetLog)
		break
	default:
		logical = new(loging2.ResetOtherLog)
		break
	}
	var err error
	if status == "99" {
		err = logical.SuccessLog(c, api, date)
	} else if noLogStatus == "99" {
		err = logical.NoLogStatusData(c, api, date)
	} else {
		err = logical.FailLog(c, api, date)
	}
	if err != nil {
		global.GVA_LOG.Error("创建失败!", zap.Error(err))
	}
}

// 每天凌晨reset统计数据
func (s *ServiceStatisticsLog) EveryDayResetStatisticsCache() {
	date := s.YesterdayDate()
	ctx := context.Background()
	gameMps, err := s.LogicalLog.GetGameCache(ctx, date)
	if err != nil {
		global.GVA_LOG.Error("获取redis game list失败!", zap.Error(err))
		return
	}
	if len(gameMps) == 0 {
		global.GVA_LOG.Info("获取redis game list没有数据!")
		return
	}
	for gameId, _ := range gameMps {
		id, _ := strconv.Atoi(gameId)
		s.ResetStatisticsLog(ctx, id, date)
	}
	global.GVA_LOG.Info("游戏重置缓存完成!")
}

func (s *ServiceStatisticsLog) CreateComputerStatisticsData() {
	ctx := context.Background()
	codeMps, err := s.LogicalLog.GetComputerCache(ctx, s.LogicalLog.CurrentDate())
	if err != nil {
		return
	}
	if len(codeMps) == 0 {
		return
	}
	key := fmt.Sprintf(taskStatistics, s.LogicalLog.CurrentDate())
	onlineComputerMpa, _ := s.LogicalLog.GetOnlineComputerNumCache(ctx, s.LogicalLog.CurrentDate())
	fmt.Println(onlineComputerMpa)
	var csReplys []*log.LogComputer
	for code, r := range codeMps {
		accountMps, err := s.LogicalLog.GetComputerPullAccountNumCache(ctx, s.LogicalLog.CurrentDate(), code)
		if err != nil {
			continue
		}
		taskMps, err := s.LogicalLog.GetComputerTaskSuccessNumCache(ctx, s.LogicalLog.CurrentDate(), code)
		if err != nil {
			continue
		}
		enterMainMps, err := s.LogicalLog.GetComputerEnterMainNumCache(ctx, s.LogicalLog.CurrentDate(), code)
		if err != nil {
			continue
		}

		for gameId, num := range accountMps {
			csReply := new(log.LogComputer)
			if _, ok := onlineComputerMpa[csReply.PcCode]; ok {
				delete(onlineComputerMpa, csReply.PcCode)
			}
			csReply.PcCode = code
			csReply.Operator = r
			data, err := global.GVA_REDIS.HGet(ctx, key, gameId).Result()
			if err != nil {
				if err == redis.Nil {
					global.GVA_LOG.Info("添加缓存数据失败TaskStatisticsDataCache", zap.Error(err))
				} else {
					global.GVA_LOG.Error("添加缓存数据失败TaskStatisticsDataCache", zap.Error(err))
					return
				}

			}
			var taskStatistics request.TaskStatistics
			_ = json.Unmarshal([]byte(data), &taskStatistics)
			csReply.GameId, _ = strconv.Atoi(gameId)
			csReply.PullAccountNum = num
			csReply.TaskSuccessNum = taskMps[gameId]
			csReply.EnterMain = enterMainMps[gameId]
			csReply.CreateDate = time.Now().Format("2006-01-02")
			csReply.TargetNum = taskStatistics.NewTarget + taskStatistics.RetainedTarget
			csReply.ComputerFeeRate = s.GetStatisticsPcFeeRate(ctx, csReply.PcCode, csReply.GameId)
			csReply.ComputerFreeTime = s.GetStatisticsComputerRate(ctx, csReply.PcCode)
			csReply.GameFeeRate = s.GetStatisticsFeeRate(ctx, csReply.GameId)
			runTime := time.Now().Hour() + 1 - csReply.ComputerFreeTime
			csReply.ComputerHourAverageRate = csReply.TaskSuccessNum / runTime
			global.GVA_DB.Where("create_date = ?", csReply.CreateDate).Where("pc_code = ?", csReply.PcCode).Where("game_id = ?", 0).Delete(&log.LogComputer{})
			if !errors.Is(global.GVA_DB.Where("create_date = ?", csReply.CreateDate).Where("pc_code = ?", csReply.PcCode).First(&log.LogComputer{}).Error, gorm.ErrRecordNotFound) {
				// 已存在,更新
				mp := make(map[string]interface{})
				if csReply.Operator != "" {
					mp["operator"] = csReply.Operator
				}
				mp["target_num"] = taskStatistics.NewTarget + taskStatistics.RetainedTarget
				mp["pull_account_num"] = num
				mp["task_success_num"] = taskMps[gameId]
				mp["computer_fee_rate"] = csReply.ComputerFeeRate
				mp["computer_free_time"] = csReply.ComputerFreeTime
				mp["game_fee_rate"] = csReply.GameFeeRate
				mp["computer_hour_average_rate"] = csReply.ComputerHourAverageRate
				mp["enter_main"] = csReply.EnterMain
				err = global.GVA_DB.Table("log_computer").Where("create_date = ?", csReply.CreateDate).Where("pc_code = ?", csReply.PcCode).Updates(mp).Error
				if err != nil {
					global.GVA_LOG.Error("更新数据失败", zap.Error(err))
				}
				continue
			}
			csReplys = append(csReplys, csReply)
		}
	}
	if len(csReplys) != 0 {
		err = global.GVA_DB.Table("log_computer").Create(csReplys).Error
		if err != nil {
			global.GVA_LOG.Error("更新数据失败", zap.Error(err))
		}
	}
	// 在线电脑没有跑数据记录
	if len(onlineComputerMpa) != 0 {
		var onlineComputer []*log.LogComputer
		for pcCode, op := range onlineComputerMpa {
			csReply := new(log.LogComputer)
			csReply.PcCode = pcCode
			csReply.Operator = op
			csReply.CreateDate = time.Now().Format("2006-01-02")
			if !errors.Is(global.GVA_DB.Where("create_date = ?", csReply.CreateDate).Where("pc_code = ?", csReply.PcCode).First(&log.LogComputer{}).Error, gorm.ErrRecordNotFound) {
				continue
			}
			onlineComputer = append(onlineComputer, csReply)
		}
		if len(onlineComputer) != 0 {
			err = global.GVA_DB.Table("log_computer").Create(onlineComputer).Error
			if err != nil {
				global.GVA_LOG.Error("更新数据失败", zap.Error(err))
			}
		}
	}

	return
}

func (s *ServiceStatisticsLog) ComputerStatistics(ctx context.Context, api log.LogComputer, info request.PageInfo, order string, desc bool) (interface{}, int64, error) {
	date := api.CreateDate
	isCurrentDate := false
	if date == "" {
		date = s.CurrentDate()
		isCurrentDate = true
	}
	db := global.GVA_DB.Model(&log.LogComputer{})
	var total int64
	db = db.Where("create_date = ?", date)
	if api.Operator != "" {
		db = db.Where("operator = ?", api.Operator)
	}
	if api.PcCode != "" {
		db = db.Where("pc_code = ?", api.PcCode)
	}
	if api.GameId != 0 {
		db = db.Where("game_id = ?", api.GameId)
	}
	err := db.Count(&total).Error
	if err != nil {
		return nil, 0, err
	}
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var statisticsLogs []*log.LogComputer
	db = db.Limit(limit).Offset(offset)
	if order != "" {
		var OrderStr string
		// 设置有效排序key 防止sql注入
		// 感谢 Tom4t0 提交漏洞信息
		orderMap := make(map[string]bool, 3)
		orderMap["pc_code"] = true
		orderMap["game_id"] = true
		orderMap["operator"] = true
		if orderMap[order] {
			if desc {
				OrderStr = order + " desc"
			} else {
				OrderStr = order
			}
		} else { // didn't matched any order key in `orderMap`
			global.GVA_LOG.Error("获取失败!", zap.Error(err))
			return statisticsLogs, total, err
		}
		err = db.Order(OrderStr).Find(&statisticsLogs).Error
	} else {
		err = db.Order("id").Find(&statisticsLogs).Error
	}
	if err != nil {
		return nil, 0, err
	}
	var statisticsLogsComputer []*response.ComputerStatisticsReply1

	for _, statisticsLog := range statisticsLogs {
		/*var gameInfo []*response.GameInfo
		err = json.Unmarshal([]byte(statisticsLog.GameInfo), &gameInfo)
		for i, _ := range gameInfo {
			statisticsLogComputer := new(response.ComputerStatisticsReply1)
			statisticsLogComputer.GameInfo = gameInfo
			statisticsLogComputer.PcCode = statisticsLog.PcCode
			statisticsLogComputer.Operator = statisticsLog.Operator
			statisticsLogComputer.CreateDate = statisticsLog.CreateDate[:10]
			statisticsLogComputer.GameId = gameInfo[i].GameId
			statisticsLogComputer.PullAccountNum = gameInfo[i].PullAccountNum
			statisticsLogComputer.TaskSuccessNum = gameInfo[i].TaskSuccessNum
			statisticsLogsComputer = append(statisticsLogsComputer, statisticsLogComputer)
		}*/
		//gameIdStr:=strconv.Itoa(statisticsLog.GameId)
		//taskStatistics := s.GameTargetInfo(ctx,s.LogicalLog.CurrentDate(),gameIdStr)
		statisticsLogComputer := new(response.ComputerStatisticsReply1)
		statisticsLogComputer.PcCode = statisticsLog.PcCode
		statisticsLogComputer.Operator = statisticsLog.Operator
		statisticsLogComputer.CreateDate = statisticsLog.CreateDate[:10]
		statisticsLogComputer.GameId = statisticsLog.GameId
		statisticsLogComputer.PullAccountNum = statisticsLog.PullAccountNum
		statisticsLogComputer.TaskSuccessNum = statisticsLog.TaskSuccessNum
		statisticsLogComputer.TargetNum = statisticsLog.TargetNum
		statisticsLogComputer.ComputerFreeTime = statisticsLog.ComputerFreeTime
		statisticsLogComputer.ComputerFeeRate = statisticsLog.ComputerFeeRate
		statisticsLogComputer.EnterMain = statisticsLog.EnterMain
		if isCurrentDate {
			statisticsLogComputer.ComputerFeeRate = s.GetStatisticsPcFeeRate(ctx, statisticsLog.PcCode, statisticsLog.GameId)
		}
		statisticsLogComputer.ComputerHourAverageRate = statisticsLog.ComputerHourAverageRate
		statisticsLogsComputer = append(statisticsLogsComputer, statisticsLogComputer)
	}
	return statisticsLogsComputer, total, err
}

// 在线电脑
func (s *ServiceStatisticsLog) OnlineComputerStatistics(ctx context.Context, api log.LogComputer, info request.PageInfo, order string, desc bool) (interface{}, int64, error) {
	date := api.CreateDate
	if date == "" {
		date = s.CurrentDate()
	}
	db := global.GVA_DB.Model(&log.LogComputer{})
	var total int64
	db = db.Where("create_date = ?", date)
	if api.Operator != "" {
		db = db.Where("operator = ?", api.Operator)
	}
	if api.PcCode != "" {
		db = db.Where("pc_code = ?", api.PcCode)
	}
	db = db.Group("pc_code")
	err := db.Count(&total).Error
	if err != nil {
		return nil, 0, err
	}
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var statisticsLogs []*log.LogComputer
	db = db.Limit(limit).Offset(offset)
	if order != "" {
		var OrderStr string
		// 设置有效排序key 防止sql注入
		// 感谢 Tom4t0 提交漏洞信息
		orderMap := make(map[string]bool, 3)
		orderMap["pc_code"] = true
		orderMap["operator"] = true
		if orderMap[order] {
			if desc {
				OrderStr = order + " desc"
			} else {
				OrderStr = order
			}
		} else { // didn't matched any order key in `orderMap`
			global.GVA_LOG.Error("获取失败!", zap.Error(err))
			return statisticsLogs, total, err
		}
		err = db.Order(OrderStr).Find(&statisticsLogs).Error
	} else {
		err = db.Order("id").Find(&statisticsLogs).Error
	}
	if err != nil {
		return nil, 0, err
	}
	var statisticsLogsComputer []*response.ComputerStatisticsReply1

	for _, statisticsLog := range statisticsLogs {
		statisticsLogComputer := new(response.ComputerStatisticsReply1)
		statisticsLogComputer.PcCode = statisticsLog.PcCode
		statisticsLogComputer.Operator = statisticsLog.Operator
		statisticsLogComputer.CreateDate = statisticsLog.CreateDate[:10]
		statisticsLogComputer.GameId = statisticsLog.GameId
		statisticsLogComputer.PullAccountNum = statisticsLog.PullAccountNum
		statisticsLogComputer.TaskSuccessNum = statisticsLog.TaskSuccessNum
		statisticsLogComputer.TargetNum = statisticsLog.TargetNum
		statisticsLogComputer.ComputerFreeTime = statisticsLog.ComputerFreeTime
		statisticsLogComputer.ComputerFeeRate = statisticsLog.ComputerFeeRate
		statisticsLogComputer.EnterMain = statisticsLog.EnterMain
		statisticsLogComputer.ComputerHourAverageRate = statisticsLog.ComputerHourAverageRate
		statisticsLogsComputer = append(statisticsLogsComputer, statisticsLogComputer)
	}
	return statisticsLogsComputer, total, err
}

//根据游戏id查询数据
func (s *ServiceStatisticsLog) GameStatistics(ctx context.Context, api log.LogComputer, info request.PageInfo) (interface{}, int64, error) {
	date := api.CreateDate
	isCurrentDate := false
	if date == "" {
		date = s.CurrentDate()
		isCurrentDate = true
	}
	db := global.GVA_DB.Model(&log.LogComputer{})
	var total int64
	db = db.Where("create_date = ?", date)
	if api.Operator != "" {
		db = db.Where("operator = ?", api.Operator)
	}
	if api.PcCode != "" {
		db = db.Where("pc_code = ?", api.PcCode)
	}
	if api.GameId != 0 {
		db = db.Where("game_id = ?", api.GameId)
	}
	db = db.Select("SUM(task_success_num) task_success_total,count(pc_code) pc_code_total,game_id,create_date,SUM(computer_free_time) computer_free_time_total,SUM(computer_hour_average_rate) computer_hour_average_total,SUM(enter_main) enter_main_total,game_fee_rate,target_num").Group("game_id")
	err := db.Count(&total).Error
	if err != nil {
		return nil, 0, err
	}
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var statisticsLogsByGameId []*response.GameIdStatisticsReply

	db = db.Limit(limit).Offset(offset)
	err = db.Order("id").Find(&statisticsLogsByGameId).Error
	if err != nil {
		return nil, 0, err
	}

	for _, statisticsLog := range statisticsLogsByGameId {
		statisticsLog.CreateDate = statisticsLog.CreateDate[:10]
		statisticsLog.OneComputerAverageNum = statisticsLog.TaskSuccessTotal / statisticsLog.PcCodeTotal
		if isCurrentDate {
			statisticsLog.GameFeeRate = s.GetStatisticsFeeRate(ctx, statisticsLog.GameId)
		}
	}
	return statisticsLogsByGameId, total, err
}

func (s *ServiceStatisticsLog) GameTargetInfo(ctx context.Context, date string, gameId string) (taskStatistics1 request.TaskStatistics) {
	key := fmt.Sprintf(taskStatistics, date)
	data, err := global.GVA_REDIS.HGet(ctx, key, gameId).Result()
	if err != nil {
		if err == redis.Nil {
			global.GVA_LOG.Info("TaskStatisticsDataCache"+key+gameId, zap.Error(err))
		} else {
			global.GVA_LOG.Error("添加缓存数据失败TaskStatisticsDataCache"+key, zap.Error(err))
			return
		}

	}
	_ = json.Unmarshal([]byte(data), &taskStatistics1)
	return
}

// 同步群控任务数据到缓存
func (s *ServiceStatisticsLog) TaskStatisticsDataCache() {
	ctx := context.Background()
	key := fmt.Sprintf(taskStatistics, s.LogicalLog.CurrentDate())
	data, err := s.LogicalLog.RequestJfRoom()
	if err != nil {
		global.GVA_LOG.Error("获取机房数据失败TaskStatisticsDataCache", zap.Error(err))
		return
	}
	dataTask, err := s.LogicalLog.RequestTaskData()
	if err != nil {
		global.GVA_LOG.Error("RequestTaskData", zap.Error(err))
		return
	}
	var taskData []request.TaskData
	var taskStatistics []request.TaskStatistics
	_ = json.Unmarshal(data, &taskStatistics)
	_ = json.Unmarshal(dataTask, &taskData)
	mps := map[int]request.TaskData{}
	for _, td := range taskData {
		mps[td.GameId] = td
	}
	for _, data := range taskStatistics {
		var id int
		id = data.GameId
		if _, ok := mps[id]; ok {
			data.NewScanningCode = mps[id].NewScanningCode
			data.RetainedPullAccount = mps[id].RetainedPullAccount
			data.NewPullAccount = mps[id].NewPullAccount
			data.FeeAccountNum = mps[id].FeeAccountNum
			data.RetainedAccountNum = mps[id].RetainedAccountNum
		}
		bd, _ := json.Marshal(data)
		err = global.GVA_REDIS.HSet(ctx, key, id, bd).Err()
		if err != nil {
			global.GVA_LOG.Error("添加缓存数据失败TaskStatisticsDataCache", zap.Error(err))
			return
		}
	}
}

// 同步群控任务数据到缓存
func (s *ServiceStatisticsLog) TaskStatisticsDataCache1() {
	ctx := context.Background()
	key := fmt.Sprintf(taskStatistics, s.LogicalLog.CurrentDate())
	data, err := s.LogicalLog.RequestJfRoom()
	if err != nil {
		global.GVA_LOG.Error("获取机房数据失败TaskStatisticsDataCache", zap.Error(err))
		return
	}
	dataTask, err := s.LogicalLog.RequestTaskData()
	if err != nil {
		global.GVA_LOG.Error("RequestTaskData", zap.Error(err))
		return
	}
	var taskData []request.TaskData
	var taskStatistics []request.TaskStatistics
	_ = json.Unmarshal(data, &taskStatistics)
	_ = json.Unmarshal(dataTask, &taskData)
	mps := map[int]request.TaskData{}
	for _, td := range taskData {
		mps[td.GameId] = td
	}
	for _, data := range taskStatistics {
		var id int
		if data.GameIdXmy != "" {
			if data.GameIdXmy == "0" {
				id = data.GameId
			} else {
				id, _ = strconv.Atoi(data.GameIdXmy)
			}
		} else {
			id = data.GameId
		}
		if _, ok := mps[id]; ok {
			data.NewScanningCode = mps[id].NewScanningCode
			data.RetainedPullAccount = mps[id].RetainedPullAccount
			data.NewPullAccount = mps[id].NewPullAccount
			data.FeeAccountNum = mps[id].FeeAccountNum
			data.RetainedAccountNum = mps[id].RetainedAccountNum
		}
		bd, _ := json.Marshal(data)
		err = global.GVA_REDIS.HSet(ctx, key, id, bd).Err()
		if err != nil {
			global.GVA_LOG.Error("添加缓存数据失败TaskStatisticsDataCache", zap.Error(err))
			return
		}
	}
}

// 同步群控任务数据到缓存
func (s *ServiceStatisticsLog) GetComputerNum(date string) int64 {
	var total int64
	if date == "" {
		date = s.CurrentDate()
	}
	db := global.GVA_DB.Model(&log.LogComputer{})
	db = db.Distinct("pc_code").Where("create_date = ?", date)
	_ = db.Count(&total).Error
	return total
}

// 在线电脑接口
func (s *ServiceStatisticsLog) ComputerHeartbeat(c context.Context, onlineComputer request.OnlineComputerRequest) error {
	err := s.LogicalLog.SetOnlineComputerNumCache(c, s.LogicalLog.CurrentDate(), onlineComputer.PcCode, onlineComputer.Operator)
	return err
}

// 在线电脑接口测试
func (s *ServiceStatisticsLog) ComputerTest(c context.Context) (interface{}, error) {
	mps, err := s.LogicalLog.GetOnlineComputerNumCache(c, s.LogicalLog.CurrentDate())
	if err != nil {
		return mps, err
	}
	return mps, err
}
