package game

import (
	"context"
	"github.com/davy66666/poker-go/src/github.com/davecgh/go-spew/spew"
	"github.com/golang/glog"
	"github.com/jinzhu/copier"
	"github.com/zeromicro/go-zero/core/logc"
	"log"
	"microGame/app/usercenter/cmd/api/internal/types"
	"microGame/pkg/result"
	"time"
)

func (r *Room) joinRoom(m *types.JoinRoom, o *Player) bool {
	ctx := context.Background()
	for k, v := range r.Players {
		logc.Info(ctx, v, o)
		if v.Uid == o.Uid {
			// todo 掉线重连现场数据替换处理
			o.Replace(r.Players[k])
			r.Players[k] = o
			if o != v {
				logc.Info(ctx, "掉线重连处理")
			} else {
				logc.Info(ctx, "同一个链接重复请求加入房间")
			}
			o.WriteMsg(result.WSError("join", types.MSG_ROOM_OVERVOLUME, -1002))
			return false
		}
	}

	userInfos := make([]*types.UserInfo, 0, r.Cap())
	r.Each(0, func(o *Player) bool {
		userinfo := &types.UserInfo{
			Nickname: o.Nickname,
			Uid:      o.Uid,
			Username: o.Username,
			Sex:      o.Sex,
			Profile:  o.Profile,
			Chips:    o.chips,
			Pos:      o.Pos,
		}
		userInfos = append(userInfos, userinfo)
		return true
	})

	var pos uint8 = 0
	// 判断游戏是否开始 如果已经开始 用户只能先加入观察者 坐下失败转为旁观
	if r.status == 1 {
		pos = r.addObserve(o)
	} else {
		pos = r.addPlayer(o)
	}

	// 坐下成功
	if pos != 0 {
		userInfo := &types.UserInfo{
			Nickname: o.Nickname,
			Uid:      o.Uid,
			Username: o.Username,
			Sex:      o.Sex,
			Profile:  o.Profile,
			Chips:    o.chips,
			Pos:      pos,
		}

		r.Broadcast(result.WSSuccess("join", &types.JoinRoomBroadcast{UserInfo: userInfo}), true, o.Uid)
		// 加入列表
		userInfos = append(userInfos, userInfo)
	}
	roomInfo := &types.RoomInfoResp{
		RoomNumber: r.RoomNumber,
	}
	//记录用户属于哪个room 防止数据丢失
	//o.UpdateRoomId()
	var resp []*types.UserInfoResp
	_ = copier.Copy(&resp, userInfos)
	// send message 推送 告诉当前加入room的用户 room里成员信息
	o.WriteMsg(result.WSSuccess("join", &types.JoinRoomResp{UserInfos: resp, RoomInfo: roomInfo}))

	time.AfterFunc(2*time.Second, func() {
		defer func() {
			if err := PrintPanicStack(); err != nil {
				logc.Errorf(context.Background(), "Recovered from panic: %v", err)
			}
		}()

		// 你的业务逻辑
		// r.WriteMsg(o, &startDelay{})
	})

	logc.Debugw(ctx, "joinRoom", logc.Field("key", spew.Sdump(m)))
	return true
}

func (r *Room) leaveAndRecycleChips(o *Player) {
	if r.removePlayer(o) > 0 {
		// 玩家站起回收带入筹码
		gap := o.chips - uint32(r.DraginChips)
		if gap == 0 {
			//数据库处理用户资金
			//o.UpdateChips(gap)
		}
	}
}
func (r *Room) LeaveRoom(m *types.LeaveRoom, o *Player) {

	r.removeObserve(o)
	r.removePlayer(o)
	r.leaveAndRecycleChips(o)

	o.RoomId = 0
	//数据库处理用户资金
	//o.UpdateRoomId()

	leave := &types.LeaveRoom{
		RoomNumber: r.RoomNumber,
		Uid:        o.Uid,
	}
	r.Broadcast(result.WSSuccess("leave", leave), true)

	// 房间里没有玩家时关闭并从列表中删除
	if r.Len() == 0 {
		r.CloseRoomChannel()
	}
	glog.Errorln("leaveRoom", m)
}

func (r *Room) bet(m *types.WSMessage, o *Player) {
	if !o.IsGaming() {
		o.WriteMsg(result.WSSuccess("bet", types.MSG_NOT_NOT_START))
		return
	}
	data, ok := m.Data.(int)
	if !ok {
		log.Println("m.Data 不是 int 类型")
		return
	}
	if data < 0 {
		err := o.SetAction(-1)
		if err != nil {
			o.WriteMsg(result.WSSuccess("bet", types.MSG_NOT_TURN))
		}

	} else {
		err := o.SetAction(int32(data))
		if err != nil {
			o.WriteMsg(result.WSSuccess("bet", types.MSG_NOT_TURN))
		}
	}

	glog.Errorln("bet", m)
}

func (r *Room) sitDown(m *types.WSMessage, o *Player) {
	pos := r.addPlayer(o)
	if pos == 0 {
		// 给进入房间的玩家带入筹码
		o.chips = uint32(r.DraginChips)
		r.addObserve(o)
	} else {

	}
	r.Broadcast(result.WSSuccess("sitDown", &types.SitDown{Uid: o.Uid, Pos: o.Pos}), true)

	glog.Errorln("sitDown", m)
}

func (r *Room) standUp(m *types.WSMessage, o *Player) {

	err := o.SetAction(-1)
	if err != nil {
		return
	}
	r.leaveAndRecycleChips(o)

	r.addObserve(o)
	r.Broadcast(result.WSSuccess("standUp", &types.StandUp{Uid: o.Uid}), true)

	glog.Errorln("standUp", m)
}

func (r *Room) chat(m *types.Chat, o *Player) {
	r.Broadcast(result.WSSuccess("chat", m), true)
}
