package data

import (
	"errors"
	"gadmin/config"
	"gadmin/internal/gorm/model"
	"gadmin/internal/gorm/query"
	"github.com/sirupsen/logrus"
	"gorm.io/gorm"
	"sync"
)

var (
	userInfo = make(map[int64]*model.PlayerAttr)
)

func GetUser(userId int64) *model.PlayerAttr {
	if val, ok := userInfo[userId]; ok {
		return val
	}
	if userId == 0 {
		return nil
	}

	lock.RLock()
	defer lock.RUnlock()

	var (
		user *model.PlayerAttr
		err  error
	)

	for _, DB := range config.GDBGroup {
		u := query.Use(DB).PlayerAttr
		user, err = u.Where(u.Playerid.Eq(userId)).First()
		if err != nil && err.Error() != "record not found" {
			logrus.Errorf("query user failed：%v", err)
			return nil
		}

		if user != nil {
			break
		}
	}

	if user != nil {
		userInfo[userId] = user
	}

	return user
}

var userMap = &sync.Map{}

func GetUserToSyncMap(userId int64) *model.PlayerAttr {
	if userId == 0 {
		return nil
	}
	if user, ok := userMap.Load(userId); ok {
		return user.(*model.PlayerAttr)
	}

	var (
		user *model.PlayerAttr
		err  error
	)

	for _, DB := range config.GDBGroup {
		u := query.Use(DB).PlayerAttr
		user, err = u.Where(u.Playerid.Eq(userId)).First()
		if err != nil && err.Error() != "record not found" {
			logrus.Errorf("query user failed：%v", err)
			return nil
		}

		if user != nil {
			break
		}
	}

	if user != nil {
		userMap.Store(userId, user)
	}

	return user
}

// GetUsers playerIdMap map[serverId][]playerId
func GetUsers(playerIds []int64, svrId int) []*model.PlayerAttr {
	if len(playerIds) == 0 {
		return nil
	}

	result := make([]*model.PlayerAttr, 0)
	uIds := make([]int64, 0)
	for _, playerId := range playerIds {
		if uInfo, ok := userInfo[playerId]; ok {
			result = append(result, uInfo)
			continue
		}
		uIds = append(uIds, playerId)
	}

	if len(uIds) == 0 {
		return result
	}

	lock.RLock()
	defer lock.RUnlock()

	m := query.Use(config.GDBGroup[svrId]).PlayerAttr

	res, err := m.Where(m.Playerid.In(uIds...)).Find()
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		logrus.Errorf("query user failed：%v", err)
		return nil
	}
	if len(res) == 0 {
		return result
	}

	//塞进userInfo
	for _, uInfo := range res {
		userInfo[uInfo.Playerid] = uInfo
		result = append(result, uInfo)
	}

	return result
}
