package base

import (
	"math/rand"
	"time"

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

	"mongo.games.com/game/proto"
	player_proto "mongo.games.com/game/protocol/player"
)

func GetUser(s *netlib.Session) *player_proto.SCPlayerData {
	if user, ok := s.GetAttribute(SessionAttributeUser).(*player_proto.SCPlayerData); ok {
		return user
	}
	return nil
}

func GetScene(s *netlib.Session) IScene {
	if sceneId, ok := s.GetAttribute(SessionAttributeSceneId).(int32); ok {
		return SceneMgrSingleton.GetScene(sceneId)
	}
	ss := s.GetAttribute(SessionAttributeScene)
	if ss != nil {
		if scene, ok := ss.(IScene); ok {
			return scene
		}
	}
	return nil
}

func HadScene(s *netlib.Session) bool {
	if sceneId, ok := s.GetAttribute(SessionAttributeSceneId).(int32); ok {
		return sceneId > 0
	}
	if scene := s.GetAttribute(SessionAttributeScene); scene != nil {
		return true
	}
	return false
}

func StartSessionPingTimer(s *netlib.Session, act timer.TimerAction, ud interface{}, interval time.Duration, times int) bool {
	StopSessionPingTimer(s)
	if hTimer, ok := timer.StartTimer(act, ud, interval, times); ok {
		s.SetAttribute(SessionAttributePingTimer, hTimer)
		return true
	}
	return false
}

func StopSessionPingTimer(s *netlib.Session) {
	if h, ok := s.GetAttribute(SessionAttributePingTimer).(timer.TimerHandle); ok {
		if h != timer.TimerHandle(0) {
			timer.StopTimer(h)
			s.RemoveAttribute(SessionAttributePingTimer)
		}
	}
}

// StartSessionLoginTimer 登录定时器
func StartSessionLoginTimer(s *netlib.Session, act timer.TimerAction, ud interface{}, interval time.Duration, times int) bool {
	StopSessionLoginTimer(s)
	if hTimer, ok := timer.StartTimer(act, ud, interval, times); ok {
		s.SetAttribute(SessionAttributeLoginTimer, hTimer)
		return true
	}
	return false
}

func StopSessionLoginTimer(s *netlib.Session) {
	if h, ok := s.GetAttribute(SessionAttributeLoginTimer).(timer.TimerHandle); ok {
		if h != timer.TimerHandle(0) {
			timer.StopTimer(h)
			s.RemoveAttribute(SessionAttributeLoginTimer)
		}
	}
}

// ExePMCmd 机器人特殊指令
func ExePMCmd(s *netlib.Session, cmd string) {
	CSPMCmd := &player_proto.CSPMCmd{
		Cmd: proto.String(cmd),
	}
	proto.SetDefaults(CSPMCmd)
	s.Send(int(player_proto.PlayerPacketID_PACKET_CS_PMCMD), CSPMCmd)
}

// DelaySendSecond 延迟消息发送
// DelaySendSecond(s, packetid, pack, []int{1, 2}...) 1到2秒随机延迟发送消息
func DelaySendSecond(s *netlib.Session, packetid int, pack interface{}, params ...int) {
	DelaySendDuration(s, packetid, pack, time.Second, params...)
}

// DelaySendMillisecond 延迟消息发送
// DelaySendMillisecond(s, packetid, pack, []int{1, 2}...) 1到2毫秒随机延迟发送消息
func DelaySendMillisecond(s *netlib.Session, packetid int, pack interface{}, params ...int) {
	DelaySendDuration(s, packetid, pack, time.Millisecond, params...)
}

// DelaySendDuration 在某个时间区间随机延迟发送一次消息
// unit 时间单位
// params 延时区间
func DelaySendDuration(s *netlib.Session, packetid int, pack interface{}, unit time.Duration, params ...int) {
	min := 1
	if len(params) > 0 {
		min = params[0]
	}
	max := min + 3
	if len(params) > 1 {
		max = params[1]
	}
	if max < min {
		min, max = max, min
	} else if max == min {
		max = min + 1
	}
	thinkSec := time.Duration(min + rand.Intn(max-min))

	timer.StartTimer(timer.TimerActionWrapper(func(h timer.TimerHandle, ud interface{}) bool {
		s.Send(packetid, pack)
		return true
	}), nil, unit*thinkSec, 1)
}
