package service

import (
	"context"
	"math"
	"time"

	mhayaTime "github.com/mhaya/extend/time"
	"github.com/mhaya/game/game_cluster/internal/code"
	"github.com/mhaya/game/game_cluster/internal/constant"
	"github.com/mhaya/game/game_cluster/internal/mdb"
	"github.com/mhaya/game/game_cluster/internal/mdb/eventmodels"
	"github.com/mhaya/game/game_cluster/internal/mdb/models"
	"github.com/mhaya/game/game_cluster/nodes/webadmin/common"
	"github.com/mhaya/game/game_cluster/nodes/webadmin/entity"
	"github.com/mhaya/game/game_cluster/nodes/webadmin/model"
	mhayaLogger "github.com/mhaya/logger"
	"github.com/spf13/cast"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"gorm.io/gorm"
)

type Synthesis struct {
	nodeId string
	db     *mongo.Database
}

func NewSynthesis(nodeId string) *Synthesis {
	return &Synthesis{
		nodeId: nodeId,
		db:     mdb.MDB,
	}
}

// 综合统计
func (s *Synthesis) Overview(req entity.OverviewReq) (*entity.OverviewResp, *code.Result) {
	page, pageSize := checkPageParam(req.Page, req.Size)

	// 构建查询条件
	filter := bson.M{}
	if req.UserName != "" {
		filter["userName"] = req.UserName
	}
	if req.OpenId != "" {
		filter["openId"] = req.OpenId
	}

	// 设置分页选项
	findOptions := options.Find()
	findOptions.SetSkip(int64((page - 1) * pageSize))
	findOptions.SetLimit(int64(pageSize))
	findOptions.SetSort(bson.D{{"createTime", -1}})

	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
	defer cancel()

	collection := mdb.MDB.Collection(constant.CNamePlayer)

	// 查询数据
	var results []*entity.OverviewDetail
	cursor, err := collection.Find(ctx, filter, findOptions)
	if err != nil {
		mhayaLogger.Warnf("Overview Find error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	defer cursor.Close(ctx)
	// 解析结果
	for cursor.Next(ctx) {
		var result entity.OverviewDetail
		if err := cursor.Decode(&result); err != nil {
			mhayaLogger.Warnf("Overview Decode error:%v", err)
			return nil, common.NewResult(code.InternalError)
		}

		results = append(results, &result)
	}

	if err := cursor.Err(); err != nil {
		mhayaLogger.Warnf("Overview cursor error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	// TODO 综合统计相关信息

	// TODO 获取总数total
	var count int64

	return &entity.OverviewResp{
		Details: results,
		Total:   count,
	}, nil
}

// 统计用户相关信息
func (s *Synthesis) UserList(req entity.UserListReq) (*entity.UserListResp, *code.Result) {
	page, pageSize := checkPageParam(req.Page, req.Size)

	// 构建查询条件
	filter := bson.M{}
	if req.UserName != "" {
		filter["userName"] = req.UserName
	}
	if req.OpenId != "" {
		filter["openId"] = req.OpenId
	}

	// 设置分页选项
	findOptions := options.Find()
	findOptions.SetSkip(int64((page - 1) * pageSize))
	findOptions.SetLimit(int64(pageSize))
	findOptions.SetSort(bson.D{{"createTime", -1}})

	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
	defer cancel()

	collection := mdb.MDB.Collection(constant.CNamePlayer)

	// 查询数据
	var results []*entity.UserListDetail
	cursor, err := collection.Find(ctx, filter, findOptions)
	if err != nil {
		mhayaLogger.Warnf("UserList Find error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	defer cursor.Close(ctx)
	// 解析结果
	for cursor.Next(ctx) {
		var result entity.UserListDetail
		if err := cursor.Decode(&result); err != nil {
			mhayaLogger.Warnf("UserList Decode error:%v", err)
			return nil, common.NewResult(code.InternalError)
		}

		results = append(results, &result)
	}

	if err := cursor.Err(); err != nil {
		mhayaLogger.Warnf("UserList cursor error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	// TODO UserList 统计用户相关信息

	// TODO 获取总数total
	var count int64

	return &entity.UserListResp{
		Details: results,
		Total:   count,
	}, nil
}

func (s *Synthesis) FindMDBUserLogDaily(req entity.UserLogDailyReq) (*entity.UserLogDailyResp, *code.Result) {
	page, pageSize := checkPageParam(req.Page, req.Size)

	// 定义上下文
	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
	defer cancel()

	// 指定集合
	collection := mdb.MDB.Collection(constant.CNamePlayerDailyRecord)

	// 构建查询条件 - 如果查询值为空那就不添加查询条件
	filter := bson.M{}

	if req.StartTime != 0 {
		filter["daily"] = bson.M{
			"$gte": req.StartTime,
			"$lte": req.EndTime,
		}
	}

	if req.Platform != "" && req.Platform != "all" {
		filter["platform"] = req.Platform
	}

	if req.Channel != "" {
		filter["channel"] = req.Channel
	}

	// 计算总数
	count, err := collection.CountDocuments(ctx, filter)
	if err != nil {
		mhayaLogger.Warnf("FindMDBUserLogDaily CountDocuments error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	// 执行查询
	opts := options.Find()
	opts.SetSkip(int64((page - 1) * pageSize))
	opts.SetLimit(int64(pageSize))
	opts.SetSort(bson.D{{"daily", -1}})

	cursor, err := collection.Find(ctx, filter, opts)
	if err != nil {
		mhayaLogger.Warnf("FindMDBUserLogDaily Find error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}
	defer cursor.Close(ctx)

	// 解析查询结果
	var results []*entity.UserLogDailyDetail

	for cursor.Next(ctx) {
		var result *entity.UserLogDailyDetail
		err := cursor.Decode(&result)
		if err != nil {
			mhayaLogger.Warnf("FindMDBUserLogDaily Decode error:%v", err)
			return nil, common.NewResult(code.InternalError)
		}
		results = append(results, result)
	}
	// 同一天的数据全部放到platform= ALl 且数据累加
	// 如果没有platform=all 的那就新增一个 同一个时间段只能有一个 platform=all
	// 将同一天的数据累加到platform=all的记录中
	allPlatformRecordMap := make(map[int64]*entity.UserLogDailyDetail)

	for _, result := range results {
		allPlatformRecordMap[result.Timestamp] = &entity.UserLogDailyDetail{
			Timestamp: result.Timestamp,
			Platform:  "all",
		}
	}
	for _, v := range results {
		if v.Timestamp == allPlatformRecordMap[v.Timestamp].Timestamp {
			allPlatformRecordMap[v.Timestamp].Registered += v.Registered
			allPlatformRecordMap[v.Timestamp].LoggedIn += v.LoggedIn
			allPlatformRecordMap[v.Timestamp].NewActive += v.NewActive
			allPlatformRecordMap[v.Timestamp].OldActive += v.OldActive
			allPlatformRecordMap[v.Timestamp].TotalPoints += v.TotalPoints
			allPlatformRecordMap[v.Timestamp].UProduced += v.UProduced
			allPlatformRecordMap[v.Timestamp].UCashout += v.UCashout
			allPlatformRecordMap[v.Timestamp].NewLogin += v.NewLogin
			allPlatformRecordMap[v.Timestamp].OldLogin += v.OldLogin
		}
	}

	// 替换原有结果
	for _, record := range allPlatformRecordMap {
		results = append(results, record)
	}

	return &entity.UserLogDailyResp{
		Details: results,
		Total:   count,
	}, nil
}

// FindWithdrawal 根据请求查询提现记录
func (s *Synthesis) FindWithdrawal(req entity.UserWithdrawalReq) (*entity.UserWithdrawalResp, *code.Result) {
	page, pageSize := checkPageParam(req.Page, req.Size)

	if !constant.CurrencyValid(req.Currency) {
		mhayaLogger.Warnf("FindWithdrawal unknow currency:%v", req.Currency)
		return nil, common.NewResult(code.ParamError)
	}

	var records []*eventmodels.UserWithdrawEventContent

	where := &eventmodels.UserWithdrawEventContent{
		UserBasic: eventmodels.UserBasic{
			UserId:   req.UserName,
			UserName: req.NickName,
		},
		EventBasic: eventmodels.EventBasic{
			ServerId: s.nodeId,
		},
		WithdrawId:      req.ID,
		Currency:        req.Currency,
		Address:         req.Address,
		State:           req.State,
		WithdrawalState: req.Withdrawal,
	}
	db := mdb.LogstashDB.Model(&eventmodels.UserWithdrawEventContent{}).Where(where).Order("create_at")

	if req.StartTime > 0 && req.EndTime > 0 && req.StartTime <= req.EndTime {
		db = db.Where("create_at >= ? and create_at <= ?", req.StartTime, req.EndTime)
	}
	if req.AmountMin > 0 && req.AmountMax > 0 && req.AmountMin <= req.AmountMax {
		db = db.Where("amount >= ? and amount <= ?", req.AmountMin, req.AmountMax)
	}
	if req.AfterAmountMin > 0 && req.AfterAmountMax > 0 && req.AfterAmountMin <= req.AfterAmountMax {
		db = db.Where("after_balance >= ? and after_balance <= ?", req.AfterAmountMin, req.AfterAmountMax)
	}

	pages := Paginate(db, page, pageSize)
	err := db.Scopes(pages.Limit).Find(&records).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		mhayaLogger.Warnf("FindWithdrawal Find error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	var results []*entity.UserWithdrawalDetail
	for _, v := range records {
		results = append(results, &entity.UserWithdrawalDetail{
			Id:          v.WithdrawId,
			UserName:    v.UserId,
			NickName:    v.UserName,
			OpenId:      v.TgId,
			Status:      v.State,
			Reason:      v.Reason,
			Withdrawal:  v.WithdrawalState,
			Amount:      int(v.Amount),
			AfterAmount: int(v.AfterBalance),
			Type:        v.Currency,
			Address:     v.Address,
			CreateAt:    v.CreateAt,
			UpdateAt:    v.CreateAt,
		})
	}

	return &entity.UserWithdrawalResp{
		Details: results,
		Total:   pages.Count,
	}, nil
}

// 导出提现记录
func (s *Synthesis) WithdrawalExport(req entity.UserWithdrawalExportReq) (*entity.UserWithdrawalResp, *code.Result) {
	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
	defer cancel()
	collection := mdb.MDB.Collection(constant.CNameCashOutRecord)

	// 构建过滤器
	filter := bson.M{}
	if req.UserName != "" {
		filter["userName"] = req.UserName
	}
	if req.NickName != "" {
		filter["nickName"] = req.NickName
	}
	if req.ID != "" {
		filter["_id"], _ = primitive.ObjectIDFromHex(req.ID)
	}
	if req.Address != "" {
		filter["address"] = req.Address
	}
	if req.State > 0 {
		filter["state"] = req.State
	}
	if req.Withdrawal > 0 {
		filter["withdrawal"] = req.Withdrawal
	}
	if req.StartTime > 0 && req.EndTime > 0 && req.StartTime <= req.EndTime {
		filter["createAt"] = bson.M{
			"$gte": req.StartTime,
			"$lte": req.EndTime,
		}
	}
	if req.AmountMin > 0 && req.AmountMax > 0 && req.AmountMin <= req.AmountMax {
		filter["amount"] = bson.M{
			"$gte": req.AmountMin,
			"$lte": req.AmountMax,
		}
	}
	if req.AfterAmountMin > 0 && req.AfterAmountMax > 0 && req.AfterAmountMin <= req.AfterAmountMax {
		filter["after_amount"] = bson.M{
			"$gte": req.AfterAmountMin,
			"$lte": req.AfterAmountMax,
		}
	}

	findOptions := options.Find()
	findOptions.SetSort(bson.D{{"createAt", -1}})

	// 获取总数total
	count, err := collection.CountDocuments(ctx, filter)
	if err != nil {
		mhayaLogger.Warnf("WithdrawalExportData CountDocuments error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	// 查询数据
	var results []*entity.UserWithdrawalDetail
	cursor, err := collection.Find(ctx, filter, findOptions)
	if err != nil {
		mhayaLogger.Warnf("WithdrawalExportData Find error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	defer cursor.Close(ctx)
	// 解析结果
	for cursor.Next(ctx) {
		var result entity.UserWithdrawalDetail
		if err := cursor.Decode(&result); err != nil {
			mhayaLogger.Warnf("WithdrawalExportData Decode error:%v", err)
			return nil, common.NewResult(code.InternalError)
		}
		results = append(results, &result)
	}

	if err := cursor.Err(); err != nil {
		mhayaLogger.Warnf("WithdrawalExportData cursor error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	return &entity.UserWithdrawalResp{
		Details: results,
		Total:   count,
	}, nil
}

// WithdrawalStatus 更新提现状态
func (s *Synthesis) WithdrawalStatus(req entity.UserWithdrawalStatus) *code.Result {
	// ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
	// defer cancel()
	collection := mdb.MDB.Collection(constant.CNameCashOutRecord)

	// 更新条件
	updateCondition := bson.M{"userName": req.UserName}
	// 更新内容
	updateContent := bson.M{"$set": bson.M{"status": req.Status}}
	// 设置更新选项
	updateOptions := options.Update() // 设置 upsert 选项
	// 执行更新操作
	_, err := collection.UpdateOne(context.TODO(), updateCondition, updateContent, updateOptions)
	if err != nil {
		mhayaLogger.Warnf("WithdrawalStatus UpdateOne error:%v", err)
		return common.NewResult(code.InternalError)
	}

	return nil
}

// WithdrawalStatusBatch 更新提现状态
func (s *Synthesis) WithdrawalStatusBatch(req entity.UserWithdrawalStatusBatch) *code.Result {
	collection := mdb.MDB.Collection(constant.CNameCashOutRecord)
	if len(req.ID) == 0 {
		return common.NewResult(code.ParamError)
	}

	for _, id := range req.ID {
		objID := primitive.ObjectID{}
		objID, _ = primitive.ObjectIDFromHex(id)
		updateCondition := bson.M{"_id": objID}
		updateContent := bson.M{}
		withdrawal := models.CashOutRecord{}
		err := collection.FindOne(context.TODO(), updateCondition).Decode(&withdrawal)
		if err != nil {
			mhayaLogger.Warnf("WithdrawalStatusBatch FindOne error:%v", err)
			continue
		}

		if req.Withdrawal != 0 {
			if withdrawal.Status == 1 {
				updateContent = bson.M{"$set": bson.M{"withdrawal": req.Withdrawal}}
			} else {
				continue
			}
		}

		if req.Status > 0 {
			if withdrawal.Status != 0 {
				continue
			}
			updateContent = bson.M{"$set": bson.M{"status": req.Status}}
		}

		updateOptions := options.Update().SetUpsert(true)
		_, err = collection.UpdateOne(context.TODO(), updateCondition, updateContent, updateOptions)
		if err != nil {
			mhayaLogger.Warnf("WithdrawalStatusBatch UpdateOne error:%v", err)
			continue
		}
	}

	return nil
}

// FindUserCountryCount 查询用户国家分布
//
// 返回值为 UserCountryResp 的切片和错误。
func (s *Synthesis) FindUserCountryCount() (*entity.UserCountryResp, *code.Result) {
	// 选择数据库和集合
	collection := mdb.MDB.Collection(constant.CNamePlayerCountryByIPStat)

	// 定义聚合管道
	// 定义聚合管道
	pipeline := []bson.D{
		{
			{Key: "$project", Value: bson.D{
				{Key: "playerRegisterCountry", Value: bson.D{{Key: "$objectToArray", Value: "$playerRegisterCountry"}}},
			}},
		},
		{

			{Key: "$unwind", Value: "$playerRegisterCountry"},
		},
		{
			{Key: "$group", Value: bson.D{
				{Key: "_id", Value: "$playerRegisterCountry.k"},
				{Key: "totalValue", Value: bson.D{{Key: "$sum", Value: "$playerRegisterCountry.v"}}},
			}},
		},
		{
			{Key: "$project", Value: bson.D{
				{Key: "_id", Value: 0},
				{Key: "countryKey", Value: "$_id"},
				{Key: "totalValue", Value: 1},
			}},
		},
	}

	// 执行聚合查询
	cursor, err := collection.Aggregate(context.TODO(), pipeline)
	if err != nil {
		mhayaLogger.Warnf("FindUserCountryCount Aggregate error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}
	defer cursor.Close(context.TODO())

	// 遍历查询结果
	var results []bson.M
	if err := cursor.All(context.TODO(), &results); err != nil {
		mhayaLogger.Warnf("FindUserCountryCount All error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	var totalIPCount int64
	var data []*entity.UserCountryDetail
	// 将结果转换为 UserCountryDetail
	for _, r := range results {
		var resp entity.UserCountryDetail
		resp.Country = r["countryKey"].(string)
		resp.IPCount = int(r["totalValue"].(int32))
		totalIPCount += int64(resp.IPCount)
		data = append(data, &resp)
	}
	for _, v := range data {
		// 保留小数点后两位
		v.Percentage = math.Round(float64(v.IPCount)/float64(totalIPCount)*10000) / 100
	}

	// 根据阈值过滤结果
	otherCount := 0
	otherPercentage := 0.00
	filteredResults := make([]*entity.UserCountryDetail, 0)
	threshold := 1.00
	for _, r := range data {
		if r.Percentage >= threshold {
			filteredResults = append(filteredResults, r)
			// 保留小数点后两位
			r.Percentage = math.Round(r.Percentage*100) / 100
			otherPercentage += r.Percentage
		} else {
			otherCount += r.IPCount
		}
	}
	// 将其他国家添加到过滤后的结果中
	if otherCount > 0 {
		p := 100.00 - math.Round(otherPercentage*100)/100
		filteredResults = append(filteredResults, &entity.UserCountryDetail{
			Country:    "other",
			IPCount:    otherCount,
			Percentage: math.Round(p*100) / 100,
		})
	}
	return &entity.UserCountryResp{
		Details: filteredResults,
	}, nil

}

// FindUserRetention UserRetentionResp 用户留存率
// 1. 获取指定日期范围内的注册用户数量
// 2. 获取指定日期范围内的活跃用户数量
// 3. 计算留存率
// 4. 返回结果
func (s *Synthesis) FindUserRetention(req entity.UserRetentionReq) (*entity.UserRetentionResp, *code.Result) {
	playerPreserve := models.GetPlayerPreserve(req.StartTime, req.EndTime)
	// 查询数据
	var results []*entity.UserRetentionDetail

	for key, v := range playerPreserve {
		var retention entity.Retention
		for _, vv := range v {
			if vv.ID == 1 {
				retention.Day1 = entity.DayRetention{
					LoggedIn:  vv.Ratio,
					LoginDate: key,
				}
			}
			if vv.ID == 3 {
				retention.Day3 = entity.DayRetention{
					LoggedIn:  vv.Ratio,
					LoginDate: key,
				}
			}
			if vv.ID == 7 {
				retention.Day7 = entity.DayRetention{
					LoggedIn:  vv.Ratio,
					LoginDate: key,
				}
			}
			if vv.ID == 14 {
				retention.Day14 = entity.DayRetention{
					LoggedIn:  vv.Ratio,
					LoginDate: key,
				}
			}
			if vv.ID == 30 {
				retention.Day30 = entity.DayRetention{
					LoggedIn:  vv.Ratio,
					LoginDate: key,
				}
			}
		}

		results = append(results, &entity.UserRetentionDetail{
			RegistrationDate: key,
			RetentionData:    retention,
		})
	}

	return &entity.UserRetentionResp{
		Details: results,
	}, nil
}

// FindUserLevel 用户等级统计
func (s *Synthesis) FindUserLevel() (*entity.UserLevelCountResp, *code.Result) {
	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
	defer cancel()
	collection := mdb.MDB.Collection(constant.CNamePlayerLevelStat)

	// 查询所有文档
	cursor, err := collection.Find(ctx, bson.M{})
	if err != nil {
		mhayaLogger.Warnf("FindUserLevel Find error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}
	defer cursor.Close(ctx)

	var results []*entity.UserLevelCountDetail
	var reData []*models.PlayerLevelStat
	for cursor.Next(ctx) {
		var result models.PlayerLevelStat
		if err := cursor.Decode(&result); err != nil {
			mhayaLogger.Warnf("FindUserLevel Decode error:%v", err)
			return nil, common.NewResult(code.InternalError)
		}
		reData = append(reData, &result)
	}
	if err := cursor.Err(); err != nil {
		mhayaLogger.Warnf("FindUserLevel cursor error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	dataMap := make(map[string]int)
	for _, v := range reData {
		for key, v1 := range v.ServerLevel {
			dataMap[key] += v1
		}
	}

	for k, v := range dataMap {
		results = append(results, &entity.UserLevelCountDetail{
			Level:     cast.ToInt(k),
			UserCount: v,
		})
	}

	return &entity.UserLevelCountResp{
		Details: results,
	}, nil
}

func (s *Synthesis) InsertRecord(param model.UserOperationLog) {
	mhayaLogger.Warnf("InsertRecord param:%#v", param)

	record := new(model.UserOperationLog)
	collection := mdb.MDB.Collection(record.TableName())

	insertData := bson.M{}
	insertData["user_name"] = param.Username
	insertData["role_id"] = param.RoleId
	insertData["url"] = param.Path
	insertData["method"] = param.Method
	insertData["status_code"] = param.StatusCode
	insertData["dur"] = param.Dur
	insertData["client_ip"] = param.ClientIP
	insertData["error_message"] = param.ErrorMessage
	insertData["created_at"] = mhayaTime.Now().Unix()

	_, err := collection.InsertOne(context.Background(), insertData)
	if err != nil {
		mhayaLogger.Warnf("InsertRecord InsertOne error:%v", err)
		return
	}
}

func (s *Synthesis) RecordList(req entity.RecordListReq) (*entity.RecordListResp, *code.Result) {
	page, pageSize := checkPageParam(req.Page, req.Size)

	var records []*eventmodels.BackendOperationEventContent

	where := &eventmodels.BackendOperationEventContent{
		UserBasic: eventmodels.UserBasic{
			UserName: req.UserName,
		},
		EventBasic: eventmodels.EventBasic{
			ServerId: s.nodeId,
		},
		RoleId:     req.RoleId,
		Path:       req.Path,
		StatusCode: req.StatusCode,
		ClientIP:   req.ClientIP,
	}
	db := mdb.LogstashDB.Model(&eventmodels.BackendOperationEventContent{}).Where(where).Order("create_at")

	if req.StartTime > 0 && req.EndTime > 0 && req.StartTime <= req.EndTime {
		db = db.Where("create_at >= ? and create_at <= ?", req.StartTime, req.EndTime)
	}
	if req.DurMin > 0 && req.DurMax > 0 && req.DurMin <= req.DurMax {
		db = db.Where("dur >= ? and dur <= ?", req.DurMin, req.DurMax)
	}

	pages := Paginate(db, page, pageSize)
	err := db.Scopes(pages.Limit).Find(&records).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		mhayaLogger.Warnf("RecordList Find error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	var results []*entity.RecordListDetail
	for _, v := range records {
		results = append(results, &entity.RecordListDetail{
			Username:     v.UserName,
			RoleId:       v.RoleId,
			Path:         v.Path,
			Method:       v.Method,
			StatusCode:   v.StatusCode,
			Dur:          v.Dur,
			ClientIP:     v.ClientIP,
			ErrorMessage: v.ErrorMessage,
			CreatedAt:    v.CreateAt,
		})
	}

	return &entity.RecordListResp{
		Details: results,
		Total:   pages.Count,
	}, nil
}

// 转盘统计
func (s *Synthesis) Turntable(req entity.TurntableReq) (*entity.TurntableResp, *code.Result) {
	page, pageSize := checkPageParam(req.Page, req.Size)

	var records []*eventmodels.TurntableEventContent

	where := &eventmodels.TurntableEventContent{
		UserBasic: eventmodels.UserBasic{
			UserId: req.UserName,
			TgId:   req.OpenId,
		},
		EventBasic: eventmodels.EventBasic{
			ServerId: s.nodeId,
		},
	}
	db := mdb.LogstashDB.Model(&eventmodels.TurntableEventContent{}).Where(where).Order("create_at")

	if req.StartTime > 0 && req.EndTime > 0 && req.StartTime <= req.EndTime {
		db = db.Where("create_at >= ? and create_at <= ?", req.StartTime, req.EndTime)
	}

	pages := Paginate(db, page, pageSize)
	err := db.Scopes(pages.Limit).Find(&records).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		mhayaLogger.Warnf("Turntable Find error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	var results []*entity.TurntableDetail
	for _, v := range records {
		results = append(results, &entity.TurntableDetail{
			UserName:               v.UserName,
			OpenId:                 v.TgId,
			TurntableExecutionTime: v.CreateAt,
			PrizeName:              v.PrizeName,
			PrizeNumber:            v.PrizeNumber,
		})
	}

	return &entity.TurntableResp{
		Details: results,
		Total:   pages.Count,
	}, nil
}

// 资产统计
func (s *Synthesis) Assets(req entity.AssetsReq) (*entity.AssetsResp, *code.Result) {
	// TODO Assets
	// page, pageSize := checkPageParam(req.Page, req.Size)

	// var records []*eventmodels.TurntableEventContent

	// where := &eventmodels.TurntableEventContent{
	// 	UserBasic: eventmodels.UserBasic{
	// 		UserId: req.UserName,
	// 		TgId:   req.OpenId,
	// 	},
	// 	EventBasic: eventmodels.EventBasic{
	// 		ServerId: s.nodeId,
	// 	},
	// }
	// db := mdb.LogstashDB.Model(&eventmodels.TurntableEventContent{}).Where(where).Order("create_at")

	// pages := Paginate(db, page, pageSize)
	// err := db.Scopes(pages.Limit).Find(&records).Error
	// if err != nil && err != gorm.ErrRecordNotFound {
	// 	mhayaLogger.Warnf("Turntable Find error:%v", err)
	// 	return nil, common.NewResult(code.InternalError)
	// }

	// var results []*entity.TurntableDetail
	// for _, v := range records {
	// 	results = append(results, &entity.TurntableDetail{
	// 		UserName:               v.UserName,
	// 		OpenId:                 v.TgId,
	// 		TurntableExecutionTime: v.CreateAt,
	// 		PrizeName:              v.PrizeName,
	// 		PrizeNumber:            v.PrizeNumber,
	// 	})
	// }

	count, codeResult := NewPlayerManage().GetPlayerTotalCount()
	if codeResult != nil {
		mhayaLogger.Warnf("Assets GetPlayerTotalCount codeResult:%v", codeResult)
		return nil, codeResult
	}

	return &entity.AssetsResp{
		// Details: results,
		Total: int64(count),
	}, nil
}

// 资产变动记录
func (s *Synthesis) AssetsRecord(req entity.AssetsRecordReq) (*entity.AssetsRecordResp, *code.Result) {
	page, pageSize := checkPageParam(req.Page, req.Size)

	if !constant.CurrencyValid(req.Currency) {
		mhayaLogger.Warnf("AssetsRecord unknow currency:%v", req.Currency)
		return nil, common.NewResult(code.ParamError)
	}

	if req.OperationType != string(constant.IncreaseOp) && req.OperationType != string(constant.DecreaseOp) {
		mhayaLogger.Warnf("AssetsRecord unknow OperationType:%v", req.OperationType)
		return nil, common.NewResult(code.ParamError)
	}

	var records []*eventmodels.AssetsEventContent

	where := &eventmodels.AssetsEventContent{
		UserBasic: eventmodels.UserBasic{
			UserId: req.UserName,
			TgId:   req.OpenId,
		},
		EventBasic: eventmodels.EventBasic{
			ServerId: s.nodeId,
		},
		OperationType: req.OperationType,
		Currency:      req.Currency,
		Amount:        req.Amount,
	}
	db := mdb.LogstashDB.Model(&eventmodels.AssetsEventContent{}).Where(where).Order("create_at")

	if req.StartTime > 0 && req.EndTime > 0 && req.StartTime <= req.EndTime {
		db = db.Where("create_at >= ? and create_at <= ?", req.StartTime, req.EndTime)
	}

	pages := Paginate(db, page, pageSize)
	err := db.Scopes(pages.Limit).Find(&records).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		mhayaLogger.Warnf("Invite Find error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	var results []*entity.AssetsRecordDetail
	for _, v := range records {
		results = append(results, &entity.AssetsRecordDetail{
			UserName:                 v.UserName,
			OpenId:                   v.TgId,
			AssetType:                string(v.Currency),
			AssetsGrowth:             v.Amount,
			AcquisitionTime:          v.CreateAt,
			SourceOfAssetAcquisition: v.Reason,
		})
	}

	return &entity.AssetsRecordResp{
		Details: results,
		Total:   pages.Count,
	}, nil
}

// 邀请统计
func (s *Synthesis) Invite(req entity.InviteReq) (*entity.InviteResp, *code.Result) {
	page, pageSize := checkPageParam(req.Page, req.Size)

	// 构建查询条件
	filter := bson.M{}
	if req.UserName != "" {
		filter["userName"] = req.UserName
	}
	if req.OpenId != "" {
		filter["openId"] = req.OpenId
	}

	// 设置分页选项
	findOptions := options.Find()
	findOptions.SetSkip(int64((page - 1) * pageSize))
	findOptions.SetLimit(int64(pageSize))
	findOptions.SetSort(bson.D{{"createTime", -1}})

	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
	defer cancel()

	collection := mdb.MDB.Collection(constant.CNamePlayer)

	// 查询数据
	var results []*entity.InviteDetail
	cursor, err := collection.Find(ctx, filter, findOptions)
	if err != nil {
		mhayaLogger.Warnf("Invite Find error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	defer cursor.Close(ctx)
	// 解析结果
	for cursor.Next(ctx) {
		var result entity.InviteDetail
		if err := cursor.Decode(&result); err != nil {
			mhayaLogger.Warnf("Invite Decode error:%v", err)
			return nil, common.NewResult(code.InternalError)
		}

		results = append(results, &result)
	}

	if err := cursor.Err(); err != nil {
		mhayaLogger.Warnf("Invite cursor error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	// TODO 邀请统计相关信息

	// TODO 获取总数total
	var count int64

	return &entity.InviteResp{
		Details: results,
		Total:   count,
	}, nil
}

// 活跃统计
func (s *Synthesis) Active(req entity.ActiveReq) (*entity.ActiveResp, *code.Result) {
	page, pageSize := checkPageParam(req.Page, req.Size)

	// 构建查询条件
	filter := bson.M{}
	if req.UserName != "" {
		filter["userName"] = req.UserName
	}
	if req.OpenId != "" {
		filter["openId"] = req.OpenId
	}

	// 设置分页选项
	findOptions := options.Find()
	findOptions.SetSkip(int64((page - 1) * pageSize))
	findOptions.SetLimit(int64(pageSize))
	findOptions.SetSort(bson.D{{"createTime", -1}})

	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
	defer cancel()

	collection := mdb.MDB.Collection(constant.CNamePlayer)

	// 查询数据
	var results []*entity.ActiveDetail
	cursor, err := collection.Find(ctx, filter, findOptions)
	if err != nil {
		mhayaLogger.Warnf("Active Find error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	defer cursor.Close(ctx)
	// 解析结果
	for cursor.Next(ctx) {
		var result entity.ActiveDetail
		if err := cursor.Decode(&result); err != nil {
			mhayaLogger.Warnf("Active Decode error:%v", err)
			return nil, common.NewResult(code.InternalError)
		}

		results = append(results, &result)
	}

	if err := cursor.Err(); err != nil {
		mhayaLogger.Warnf("Active cursor error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	// TODO Active 活跃统计相关信息

	// TODO 获取总数total
	var count int64

	return &entity.ActiveResp{
		Details: results,
		Total:   count,
	}, nil
}

// 任务完成度统计
func (s *Synthesis) TaskCompletion(req entity.TaskCompletionReq) (*entity.TaskCompletionResp, *code.Result) {
	page, pageSize := checkPageParam(req.Page, req.Size)

	// 构建查询条件
	filter := bson.M{}
	if req.UserName != "" {
		filter["userName"] = req.UserName
	}
	if req.OpenId != "" {
		filter["openId"] = req.OpenId
	}

	// 设置分页选项
	findOptions := options.Find()
	findOptions.SetSkip(int64((page - 1) * pageSize))
	findOptions.SetLimit(int64(pageSize))
	findOptions.SetSort(bson.D{{"createTime", -1}})

	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
	defer cancel()

	collection := mdb.MDB.Collection(constant.CNamePlayer)

	// 查询数据
	var results []*entity.TaskCompletionDetail
	cursor, err := collection.Find(ctx, filter, findOptions)
	if err != nil {
		mhayaLogger.Warnf("TaskCompletion Find error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	defer cursor.Close(ctx)
	// 解析结果
	for cursor.Next(ctx) {
		var result entity.TaskCompletionDetail
		if err := cursor.Decode(&result); err != nil {
			mhayaLogger.Warnf("TaskCompletion Decode error:%v", err)
			return nil, common.NewResult(code.InternalError)
		}

		results = append(results, &result)
	}

	if err := cursor.Err(); err != nil {
		mhayaLogger.Warnf("TaskCompletion cursor error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	// TODO 任务完成度统计相关信息

	// TODO 获取总数total
	var count int64

	return &entity.TaskCompletionResp{
		Details: results,
		Total:   count,
	}, nil
}

// 用户行为检测
func (s *Synthesis) BehaviorMonitoring(req entity.BehaviorMonitoringReq) (*entity.BehaviorMonitoringResp, *code.Result) {
	page, pageSize := checkPageParam(req.Page, req.Size)

	// 构建查询条件
	filter := bson.M{}
	if req.UserName != "" {
		filter["userName"] = req.UserName
	}
	if req.OpenId != "" {
		filter["openId"] = req.OpenId
	}

	// 设置分页选项
	findOptions := options.Find()
	findOptions.SetSkip(int64((page - 1) * pageSize))
	findOptions.SetLimit(int64(pageSize))
	findOptions.SetSort(bson.D{{"createTime", -1}})

	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
	defer cancel()

	collection := mdb.MDB.Collection(constant.CNamePlayer)

	// 查询数据
	var results []*entity.BehaviorMonitoringDetail
	cursor, err := collection.Find(ctx, filter, findOptions)
	if err != nil {
		mhayaLogger.Warnf("BehaviorMonitoring Find error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	defer cursor.Close(ctx)
	// 解析结果
	for cursor.Next(ctx) {
		var result entity.BehaviorMonitoringDetail
		if err := cursor.Decode(&result); err != nil {
			mhayaLogger.Warnf("BehaviorMonitoring Decode error:%v", err)
			return nil, common.NewResult(code.InternalError)
		}

		results = append(results, &result)
	}

	if err := cursor.Err(); err != nil {
		mhayaLogger.Warnf("BehaviorMonitoring cursor error:%v", err)
		return nil, common.NewResult(code.InternalError)
	}

	// TODO 用户行为检测相关信息

	// TODO 获取总数total
	var count int64

	return &entity.BehaviorMonitoringResp{
		Details: results,
		Total:   count,
	}, nil
}
