package dataStatistics

import (
	"context"
	"errors"
	"github.com/bitly/go-simplejson"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"log-server/global"
	"log-server/model/dataStatistics"
	"log-server/model/dataStatistics/request"
	"log-server/model/dataStatistics/response"
	"log-server/model/task"
	"log-server/utils"
	"strconv"
	"strings"
	"time"
)

type ServiceDataAbnormalRate struct {
}
type Action struct {
	Action       string
	ActionResult string
}
type XjfTotal struct {
	Total  int
	GameId int
}

//type TencentOrderNum struct {
//	TaskId int `json:"task_id"`
//	Count  int `json:"count"`
//}

// QueryAbnormalRate 获取异常率列表
func (s *ServiceDataAbnormalRate) QueryAbnormalRate(ctx context.Context, api request.InfoDataAbnormalRateRequest, info request.PageInfo, order string, desc bool) (interface{}, int64, error) {

	//global.GVA_LOG.Info(api.Date[0])
	//global.GVA_LOG.Info(api.Date[1])
	//global.GVA_LOG.Info(api.DirectorName)
	//global.GVA_LOG.Info(strconv.Itoa(api.TaskId))
	//global.GVA_LOG.Info(strconv.Itoa(api.Hour))
	db := global.GVA_DB.Model(&dataStatistics.DataAbnormalRate{})
	db = db.Select("data_abnormal_rate.task_id,data_abnormal_rate.task_name,data_abnormal_rate.new_date,data_abnormal_rate.num_frozen,data_abnormal_rate.num_pull_account,data_abnormal_rate.num_start_simulator,data_abnormal_rate.num_ip,data_abnormal_rate.num_start_script,data_abnormal_rate.num_start_game," +
		"data_abnormal_rate.num_login_success,data_abnormal_rate.num_into_game,data_abnormal_rate.num_new_success,data_abnormal_rate.num_lc_success,data_abnormal_rate.num_pay_success,data_abnormal_rate.rate_all_step,data_abnormal_rate.num_pull_pay," +
		"data_abnormal_rate.num_account_lc,data_abnormal_rate.num_could_pay,data_abnormal_rate.num_order_pay,data_abnormal_rate.num_pay,data_abnormal_rate.rate_pay_success,director_name")
	//判断是否为今天，今天则取小时数据；若为往日，则取23点数据
	if len(api.Date) == 0 {
		api.Date = append(api.Date, time.Now().Format("2006-01-02"))
		api.Date = append(api.Date, time.Now().Format("2006-01-02"))
	}
	if api.Date[0] == time.Now().Format("2006-01-02") {
		hour := time.Now().Hour()
		if time.Now().Minute() <= 30 {
			hour = hour - 1
		}
		db = db.Where("hour = ?", hour)
	} else {
		db = db.Where("hour = 23")
	}
	db = db.Where("new_date >= ? and new_date <= ?", api.Date[0], api.Date[1])
	if api.TaskId != 0 {
		db = db.Where("task_id = ? ", api.TaskId)
	}
	if api.DirectorName != "" {
		db = db.Where("director_name = ? ", api.DirectorName)
	}

	//if api.TaskId != 0 {
	//	db = db.Where("rent_computer.pc_num = ?", api.TaskId)
	//}

	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.LogComputer
	var dataList []*response.DataAbnormalRateResponse
	db = db.Limit(limit).Offset(offset)
	if order != "" {
		var OrderStr string
		// 设置有效排序key 防止sql注入
		// 感谢 Tom4t0 提交漏洞信息
		orderMap := make(map[string]bool, 3)
		orderMap["director_name"] = 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 dataList, total, err
		}
		err = db.Order(OrderStr).Find(&dataList).Error
	} else {
		err = db.Order("id").Find(&dataList).Error
	}
	if err != nil {
		return nil, 0, err
	}
	var responseDataList []*response.DataAbnormalRateResponse
	//查询游戏目标
	var dataTarget []*task.GameTargetComplete
	db2 := global.GVA_DB.Model(&task.GameTargetComplete{})
	db2 = db2.Select("task_id", "create_date", "new_target", "pay_target", "retained_target")
	db2 = db2.Where("create_date >= ? and create_date <= ?", api.Date[0], api.Date[1])
	err = db2.Order("create_date,task_id").Find(&dataTarget).Error
	if err != nil {
		return nil, 0, err
	}
	for _, one := range dataList {
		temp := new(response.DataAbnormalRateResponse)
		//temp.Id = one.Id
		//temp.UpdateTime = one.UpdateTime
		//temp.CreateTime = one.CreateTime
		temp.NewTarget = 0
		temp.RetainedTarget = 0
		temp.PayTarget = 0
		for _, target := range dataTarget {
			if target.CreateDate.Format("2006-01-02") == one.NewDate && target.TaskId == one.TaskId {
				temp.NewTarget = target.NewTarget
				temp.RetainedTarget = target.RetainedTarget
				temp.PayTarget = target.PayTarget
				break
			}
		}
		temp.TaskId = one.TaskId
		temp.TaskName = one.TaskName
		temp.DirectorName = one.DirectorName
		temp.NewDate = one.NewDate
		temp.Hour = one.Hour
		temp.NumFrozen = one.NumFrozen
		temp.NumPullAccount = one.NumPullAccount
		temp.NumStartSimulator = one.NumStartSimulator
		temp.NumIp = one.NumIp
		temp.NumStartScript = one.NumStartScript
		temp.NumStartGame = one.NumStartGame
		temp.NumLoginSuccess = one.NumLoginSuccess
		temp.NumIntoGame = one.NumIntoGame
		temp.NumNewSuccess = one.NumNewSuccess
		temp.NumLcSuccess = one.NumLcSuccess
		temp.NumPaySuccess = one.NumPaySuccess
		temp.RateAllStep = one.RateAllStep
		temp.NumPullPay = one.NumPullPay
		temp.NumAccountLc = one.NumAccountLc
		temp.NumCouldPay = one.NumCouldPay
		temp.NumOrderPay = one.NumOrderPay
		temp.NumPay = one.NumPay
		temp.RatePaySuccess = one.RatePaySuccess
		responseDataList = append(responseDataList, temp)
	}
	return responseDataList, total, err
}

// SyncAbnormalRateByBatch 定时批量更新异常率
func (s *ServiceDataAbnormalRate) SyncAbnormalRateByBatch() {
	newDate := time.Now().Format("2006-01-02")
	hour := time.Now().Hour()
	db := global.GVA_DB.Model(&task.GameTargetComplete{})
	db = db.Select("game_target_complete.task_id,b.task_name,b.user,b.login_method")
	db = db.Joins("left join game_task b on b.task_id = game_target_complete.task_id")
	db = db.Where("game_target_complete.create_date = ?", newDate)
	var dataList []*request.TaskInfo1
	err := db.Order("game_target_complete.task_id").Find(&dataList).Error
	if err != nil {
		return
	}
	if len(dataList) == 0 {
		global.GVA_LOG.Warn("定时批量更新异常率执行>>>无任务:" + time.Now().Format("2006-01-02 15:04:05"))
		return
	}
	actions := map[string]Action{
		"教程主线_冻结":       {Action: "教程主线", ActionResult: "冻结"},
		"拉取账号_成功":       {Action: "拉取账号", ActionResult: "成功"},
		"启动模拟器_成功":      {Action: "启动模拟器", ActionResult: "成功"},
		"启动游戏_查询IP":     {Action: "启动游戏", ActionResult: "查询IP"},
		"脚本启动_成功":       {Action: "脚本启动", ActionResult: "成功"},
		"启动游戏_成功":       {Action: "启动游戏", ActionResult: "成功"},
		"登陆_成功":         {Action: "登陆", ActionResult: "成功"},
		"教程主线_进入游戏":     {Action: "教程主线", ActionResult: "进入游戏"},
		"教程主线_新增成功":     {Action: "教程主线", ActionResult: "新增成功"},
		"教程主线_留存成功":     {Action: "教程主线", ActionResult: "留存成功"},
		"付费充值_付费成功":     {Action: "付费充值", ActionResult: "付费成功"},
		"教程主线_可以付费":     {Action: "教程主线", ActionResult: "可以付费"},
		"留存账号总数_留存账号总数": {Action: "留存账号总数", ActionResult: "留存账号总数"},
		"询问付费_付费":       {Action: "询问付费", ActionResult: "付费"},
	}
	action6 := []string{"小绵羊登录", "小绵羊登陆", "魅族登录", "魅族登陆", "QQ登录", "微信登录", "QQ登陆", "微信登陆", "网易登录", "网易登陆"}

	// 查询机房数组，以获取付费成功率
	dataXjf, err := s.RequestXjfTaskData()
	if err != nil {
		global.GVA_LOG.Error("获取机房数据失败RequestXjfTaskData", zap.Error(err))
		return
	}
	xjfJson, err := simplejson.NewJson(dataXjf)
	if err != nil {
		global.GVA_LOG.Error("Error", zap.Error(err))
		return
	}
	xjfArr, err := xjfJson.Array()
	if err != nil {
		global.GVA_LOG.Error("Error", zap.Error(err))
		return
	}
	//查询微信扫码订单数

	//var num map[string]map[int]int /*创建集合,存储机房查询日志接口返回值 */
	num := make(map[string]map[int]int)

	for k, v := range actions {
		action := v.Action
		actionResult := v.ActionResult
		var result []byte
		//var result2 []interface{}
		if k == "登陆_成功" {
			arrNum6 := make(map[int]int)
			for _, ss := range action6 {
				result, err = s.QueryXjfLogByBatch(ss, actionResult)
				if err != nil {
					return
				}
				if string(result) != "null" {
					dataJson, err := simplejson.NewJson(result)
					if err != nil {
						global.GVA_LOG.Error("Error", zap.Error(err))
						return
					}
					dataArr, err := dataJson.Array()
					if err != nil {
						global.GVA_LOG.Error("Error", zap.Error(err))
						return
					}
					for iii, _ := range dataArr {
						info := dataJson.GetIndex(iii)
						gameId, _ := info.Get("game_id").Int()
						if gameId == 0 {
							continue
						}
						total, _ := info.Get("total").Int()
						//var arr = XjfTotal{GameId: gameId, Total: total}
						//arrTemp = append(arrTemp, arr)
						if _, ok := arrNum6[gameId]; ok {
							// 存在
							arrNum6[gameId] = arrNum6[gameId] + total
						} else {
							arrNum6[gameId] = total
						}
					}
					//arrNum6 = append(arrNum6, arrTemp...)
				}
			}
			num[k] = arrNum6
		} else {
			result, err = s.QueryXjfLogByBatch(action, actionResult)
			if err != nil {
				return
			}
			if string(result) == "null" {
				continue
			}
			dataJson, err := simplejson.NewJson(result)
			if err != nil {
				global.GVA_LOG.Error("Error", zap.Error(err))
				return
			}
			dataArr, err := dataJson.Array()
			if err != nil {
				global.GVA_LOG.Error("Error", zap.Error(err))
				return
			}
			arrTemp := make(map[int]int)
			for iii, _ := range dataArr {
				info := dataJson.GetIndex(iii)
				gameId, err := info.Get("game_id").Int()
				global.GVA_LOG.Info(strconv.Itoa(gameId))
				if gameId == 0 {
					continue
				}
				if err != nil {
					global.GVA_LOG.Error(err.Error())
					return
				}
				total, err := info.Get("total").Int()
				global.GVA_LOG.Info(strconv.Itoa(total))
				if total == 0 && err != nil {
					continue
				}
				if err != nil {
					global.GVA_LOG.Error(err.Error())
					return
				}
				//global.GVA_LOG.Info(strconv.Itoa(gameId))
				//global.GVA_LOG.Info(strconv.Itoa(total))
				//var arr = XjfTotal{GameId: gameId, Total: total}
				//arrTemp = append(arrTemp, arr)
				arrTemp[gameId] = total
			}
			num[k] = arrTemp
		}

	}

	for _, task1 := range dataList {
		taskId := task1.TaskId     //任务id
		taskName := task1.TaskName // 任务名
		directorName := task1.User //负责人
		numFrozen := 0             //冻结
		numPullAccount := 0
		numStartSimulator := 0
		numIp := 0
		numStartScript := 0
		numStartGame := 0
		numLoginSuccess := 0
		numIntoGame := 0
		numNewSuccess := 0
		numLcSuccess := 0
		numPaySuccess := 0
		rateAllStep := ""
		numCouldPay := 0       // 可以付费的账号
		numAccountLc := 0      //留存账号总数
		numPullPay := 0        // 下发付费账号
		numOrderPay := 0       // 付费订单数
		numPay := 0            //付费成功数
		ratePaySuccess := "-%" //付费成功率
		orderSuccessRate := "0/0/0%"
		if _, ok := num["教程主线_冻结"][taskId]; ok {
			// 存在
			numFrozen = num["教程主线_冻结"][taskId]
		}
		if _, ok := num["拉取账号_成功"][taskId]; ok {
			numPullAccount = num["拉取账号_成功"][taskId]
		}
		if _, ok := num["启动模拟器_成功"][taskId]; ok {
			numStartSimulator = num["启动模拟器_成功"][taskId]
		}
		if _, ok := num["启动游戏_查询IP"][taskId]; ok {
			numIp = num["启动游戏_查询IP"][taskId]
		}
		if _, ok := num["脚本启动_成功"][taskId]; ok {
			numStartScript = num["脚本启动_成功"][taskId]
		}
		if _, ok := num["启动游戏_成功"][taskId]; ok {
			numStartGame = num["启动游戏_成功"][taskId]
		}
		if _, ok := num["登陆_成功"][taskId]; ok {
			numLoginSuccess = num["登陆_成功"][taskId]
		}
		if _, ok := num["教程主线_进入游戏"][taskId]; ok {
			numIntoGame = num["教程主线_进入游戏"][taskId]
		}
		if _, ok := num["教程主线_新增成功"][taskId]; ok {
			numNewSuccess = num["教程主线_新增成功"][taskId]
		}
		if _, ok := num["教程主线_留存成功"][taskId]; ok {
			numLcSuccess = num["教程主线_留存成功"][taskId]
		}
		if _, ok := num["付费充值_付费成功"][taskId]; ok {
			numPaySuccess = num["付费充值_付费成功"][taskId]
		}
		if _, ok := num["教程主线_可以付费"][taskId]; ok {
			numCouldPay = num["教程主线_可以付费"][taskId]
		}
		if _, ok := num["留存账号总数_留存账号总数"][taskId]; ok {
			numAccountLc = num["留存账号总数_留存账号总数"][taskId]
		}
		if _, ok := num["询问付费_付费"][taskId]; ok {
			numPullPay = num["询问付费_付费"][taskId]
		}
		if numIntoGame != 0 && numStartGame != 0 {
			rateAllStep = strconv.Itoa(numIntoGame * numStartGame / 1e6)
		}

		for iii, _ := range xjfArr {
			info := xjfJson.GetIndex(iii)
			gameId, err := info.Get("game_id").Int()
			if err != nil {
				global.GVA_LOG.Error("Error", zap.Error(err))
				return
			}
			if gameId == task1.TaskId {
				orderSuccessRate, err = info.Get("order_success_rate").String()
				if err != nil {
					global.GVA_LOG.Error("Error", zap.Error(err))
					return
				}
				break
			}
		}
		orderSuccessRateArr := strings.Split(orderSuccessRate, "/")
		if len(orderSuccessRateArr) == 3 {
			numOrderPay, err = strconv.Atoi(orderSuccessRateArr[0]) // 付费订单数
			numPay, err = strconv.Atoi(orderSuccessRateArr[1])      // 付费成功数
			if err != nil {
				global.GVA_LOG.Error("Error", zap.Error(err))
				return
			}
			ratePaySuccess = orderSuccessRateArr[2] //付费成功率
		}

		var data dataStatistics.DataAbnormalRate
		data.CreateTime = time.Now().Format("2006-01-02 15:04:05")
		data.UpdateTime = time.Now().Format("2006-01-02 15:04:05")
		data.TaskId = taskId
		data.TaskName = taskName
		data.DirectorName = directorName
		data.NewDate = newDate
		data.Hour = hour
		data.NumFrozen = numFrozen
		data.NumPullAccount = numPullAccount
		data.NumStartSimulator = numStartSimulator
		data.NumIp = numIp
		data.NumStartScript = numStartScript
		data.NumStartGame = numStartGame
		data.NumLoginSuccess = numLoginSuccess
		data.NumIntoGame = numIntoGame
		data.NumNewSuccess = numNewSuccess
		data.NumLcSuccess = numLcSuccess
		data.NumPaySuccess = numPaySuccess
		data.RateAllStep = rateAllStep
		data.NumPullPay = numPullPay
		data.NumAccountLc = numAccountLc
		data.NumCouldPay = numCouldPay
		data.NumOrderPay = numOrderPay
		data.NumPay = numPay
		data.RatePaySuccess = ratePaySuccess

		//global.GVA_LOG.Info(data.TaskName)

		if !errors.Is(global.GVA_DB.Model(&dataStatistics.DataAbnormalRate{}).Where("new_date = ? and task_id = ? and hour = ?", newDate, taskId, hour).First(&dataStatistics.DataAbnormalRate{}).Error, gorm.ErrRecordNotFound) {
			//已存在,更新
			//global.GVA_LOG.Info("已存在,更新")
			err = global.GVA_DB.Model(&dataStatistics.DataAbnormalRate{}).Where("new_date = ? and task_id = ? and hour = ?", newDate, taskId, hour).Updates(data).Error
			if err != nil {
				global.GVA_LOG.Error("Error", zap.Error(err))
				return
			}
		} else {
			//不存在,新建
			//global.GVA_LOG.Info("不存在,新建")
			err = global.GVA_DB.Create(&data).Error
			if err != nil {
				global.GVA_LOG.Error("Error", zap.Error(err))
				return
			}
		}
	}

	return
}

// QueryXjfLogByBatch 请求机房任务数据
func (s *ServiceDataAbnormalRate) QueryXjfLogByBatch(action string, actionResult string) (result []byte, err error) {
	today := time.Now().Format("2006-01-02")
	jfUrl := "http://xjf.lianyou.fun:8099/v1/device/get_log_by_game"
	jfParams := map[string]string{
		"date":          today,
		"action":        action,
		"action_result": actionResult,
	}
	result, err = utils.HttpGet(jfUrl, jfParams)
	return
}

// RequestXjfTaskData 请求机房任务数据
func (s *ServiceDataAbnormalRate) RequestXjfTaskData() (result []byte, err error) {
	today := time.Now().Format("2006-01-02")
	jfurl := "http://xjf.lianyou.fun:8099/v1/task_statistics"
	jfparams := map[string]string{
		"query": "date:" + today + ",type:machine",
	}
	result, err = utils.HttpGet(jfurl, jfparams)
	return
}

// RequestXjfSomeData 请求机房数据接口数据
func (s *ServiceDataAbnormalRate) RequestXjfSomeData() (result []byte, err error) {
	today := time.Now().Format("2006-01-02")
	jfUrl := "http://xjf.lianyou.fun:8118/data/taskDateLog"
	jfParams := map[string]string{
		"date": today,
	}
	result, err = utils.HttpGet(jfUrl, jfParams)
	return
}
