package tienlen

import (
	"mongo.games.com/game/common"
	"mongo.games.com/game/gamerule/tienlen"
	"mongo.games.com/game/protocol/player"
	proto_tienlen "mongo.games.com/game/protocol/tienlen"
	"mongo.games.com/game/robot/base"
	"mongo.games.com/goserver/core/netlib"
	"sort"
)

type TienLenScene struct {
	base.BaseScene
	*proto_tienlen.SCTienLenRoomInfo
	players map[int32]*TienLenPlayer
}
type filterFunc func(*TienLenScene, *TienLenPlayer, []int32, []int32, []int32, bool) (bool, []int32)

var FilterMgr []filterFunc

func NewTienLenScene(info *proto_tienlen.SCTienLenRoomInfo) *TienLenScene {
	s := &TienLenScene{
		SCTienLenRoomInfo: info,
		players:           make(map[int32]*TienLenPlayer),
	}
	s.Init()
	return s
}

func (s *TienLenScene) Init() {
	s.players = make(map[int32]*TienLenPlayer)
	for _, mpd := range s.GetPlayers() {
		p := NewTienLenPlayer(mpd)
		if p != nil {
			s.AddPlayer(p)
		}
	}
}
func (s *TienLenScene) GetIsAllAi() bool {
	var i int
	for _, p := range s.players {
		if p.IsRobot() {
			i++
		}
	}
	return i == 4
}
func (s *TienLenScene) Clear() {
	for _, p := range s.players {
		p.Clear()
	}
}

func (s *TienLenScene) AddPlayer(p base.IPlayer) {
	if mp, ok := p.(*TienLenPlayer); ok {
		s.players[p.GetSnId()] = mp
	}
}

func (s *TienLenScene) DelPlayer(snid int32) {
	if p, exist := s.players[snid]; exist && p != nil {
		delete(s.players, snid)
	}
}

func (s *TienLenScene) GetPlayerByPos(pos int32) base.IPlayer {
	return nil
}

func (s *TienLenScene) GetPlayerBySnid(snid int32) base.IPlayer {
	if p, exist := s.players[snid]; exist {
		return p
	}
	return nil
}

func (this *TienLenScene) GetMe(s *netlib.Session) base.IPlayer {
	if user, ok := s.GetAttribute(base.SessionAttributeUser).(*player.SCPlayerData); ok {
		return this.GetPlayerBySnid(user.GetData().GetSnId())
	}
	return nil
}

func (s *TienLenScene) IsFull() bool {
	return len(s.players) >= int(s.MaxPlayerNum)
}

func (s *TienLenScene) IsMatchScene() bool {
	return s.IsMatch == 1 || s.IsMatch == 2 //锦标赛和冠军赛
}

// 娱乐版
func (this *TienLenScene) IsTienLenYule() bool {
	return common.IsTienLenYuLe(int(this.GetGameId()))
}

func (this *TienLenScene) GetMaxCardInScene(player *TienLenPlayer, cards []int32) []int32 {
	if player == nil {
		return nil
	}
	ret := make([]int32, len(cards))
	copy(ret, cards)

	sort.Slice(ret, func(i, j int) bool {
		if tienlen.CmpCard(cards[i], cards[j]) {
			return true
		}
		return false
	})

	for k, v := range this.players {
		if k == player.SnId {
			continue
		}
		cpCards := []int32{}
		for _, card := range v.Cards {
			if card != tienlen.InvalideCard {
				cpCards = append(cpCards, card)
			}
		}

		for i := 0; i < len(cpCards); i++ {
			for j := 0; j < len(ret); j++ {
				if tienlen.Value(cpCards[i]) > tienlen.Value(ret[j]) {
					ret = ret[:j]
					break
				} else if tienlen.Value(cpCards[i]) == tienlen.Value(ret[j]) {
					if tienlen.Color(cpCards[i]) > tienlen.Color(ret[j]) {
						ret = ret[:j]
						break
					}
				}
			}
		}
	}
	return ret
}

func (s *TienLenScene) IsCoinScene() bool {
	return true
}
func (this *TienLenScene) Update(ts int64) {
}

// 处理特殊规则情况下,需要处理的牌型调整
func (this *TienLenScene) FilterRobotAICard(player *TienLenPlayer, cards, lastCards, aiCards []int32, isNew bool) []int32 {

	for i := 0; i < len(FilterMgr); i++ {
		isOk, arr := FilterMgr[i](this, player, cards, lastCards, aiCards, isNew)
		if isOk {
			return arr
		}
	}

	return aiCards
}

func init() {

}
