package game

import (
	"fmt"
	"server/db"
	"server/game/mod/msg"
	GoUtil "server/game_util"
	"server/pkg/github.com/name5566/leaf/log"
)

const (
	VAR_KEY_FRIEND_MSG  = "friend_msg" // 好友消息
	VAR_GOLD_CARD       = "gold_card"
	VAR_PLAYROOM_UPVOTE = "playroom_upvote"
	VAR_PLAYROOM_CHIP   = "playroom_chip"
	VAR_PLAYROOM_KISS   = "playroom_kiss"
	VAR_USER_DATA       = "user_data"
	VAR_CATNIP_PARTNER  = "catnip_partner"
)

func (p *Player) GetVarData(key string) interface{} {
	cache := &VarExpireData{}
	err := LoadCacheVarData(key, cache)
	if err != nil {
		// log.Error("GetVarData err : %s, key: %s", err, key)
		return nil
	}
	return cache.D
}

func (p *Player) GetUserVarData(key string, PlayerId int) interface{} {
	cache := map[string]*VarExpireData{}
	err := LoadCacheVarData(GoUtil.GetVarKey(int(PlayerId)), &cache)
	if err != nil {
		// log.Error("GetUserVarData err : %s, key: %s", err, key)
		return nil
	}
	data, ok := cache[key]
	if !ok {
		return nil
	}
	return data.D
}

// func GetServerVarData(key string) interface{} {
// 	data, err := GetServerData(key)
// 	if err != nil {
// 		log.Error("GetServerVarData err : %s", err)
// 		return nil
// 	}
// 	return data.Extra
// }

func (p *Player) OpVarDataAsync(PlayerId int, key string, value interface{}, opType int) {
	SendMsgToCenterAsync(&msg.Msg{
		From:       int(p.M_DwUin),
		To:         PlayerId,
		SendT:      GoUtil.Now(),
		HandleType: msg.HANDLE_MOD_USER_VAR_SET,
		Extra: msg.VarData{
			Key:     key,
			Value:   value,
			SetType: opType,
		},
	})
}

func (p *Player) OpVarDataSync(PlayerId int, key string, value interface{}, opType int) (*msg.Msg, error) {
	return SendMsgToCenterSync(&msg.Msg{
		From:       int(p.M_DwUin),
		To:         PlayerId,
		SendT:      GoUtil.Now(),
		HandleType: msg.HANDLE_MOD_USER_VAR_SET,
		Extra: msg.VarData{
			Key:     key,
			Value:   value,
			SetType: opType,
		},
	})
}

func (p *Player) OpServerVarDataAsync(key string, Value interface{}, opType int) {
	SendMsgToCenterSync(&msg.Msg{
		HandleType: msg.HANDLE_MOD_VAR_SET,
		Extra:      msg.VarData{Key: key, Value: Value, SetType: opType},
	})
}

func (p *Player) OpServerVarDataSync(key string, Value interface{}, opType int) (*msg.Msg, error) {
	return SendMsgToCenterSync(&msg.Msg{
		HandleType: msg.HANDLE_MOD_VAR_SET,
		Extra:      msg.VarData{Key: key, Value: Value, SetType: opType},
	})
}

func (p *Player) SetVarDataAsync(key string, value interface{}, PlayerId int) {
	p.OpVarDataAsync(PlayerId, key, value, msg.VAR_OP_SET)
}

func (p *Player) AddVarDataAsync(key string, PlayerId int) {
	p.OpVarDataAsync(PlayerId, key, nil, msg.VAR_OP_ADD)
}

func (p *Player) SubVarDataAsync(key string, PlayerId int) {
	p.OpVarDataAsync(PlayerId, key, nil, msg.VAR_OP_SUB)
}

func (p *Player) AddPlayroomUpvote(PlayerId int) {
	p.AddVarDataAsync(VAR_PLAYROOM_UPVOTE, PlayerId)
}

func (p *Player) AddPlayroomChip(PlayerId int) {
	p.AddVarDataAsync(VAR_PLAYROOM_CHIP, PlayerId)
}

func (p *Player) SubPlayroomChip(PlayerId int) {
	p.SubVarDataAsync(VAR_PLAYROOM_CHIP, PlayerId)
}

func (p *Player) GetPlayroomUpvote(PlayerId int) int {
	data := p.GetUserVarData(VAR_PLAYROOM_UPVOTE, PlayerId)
	if data == nil {
		return 0
	}
	return data.(int)
}

func (p *Player) GetPlayroomChip(PlayerId int) int {
	data := p.GetUserVarData(VAR_PLAYROOM_CHIP, PlayerId)
	if data == nil {
		return 0
	}
	return data.(int)
}

func (p *Player) SetPlayroomKiss(Kiss int, PlayerId int) {
	p.SetVarDataAsync(VAR_PLAYROOM_KISS, Kiss, PlayerId)
}

func (p *Player) GetPlayroomKiss(PlayerId int) int {
	data := p.GetUserVarData(VAR_PLAYROOM_KISS, PlayerId)
	if data == nil {
		return 0
	}
	return data.(int)
}

func (p *Player) GetGoldCard() *VarGoldCard {
	data := p.GetVarData(VAR_GOLD_CARD)
	if data == nil {
		return &VarGoldCard{}
	}
	return data.(*VarGoldCard)
}

func (p *Player) GetCatnipPartner(Uid int) []int {
	data, err := GetUserData(p.M_DwUin, VAR_CATNIP_PARTNER)
	if err != nil {
		log.Error("GetVarData err : %s", err)
		return nil
	}
	if data == nil {
		return nil
	}
	return GoUtil.IntSlice(data.Extra)
}

func SaveCacheVarData(key string, value interface{}) {
	data, err := GoUtil.GobMarshal(value)
	if err != nil {
		log.Error("SaveCacheVarData GobMarshal err : %s", err)
		return
	}
	db.RedisSetKeyBytes(key, data, 0)
}

func LoadCacheVarData(key string, value interface{}) error {
	data, err := db.RedisGetKeyBytes(key)
	if err != nil {
		return err
	}
	if data == nil {
		return fmt.Errorf("no data")
	}
	return GoUtil.GobUnmarshal(data, value)
}
