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 GetDailyVarData(key string) interface{} {
	cache := &VarExpireData{}
	err := LoadCacheVarData(key, cache)
	if err != nil {
		return nil
	}
	return cache.D
}

func 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
	}
	if data.T > 0 && data.T < GoUtil.Now() {
		return nil
	}
	return data.D
}

func OpDailyVarDataAsync(PlayerId int, key string, value interface{}, opType int) {
	SendMsgToCenterAsync(&msg.Msg{
		From:       0,
		To:         PlayerId,
		SendT:      GoUtil.Now(),
		HandleType: msg.HANDLE_MOD_DAILY_VAR_SET,
		Extra: msg.VarData{
			Key:     key,
			Value:   value,
			SetType: opType,
		},
	})
}

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

func (p *Player) OpVarDataSync(PlayerId int, key string, value interface{}, opType int, end int64) (*msg.Msg, error) {
	return SendMsgToCenterSync(&msg.Msg{
		From:       int(p.M_DwUin),
		To:         PlayerId,
		SendT:      GoUtil.Now(),
		HandleType: msg.HANDLE_MOD_USER_VAR_SET,
		End:        end,
		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, end int64) {
	p.OpVarDataAsync(PlayerId, key, value, msg.VAR_OP_SET, end)
}

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

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

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

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

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

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

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

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

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

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

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)
}

const (
	notifyKeyFriendApply = "friend_apply_n"
	notifyKeyPetroomGame = "petroom_game_n"
)

func GetFriendApplyNotification(PlayerId int) int {
	data := GetUserVarData(notifyKeyFriendApply, PlayerId)
	if data == nil {
		return 0
	}
	return GoUtil.Int(data)
}

func SetFriendApplyNotification(PlayerId int, Count int) {
	p := new(Player)
	p.SetVarDataAsync(notifyKeyFriendApply, Count, PlayerId, 0)
}

func GetPetroomGameNotification(PlayerId int) (int, int64) {
	data := GetUserVarData(notifyKeyPetroomGame, PlayerId)
	if data == nil {
		return 0, 0
	}
	info, ok := data.(map[string]interface{})
	if !ok {
		return 0, 0
	}
	return GoUtil.Int(info["count"]), GoUtil.Int64(info["send"])
}

func SetPetroomGameNotification(PlayerId int, Count int) {
	p := new(Player)
	end := GoUtil.ZeroTimestamp() + oneday
	value := map[string]interface{}{
		"count": Count,
		"send":  GoUtil.Now(),
	}
	p.SetVarDataAsync(notifyKeyPetroomGame, value, PlayerId, end)
}
