package base

import (
	"fmt"
	"math/rand"
	"time"

	"mongo.games.com/goserver/core/logger"
	"mongo.games.com/goserver/core/netlib"
	"mongo.games.com/goserver/core/timer"

	"mongo.games.com/game/common"
	"mongo.games.com/game/proto"
	hallproto "mongo.games.com/game/protocol/gamehall"
	loginproto "mongo.games.com/game/protocol/login"
	playerproto "mongo.games.com/game/protocol/player"
)

func init() {
	// 玩家信息
	netlib.Register(int(playerproto.PlayerPacketID_PACKET_SC_PLAYERDATA), playerproto.SCPlayerData{}, SCPlayerData)
	// 玩家数据更新
	netlib.Register(int(playerproto.PlayerPacketID_PACKET_SC_PLAYERDATAUPDATE), playerproto.SCPlayerDataUpdate{}, SCPlayerDataUpdate)
	// 玩家状态更新
	netlib.Register(int(playerproto.PlayerPacketID_PACKET_SC_PLAYERFLAG), playerproto.SCPlayerFlag{}, SCPlayerFlag)
}

func SCPlayerData(s *netlib.Session, packetid int, data interface{}) error {
	logger.Logger.Trace("SCPlayerData ", data)
	msg, ok := data.(*playerproto.SCPlayerData)
	if !ok {
		return nil
	}

	if msg.GetOpRetCode() != playerproto.OpResultCode_OPRC_Sucess {
		accountID := s.GetAttribute(SessionAttributeClientAccountId)
		logger.Logger.Errorf("获取玩家信息失败 %v", accountID)
		s.Close()
		return nil
	}

	s.SetAttribute(SessionAttributeUser, msg)
	PlayerMgrSingleton.AddPlayer(msg, s)
	if msg.GetData() != nil {
		coin := msg.GetData().GetCoin()
		if coin < 1000000 {
			ExePMCmd(s, fmt.Sprintf("%v%v%v", common.PMCmd_AddCoin, common.PMCmd_SplitToken, 1000000))
		}
	}

	if msg.GetRoomId() != 0 {
		// 返回房间
		s.SetAttribute(SessionAttributeSceneId, msg.GetRoomId())
		scReturnRoom := &hallproto.CSReturnRoom{}
		proto.SetDefaults(scReturnRoom)
		s.Send(int(hallproto.GameHallPacketID_PACKET_CS_RETURNROOM), scReturnRoom)
	}

	StartSessionPingTimer(s, timer.TimerActionWrapper(func(h timer.TimerHandle, ud interface{}) bool {
		if !s.IsConned() {
			StopSessionPingTimer(s)
			return false
		}
		pack := &loginproto.CSPing{}
		s.Send(int(loginproto.GatePacketID_PACKET_CS_PING), pack)
		return true
	}), nil, time.Second*time.Duration(60+rand.Int31n(100)), -1)

	return nil
}

func SCPlayerDataUpdate(s *netlib.Session, packetid int, data interface{}) error {
	logger.Logger.Trace("SCPlayerDataUpdate ", data)
	msg, ok := data.(*playerproto.SCPlayerDataUpdate)
	if !ok {
		return nil
	}

	playerData := s.GetAttribute(SessionAttributeUser)
	if playerData == nil {
		logger.Logger.Errorf("SCPlayerDataUpdate playerData is nil")
		return nil
	}

	SCPlayerData, ok := playerData.(*playerproto.SCPlayerData)
	if !ok {
		logger.Logger.Errorf("SCPlayerDataUpdate SCPlayerData is nil")
		return nil
	}
	SCPlayerData.GetData().Coin = msg.GetCoin()
	return nil
}

func SCPlayerFlag(s *netlib.Session, packetid int, data interface{}) error {
	logger.Logger.Trace("SCPlayerFlag ", data)

	msg, ok := data.(*playerproto.SCPlayerFlag)
	if !ok {
		return nil
	}

	if scene, ok := GetScene(s).(IScene); ok && scene != nil {
		p := scene.GetPlayerBySnid(msg.GetPlayerId())
		if p != nil {
			p.SetFlag(msg.GetFlag())
		}
	}
	return nil
}
