package service

import (
	"context"
	"fmt"
	"github.com/mhaya/game/game_cluster/internal/data"
	"go.mongodb.org/mongo-driver/mongo/options"
	"slices"
	"time"

	"github.com/mhaya/game/game_cluster/internal/constant"
	"github.com/mhaya/game/game_cluster/internal/mdb"
	"github.com/mhaya/game/game_cluster/internal/mdb/models"
	"github.com/mhaya/game/game_cluster/nodes/adminapi/entity"
	"go.mongodb.org/mongo-driver/bson"
)

func GetUserCount() *entity.UserCountResp {
	collection := mdb.MDB.Collection(constant.CNameAccount)
	// 统计当日注册 和总注册人数
	// 获取今天开始的时间戳
	now := time.Now()
	startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
	endOfDay := startOfDay.Add(24 * time.Hour).Add(-1 * time.Second)
	// 构建查询条件 - 如果查询值为空那就不添加查询条件
	filter := bson.M{}
	// 统计当日注册 和总注册人数
	filter["JoinTime"] = bson.M{
		"$gte": startOfDay.Unix(),
		"$lte": endOfDay.Unix(),
	}
	// 获取注册总数
	totalCount, err := collection.CountDocuments(context.Background(), bson.M{})
	if err != nil {
		return nil
	}
	count, err := mdb.MDB.Collection(constant.CNameAccount).CountDocuments(context.Background(), filter)
	if err != nil {
		return nil
	}

	return &entity.UserCountResp{
		TotalReg: totalCount,
		ToDayReg: count,
	}
}

// GetUserList 获取用户列表 并且可以根据用户ID获取下级用户
func GetUserList(req *entity.UserReq) []*entity.UserListResp {
	collection := mdb.MDB.Collection(constant.CNamePlayer)
	filter := bson.M{}
	if req.UserName != "" {
		filter["pid"] = req.UserName
	}
	if req.UserID != "" {
		filter["userName"] = req.UserID
	}

	// 分页参数
	skip := (req.Page - 1) * req.Size
	// 执行查询
	opts := options.Find()
	opts.SetSkip(int64(skip))
	opts.SetLimit(int64(req.Size))

	cursor, err := collection.Find(context.Background(), filter, opts)

	count, _ := collection.CountDocuments(context.Background(), filter)
	if err != nil {
		return nil
	}
	defer cursor.Close(context.Background())
	var result []*entity.UserListResp
	for cursor.Next(context.Background()) {
		var account *models.Player
		if err := cursor.Decode(&account); err != nil {
			return nil
		}
		kol, _ := data.KolConfig.Get(account.UserName)
		var tagNum int
		if kol != nil {
			key := fmt.Sprintf("%v:%v:%v", constant.InviteTagKey, 2, kol.Mark)
			tagNum, _ = mdb.RDB.Get(context.Background(), key).Int()
		}

		var totalPlan int
		var curPlan int
		ids := []int{1000, 1001}
		for _, item := range account.FirstClaimReward {
			totalPlan++
			id := item.Reward[0].ItemID
			if slices.Contains(ids, id) {
				continue
			}

			if item.IsClaim == 1 {
				curPlan++
			}
		}

		result = append(result, &entity.UserListResp{
			UserName:          account.UserName,
			UserNameMaybe:     account.UserNameMaybe,
			NickName:          account.NickName,
			Avatar:            account.Avatar,
			Birthday:          account.Birthday,
			Gender:            account.Gender,
			Level:             account.Level,
			Rank:              account.Rank,
			Exp:               account.Exp,
			JoinTime:          account.JoinTime,
			JoinIP:            account.JoinIP,
			LoginTime:         account.LoginTime,
			LoginIP:           account.LoginIP,
			Status:            account.Status,
			PrevTime:          account.PrevTime,
			Successions:       account.Successions,
			MaxSuccessions:    account.MaxSuccessions,
			IsRobot:           account.IsRobot,
			IsVip:             account.IsVip,
			IsLeader:          account.IsLeader,
			IsFirstBindingXID: account.IsFirstBindingXID,
			XID:               account.XID,
			OpenId:            account.OpenId,
			Pid:               account.Pid,
			Mobile:            account.Mobile,
			Email:             account.Email,
			TonWall:           account.TonWall,
			UpdateTime:        account.UpdateTime,
			CreateTime:        account.CreateTime,
			RollDay:           account.RollDay,
			DailyRefreshTime:  account.DailyRefreshTime,
			HourRefreshTime:   account.HourRefreshTime,
			WeeklyRefreshTime: account.WeeklyRefreshTime,
			LoginFailure:      account.LoginFailure,
			IsCashOut:         account.IsCashOut,
			TagNum:            tagNum,
			Total:             count,
			TotalPlan:         totalPlan,
			CurPlan:           curPlan,
		})
	}
	return result
}
