package game

import (
	"encoding/json"
	"fmt"
	"os/exec"
	"server/GoUtil"
	"server/MergeConst"
	mergeCluster "server/cluster"
	"server/conf"
	cardCfg "server/conf/card"
	chargeCfg "server/conf/charge"
	mailCfg "server/conf/mail"
	mergeDataCfg "server/conf/mergeData"
	playroomCfg "server/conf/playroom"
	"server/db"
	"server/game/mod/card"
	"server/game/mod/friend"
	"server/game/mod/item"
	"server/game/mod/msg"
	"server/game/mod/order"
	"server/game/mod/playroom"
	proto "server/msg"
	"server/pkg/github.com/name5566/leaf/log"
	"sort"
	"strings"
)

// 处理玩家异步请求
func HandleMsg(p *Player, m *msg.Msg) {
	p.lock.Lock()        //加锁
	backup := p.BackUp() // 备份当前的 Player 值
	defer func() {
		if r := recover(); r != nil {
			log.Debug("Handle msg uid : %d, msg : %v, fatal : %s", p.M_DwUin, m, r)
			p.Recover(backup) //还原Player的数据
		}
		p.lock.Unlock() //解锁
	}()
	p.args = make(map[string]interface{})
	err := handle(p, m)
	if err != nil {
		log.Debug("uid : %d, err : %s", p.M_DwUin, err)
		p.Recover(backup) //还原Player的数据
		return
	}
	p.ProcessTrigger()
	p.SendClientRes()
}

// 消息处理
func handle(p *Player, m *msg.Msg) error {
	switch m.Type {
	case msg.HANDLE_TYPE_DEL, msg.HANDLE_TYPE_APPLY, msg.HADNLE_TYPE_AGREE, msg.HANDLE_TYPE_REQ_CARD:
		return HandleFriendMsg(p, m)
	case msg.SERVER_ZERO_UPDATE:
		p.ZeroUpdate(nil)
	case msg.SERVER_NOON_UPDATE:
		p.NoonUpdate(nil)
	case msg.HANDLE_TYPE_INVITE_ADD_FRIEND: // 邀请添加好友
		FriendMod := p.PlayMod.getFriendMod()
		if m.From == 0 && m.From == int(p.M_DwUin) {
			return nil
		}
		FriendMod.AddFriend(m.From)
		p.TeLog("friend_add", map[string]interface{}{
			"player_id": m.From,
			"add_type":  "invite add friend",
		})
		p.PlayMod.save()
	case msg.HANDLE_TYPE_INVITE_FRIEND: // 邀请好友
		InviteMod := p.PlayMod.getInviteMod()
		InviteMod.AddInvite(m.From)
		p.PlayMod.save()
		p.PushClientRes(InviteMod.NotifySuccess())
	case msg.HANDLE_TYPE_SEND_CARD: // B收到A赠送的卡牌
		CardInfo := m.Extra.(card.CardInfo)
		FriendMod := p.PlayMod.getFriendMod()
		FriendMod.SetCardInfo(&CardInfo)
		p.PushClientRes(
			&proto.NotifyFriendCard{
				Info: GetCardInfoMsg(&CardInfo),
			},
		)
		p.PlayMod.save()
	case msg.HANDLE_TYPE_EX_CARD_SELECT_TIMEOUT: // A收到B置换卡牌选择超时
		CardInfo := m.Extra.(card.CardInfo)
		CardMod := p.PlayMod.getCardMod()
		p.AddCard(CardInfo.CardId)
		CardMod.DelExCard(&CardInfo)
		p.PushClientRes(CardMod.NotifyCard())
		p.PushClientRes(CardMod.NotifyTimes())
	case msg.HANDLE_TYPE_EX_CARD_TIMEOUT: // B收到A同意置换卡牌超时
		CardInfo := m.Extra.(card.CardInfo)
		CardMod := p.PlayMod.getCardMod()
		p.AddCard(CardInfo.ExId)
		p.PushClientRes(CardMod.NotifyCard())
		p.PushClientRes(CardMod.NotifyTimes())
	case msg.HANDLE_TYPE_REG_CARD_FINISH, msg.HANDLE_TYPE_AGREE_CARD_FAIL: // B收到A的请求已结束
		CardInfo := m.Extra.(card.CardInfo)
		FriendMod := p.PlayMod.getFriendMod()
		FriendMod.DelCardInfo(CardInfo.Id)
		p.PushClientRes(
			&proto.NotifyFriendCard{
				Info: GetCardInfoMsg(&CardInfo),
			},
		)
		p.PlayMod.save()
	case msg.HANDLE_TYPE_AGREE_CARD: // A收到B同意卡牌
		CardInfo := m.Extra.(card.CardInfo)
		CardMod := p.PlayMod.getCardMod()
		OtherUid, err := CardMod.DelRequestCard(CardInfo.BUid)
		FriendMod := p.PlayMod.getFriendMod()
		FriendMod.SetCardInfo(&CardInfo)
		if err != nil { // 同意失败，请求已失效
			msg := &msg.Msg{Type: msg.HANDLE_TYPE_AGREE_CARD_FAIL, From: CardInfo.AUid, End: CardInfo.EndTime, Extra: CardInfo}
			FriendMgrSend(msg)
			return nil
		}
		for k, v := range OtherUid { // 通知好友请求已结束
			v.Status = card.STATUS_CARD_GIVE_3
			msg := &msg.Msg{Type: msg.HANDLE_TYPE_REG_CARD_FINISH, From: k, Extra: &v}
			FriendMgrSend(msg)
			CardMod.DelRequestCard(k)
		}
		// p.AddLog(int(p.M_DwUin), friend.LOG_TYPE_CARD_ACCEPT_GIVE, fmt.Sprintf("%d", CardInfo.CardId))
		p.PlayMod.save()
		p.PushClientRes(
			&proto.NotifyFriendCard{
				Info: GetCardInfoMsg(&CardInfo),
			},
		)
		p.PushClientRes(CardMod.NotifyTimes())
		// p.PushClientRes(CardMod.NotifyCard())
	case msg.HANDLE_TYPE_REG_CARD_REFUSE: // A收到B拒绝索要卡牌
		CardInfo := m.Extra.(card.CardInfo)
		CardMod := p.PlayMod.getCardMod()
		CardMod.DelRequestCard(CardInfo.BUid)
		CardMod.AddReqTimes(CardInfo.Id, CardInfo.StartTime)
		p.PlayMod.save()
		p.PushClientRes(CardMod.NotifyTimes())
		p.PushClientRes(CardMod.NotifyCard())
	case msg.HANDLE_TYPE_EX_CARD: // B收到A置换卡牌
		FriendMod := p.PlayMod.getFriendMod()
		CardInfo := m.Extra.(card.CardInfo)
		FriendMod.SetCardInfo(&CardInfo)
		p.PlayMod.save()
		p.PushClientRes(
			&proto.NotifyFriendCard{
				Info: GetCardInfoMsg(&CardInfo),
			},
		)
	case msg.HANDLE_TYPE_SELECT_EX_CARD: // A收到B选择卡牌进行置换
		FriendMod := p.PlayMod.getFriendMod()
		CardInfo := m.Extra.(card.CardInfo)
		FriendMod.SetCardInfo(&CardInfo)
		// p.AddLog(int(p.M_DwUin), friend.LOG_TYPE_CARD_SELECT_GET, fmt.Sprintf("%d", CardInfo.CardId))
		p.PlayMod.save()
		p.PushClientRes(
			&proto.NotifyFriendCard{
				Info: GetCardInfoMsg(&CardInfo),
			},
		)
	case msg.HANDLE_TYPE_ARGREE_EX_CARD: // B收到A同意置换卡牌
		CardInfo := m.Extra.(card.CardInfo)
		FriendMod := p.PlayMod.getFriendMod()
		FriendMod.SetCardInfo(&CardInfo)
		p.PushClientRes(
			&proto.NotifyFriendCard{
				Info: GetCardInfoMsg(&CardInfo),
			},
		)
		p.PlayMod.save()
	case msg.HANDLE_TYPE_REFUSE_SELECT_CARD: // A收到B拒绝置换卡牌
		CardMod := p.PlayMod.getCardMod()
		CardInfo := m.Extra.(card.CardInfo)
		CardMod.AddExTimes(&CardInfo)
		p.AddCard(CardInfo.CardId)
		CardMod.DelExCard(&CardInfo)
		p.PushClientRes(CardMod.NotifyCard())
		p.PushClientRes(CardMod.NotifyTimes())
		p.PlayMod.save()
	case msg.HANDLE_TYPE_REFUSE_EX_CARD: // B收到A拒绝置换卡牌
		CardMod := p.PlayMod.getCardMod()
		CardInfo := m.Extra.(card.CardInfo)
		p.AddCard(CardInfo.ExId)
		FriendMod := p.PlayMod.getFriendMod()
		FriendMod.DelCardInfo(CardInfo.Id)
		if cardCfg.CheckCardIsGold(CardInfo.CardId) || cardCfg.CheckCardIsGold(CardInfo.ExId) {
			CardMod.AddGoldTimes()
		}
		p.PlayMod.save()
		p.PushClientRes(CardMod.NotifyCard())
	case msg.HANDLE_TYPE_CHAMPSHIP_NOTIFY: // #  锦标赛排名变动通知
		BackChampship(p)
	case msg.HANDLE_TYPE_MAIL: // 邮件操作
		SyncMailMsg(p)
	case msg.HANDLE_TYPE_PLAYROOM_LOSE: // #  玩家输了
		PlayroomMod := p.PlayMod.getPlayroomMod()
		Items := make([]*item.Item, 0)
		if m.Extra != nil {
			Items = m.Extra.([]*item.Item)
		}
		PlayroomMod.AddChip()
		PlayroomMod.AddMood(playroom.MOOD_TYPE_FOOD, -50)
		PlayroomMod.AddMood(playroom.MOOD_TYPE_CLEAN, -50)
		PlayroomMod.AddVisitor(m.From, m.SendT)
		p.AddLog(m.From, friend.LOG_TYPE_PLAYROOM_VISIT, fmt.Sprintf("%d,%d", Items[0].Id, Items[0].Num))
		if len(Items) > 0 && Items[0].Id == item.ITEM_STAR_ID {
			BaseMod := p.PlayMod.getBaseMod()
			StarNum := BaseMod.GetStar()
			Items[0].Num = min(Items[0].Num, StarNum)
			p.HandleLoseItem(Items, "")
		} else {
			PlayroomMod.Lose(Items)
		}
		p.UpdateUserInfo()
		p.Kafka(PLAYROOM_LOST, map[string]interface{}{"uid": m.From})
		p.PushClientRes(PlayroomMod.NotifyLose())
	case msg.FRIEND_TREASURE_HANDLE: // #  好友宝藏
		Items := make([]*item.Item, 0)
		if m.Extra != nil {
			Items = m.Extra.([]*item.Item)
		}
		p.HandleItem(Items, proto.ITEM_POP_LABEL_Friendtreasure.String())
	case msg.HANDLE_TYPE_HANDBOOK_COLLECTION: // 图鉴收集奖励
		data := m.Extra.(msg.HandbookMsg)
		p.AddLog(m.From, friend.LOG_TYPE_PLAYROOM_VISIT, data.Type)
	}
	// #region 以下是处理系统请求
	return nil
}

// 处理系统请求
func HandleServerMsg(p *Player, msg *msg.Msg) error {
	return nil
}

// 处理好友请求
func HandleFriendMsg(p *Player, m *msg.Msg) error {
	FriendMod := p.PlayMod.getFriendMod()
	PlayerSimpleData := G_GameLogicPtr.GetResSimplePlayerByUid(m.From)
	switch m.Type {
	case msg.HANDLE_TYPE_APPLY: // 好友申请
		FriendMod.AddFriendApply(m.From)
		p.AddLog(m.From, friend.LOG_TYPE_FRIEND_APPLY, "")
		p.PushClientRes(&proto.ResFriendApplyNotify{
			Player: PlayerSimpleData,
			Type:   friend.FRIEND_NOTIFY_APPLY,
			Time:   int32(GoUtil.Now()),
		})
	case msg.HADNLE_TYPE_AGREE: // 同意好友申请
		FriendMod.AgreeApply(m.From)
		p.PushClientRes(&proto.ResFriendApplyNotify{
			Player: PlayerSimpleData,
			Type:   friend.FRIEND_NOTIFY_APPLY,
			Time:   int32(GoUtil.Now()),
		})
		p.TeLog("friend_add", map[string]interface{}{
			"player_id": m.From,
			"add_type":  "agree",
		})
		p.AddLog(m.From, friend.LOG_TYPE_FRIEND_BECOME, "")
	case msg.HANDLE_TYPE_DEL: // 删除好友
		FriendMod.DelFriend(m.From)
		p.AddLog(m.From, friend.LOG_TYPE_FRIEND_APPLY, "")
		p.PushClientRes(&proto.ResFriendApplyNotify{
			Player: PlayerSimpleData,
			Type:   friend.FRIEND_NOTIFY_APPLY,
			Time:   int32(GoUtil.Now()),
		})
	case msg.HANDLE_TYPE_REFUSE: // 拒绝好友申请
		p.PushClientRes(&proto.ResFriendApplyNotify{
			Player: PlayerSimpleData,
			Type:   friend.FRIEND_NOTIFY_REFUSE,
			Time:   int32(GoUtil.Now()),
		})
	case msg.HANDLE_TYPE_REQ_CARD: // 卡牌申请
		CardInfo := m.Extra.(card.CardInfo)
		FriendMod.SetCardInfo(&CardInfo)
		p.PushClientRes(
			&proto.NotifyFriendCard{
				Info: GetCardInfoMsg(&CardInfo),
			},
		)
	}
	p.PlayMod.save()
	return nil
}

// 同步好友请求
func SyncFriendMsg(p *Player) {
	MsgList := G_GameLogicPtr.FriendMgrCall(&msg.Msg{Type: msg.HANDLE_TYPE_SYNC, From: int(p.M_DwUin)})
	FriendMod := p.PlayMod.getFriendMod()
	MsgId := FriendMod.GetSyncId()
	if MsgList == nil {
		return
	}
	ml := MsgList.([]*msg.Msg)
	if len(ml) == 0 {
		return
	}
	sort.Slice(ml, func(i, j int) bool {
		return ml[i].SendT < ml[j].SendT
	})
	maxId := int64(0)
	for _, v := range ml {
		maxId = max(maxId, v.Id)
		if v.H == 1 {
			continue
		}
		if v.Id > 0 && v.Id <= MsgId {
			continue
		}
		handle(p, v)
	}
	FriendMod.SetSyncId(maxId)
	p.PlayMod.save()
}

func SyncMailMsg(p *Player) {
	ServerMailList := G_GameLogicPtr.MailMgr.Sync(int(p.M_DwUin), p.GetPlayerBaseMod().GetRegisterTime())
	MailMod := p.PlayMod.getMailMod()
	for _, v := range ServerMailList {
		if GoUtil.InArray(v.Id, MailMod.ServerMail) {
			continue
		}
		MailMod.ServerMail = append(MailMod.ServerMail, v.Id)
		MailMod.Send(v.Title, v.Content, v.Items)
	}
}

// 返回好友信息
func FriendListBackData(p *Player) {
	FriendMod := p.PlayMod.getFriendMod()
	var fl []*proto.ResPlayerSimple
	for k := range FriendMod.FriendList {
		if k == int(p.M_DwUin) {
			continue
		}
		ps := G_GameLogicPtr.GetResSimplePlayerByUid(k)
		if ps != nil {
			fl = append(fl, ps)
		}
	}
	p.PushClientRes(&proto.ResFriendList{
		FriendList: fl,
	})
}

func FriendApplyBackData(p *Player) {
	FriendMod := p.PlayMod.getFriendMod()
	var al []*proto.ResFriendApplyInfo
	for k, v := range FriendMod.ApplyList {
		ps := G_GameLogicPtr.GetResSimplePlayerByUid(k)
		if ps != nil {
			al = append(al, &proto.ResFriendApplyInfo{
				Player: ps,
				Time:   int32(v),
			})
		}
	}
	p.PushClientRes(&proto.ResFriendApply{
		ApplyList: al,
	})
}

func FriendLogBackData(p *Player) {
	FriendMod := p.PlayMod.getFriendMod()
	var log []*proto.ResFriendLog
	for _, v := range FriendMod.Log {
		ps := G_GameLogicPtr.GetResSimplePlayerByUid(v.Uid)
		log = append(log, &proto.ResFriendLog{
			Player: ps,
			Type:   int32(v.Type),
			Time:   int32(v.Time),
			Param:  v.Param,
			Id:     int32(v.Id),
			Upvote: v.Upvote,
		})
	}
	p.PushClientRes(&proto.ResFriendTimeLine{
		Log: log,
	})
}

func FriendCardBackData(p *Player) {
	FriendMod := p.PlayMod.getFriendMod()
	var msgList []*proto.ResFriendCard
	for _, v := range FriendMod.Card {
		m := GetCardInfoMsg(v)
		msgList = append(msgList, m)
	}
	p.PushClientRes(&proto.ResFriendCardMsg{
		MsgList: msgList,
	})
}

// 发送消息给玩家
func ClusterSendMsg(ServerId int, m *msg.Msg) {
	mergeCluster.SendServerMsg(m, ServerId)
}

// 创建订单
func CreateOrderSn(p *Player, ChargeId int, Platform, Channel string) (string, error) {
	Uid := int(p.M_DwUin)
	OrderSn := GoUtil.CreateOrderSn(Uid)

	Price, Currency := chargeCfg.GetChargeInfo(ChargeId)
	err := db.CreateOrderSn(Uid, ChargeId, OrderSn, Platform, Channel, Price, Currency)
	if err != nil {
		return "", err
	}
	return OrderSn, nil
}

func GoogleVerify(p *Player, OrderSn, ProduceId, Token string) (*db.SqlChargeOrderStruct, error) {
	Order, err := db.GetPlayerChargeData(OrderSn)
	if err != nil {
		return nil, err
	}
	if !conf.Server.GoogleVerify {
		Order.PayStatus = MergeConst.ORDER_STATUS_PAY
		return Order, nil
	}
	if Order.PayStatus != MergeConst.ORDER_STATUS_IDLE {
		return nil, fmt.Errorf("订单已经支付")
	}
	cmd := exec.Command(conf.Server.AppPath+"/script/verifyOrder", ProduceId, Token)

	// 获取命令的输出
	output, err := cmd.Output()
	if err != nil {
		return nil, err
	}
	// 将输出转换为字符串
	outputStr := string(output)

	// 替换单引号为双引号
	outputStr = strings.Replace(outputStr, "'", "\"", -1)
	type VerifyData struct {
		PurchaseState    int    `json:"purchaseState"`
		DeveloperPayload string `json:"developerPayload"`
		OrderId          string `json:"orderId"`
		ConsumptionState int    `json:"consumptionState"`
	}
	r := &VerifyData{}
	err = json.Unmarshal([]byte(outputStr), &r)
	if err != nil {
		log.Debug("output %s", string(output))
		return nil, err
	}
	_, err = db.GetPlayerPayChannelOrderId(r.OrderId)
	if err == nil {
		return nil, fmt.Errorf("订单已支付发货 param: %v", r)
	}
	// if r.DeveloperPayload != OrderSn {
	// 	return nil, fmt.Errorf("订单号不匹配")
	// }
	if r.ConsumptionState != 1 {
		return nil, fmt.Errorf("订单未消费")
	}
	Order.PayStatus = MergeConst.ORDER_STATUS_PAY
	Order.PayChannelOrderId = r.OrderId
	Order.PayTime = GoUtil.Now()
	return Order, nil
}

func CancelOrder(p *Player, OrderSn string) error {
	Order, err := db.GetPlayerChargeData(OrderSn)
	if err != nil {
		return err
	}
	if Order.PayStatus != MergeConst.ORDER_STATUS_IDLE {
		return fmt.Errorf("订单已支付")
	}
	Order.PayStatus = MergeConst.ORDER_STATUS_CANCEL
	err = db.UpdatePlayerChargeData(Order)
	if err != nil {
		return err
	}
	return nil
}

func BackUserInfo(p *Player) {
	BaseMod := p.PlayMod.getBaseMod()
	FaceMod := p.PlayMod.getFaceMod()
	AvatarMod := p.PlayMod.getAvatarMod()
	DecorateMod := p.PlayMod.getDecorateMod()
	p.PushClientRes(&proto.UserInfo{
		Uid:         p.M_DwUin,
		Nickname:    BaseMod.NickName,
		Avatar:      int32(AvatarMod.SetId),
		Face:        int32(FaceMod.SetId),
		DecorateCnt: int32(DecorateMod.DecorateNum),
		AvatarList:  AvatarMod.BackData(),
		FaceList:    FaceMod.BackData(),
		EmojiList:   p.PlayMod.getEmojiMod().BackData(),
		SetEmoji:    p.PlayMod.getEmojiMod().GetEmojiSet(),
		Login:       int32(BaseMod.GetLoginTime()),
		PetName:     BaseMod.PetName,
	})
}

func GetCardInfoMsg(CardInfo *card.CardInfo) *proto.ResFriendCard {
	Uid := 0
	if CardInfo.Type == card.TYPE_CARD_SEND {
		Uid = CardInfo.BUid
	}

	if CardInfo.Type == card.TYPE_CARD_GIVE {
		if CardInfo.Status == card.STATUS_CARD_GIVE_1 {
			Uid = CardInfo.AUid
		} else {
			Uid = CardInfo.BUid
		}
	}

	if CardInfo.Type == card.TYPE_CARD_EX {
		if CardInfo.Status == card.STATUS_CARD_EX_2 {
			Uid = CardInfo.AUid
		} else {
			Uid = CardInfo.BUid
		}
	}

	ps := G_GameLogicPtr.GetSimplePlayerByUid(Uid)
	return &proto.ResFriendCard{
		Uid:      int64(Uid),
		Name:     ps.Name,
		Face:     int32(ps.Face),
		Avatar:   int32(ps.Avatar),
		Level:    int32(ps.Level),
		CardId:   int32(CardInfo.CardId),
		ExCardId: int32(CardInfo.ExId),
		Time:     int32(CardInfo.StartTime),
		Type:     int32(CardInfo.Type),
		Status:   int32(CardInfo.Status),
		Id:       CardInfo.Id,
	}
}

func BackChampship(p *Player) {
	ChampshipMod := p.PlayMod.getChampshipMod()
	MyRank := G_GameLogicPtr.ChampshipMgr.getMyRank(int(p.M_DwUin))
	MyPreRank := G_GameLogicPtr.ChampshipMgr.getLastMyRank(int(p.M_DwUin))
	p.PushClientRes(ChampshipMod.BackData(MyRank, MyPreRank))
}

func PlayroomOrderTrigger(p *Player) error {
	CD := playroomCfg.GetTriggerCd()
	PlayroomMod := p.PlayMod.getPlayroomMod()
	Now := GoUtil.Now()
	if PlayroomMod.TriggerTime+int64(CD) > Now {
		return nil
	}
	PlayroomUnlockLv := playroomCfg.GetUnLockLv()
	if p.GetPlayerBaseMod().GetLevel() < PlayroomUnlockLv {
		return nil
	}
	OrderMod := p.PlayMod.getOrderMod()
	Lv := p.GetPlayerBaseMod().GetLevel()
	Emit := p.PlayMod.getChessMod().GetOrderEmit()
	EnergyMul := p.PlayMod.getBaseMod().GetEnergyMul()
	Star, err := OrderMod.CreateTriggerOrder(Lv, Emit, EnergyMul)
	if err != nil {
		log.Debug("uid : %d, PlayroomOrderTrigger, err : %s", p.M_DwUin, err)
		return err
	}
	PlayroomMod.CreateOrderReward(Star, p.PlayMod.getItemMod())
	PlayroomBackData(p)
	p.PlayMod.save()
	return nil
}

func PlayroomBackData(p *Player) {
	r := &proto.ResPlayroom{}
	PlayroomMod := p.PlayMod.getPlayroomMod()
	FriendMod := p.PlayMod.getFriendMod()
	r.Status = int32(PlayroomMod.Status)
	r.Items = item.ItemToMsg(PlayroomMod.Reward)
	Opponent := make([]*proto.RoomOpponent, 0)
	FriendList := make([]*proto.FriendRoom, 0)

	for k, v := range PlayroomMod.Visitor {
		ps := G_GameLogicPtr.GetSimplePlayerByUid(k)
		if ps == nil {
			continue
		}
		if !FriendMod.CheckFriend(k) {
			Opponent = append(Opponent, &proto.RoomOpponent{
				Uid:      int64(k),
				Name:     ps.Name,
				Face:     int32(ps.Face),
				Avatar:   int32(ps.Avatar),
				LastTime: int32(v.Time),
			})
		}
	}
	Friend := FriendMod.GetFriendList()
	for _, v := range Friend {
		ps := G_GameLogicPtr.GetSimplePlayerByUid(v)
		if ps == nil {
			continue
		}
		Times, _ := PlayroomMod.GetVisitorInfo(v)
		FriendList = append(FriendList, &proto.FriendRoom{
			Uid:    int64(v),
			Name:   ps.Name,
			Face:   int32(ps.Face),
			Avatar: int32(ps.Avatar),
			Times:  int32(Times),
		})
	}
	r.Opponent = Opponent
	r.Friend = FriendList
	Collect := make([]int32, 0)
	for k, v := range PlayroomMod.GetCollect() {
		if v > 0 {
			Collect = append(Collect, int32(k))
		}
	}
	r.Collect = Collect
	Dress := make(map[int32]*proto.PlayroomDress)
	for k, v := range PlayroomMod.GetDress() {
		Dress[int32(k)] = &proto.PlayroomDress{
			List: GoUtil.IntToInt32(v),
		}
	}
	r.Dress = Dress
	r.DressSet = GoUtil.MapIntToInt32(PlayroomMod.GetDressSet())
	r.PetAir = GoUtil.IntToInt32(PlayroomMod.GetPetAir())
	r.PetAirSet = int32(PlayroomMod.GetPetAirSet())
	r.Chip = int32(PlayroomMod.Chip)
	r.StartTime = int32(PlayroomMod.Starttime)
	r.WorkStatus = int32(PlayroomMod.WorkStatus)
	r.Playroom = GoUtil.MapIntToInt32(PlayroomMod.GetRoom())
	r.Mood = GoUtil.MapIntToInt32(PlayroomMod.GetMood())
	r.Physiology = GoUtil.MapIntToInt32(PlayroomMod.GetPhysiologyList())
	r.AllMood = int32(PlayroomMod.AllMood)
	r.Jackpot = int32(PlayroomMod.JackpotNum)
	p.PushClientRes(r)
}

func PlayroomVisit(p *Player, Uid int) {
	if Uid == 0 {
		return
	}
	PlayroomMod := p.PlayMod.getPlayroomMod()
	r := &proto.ResPlayroomInfo{}
	PlayerData := G_GameLogicPtr.GetSimplePlayerByUid(Uid)
	Now := GoUtil.Now()
	Work := false
	if PlayerData.WorkStart > 0 && PlayerData.WorkStart+86400 > Now {
		Work = true
	}
	r.Uid = int64(Uid)
	r.Name = PlayerData.Name
	r.Face = int32(PlayerData.Face)
	r.Avatar = int32(PlayerData.Avatar)
	r.Playroom = GoUtil.MapIntToInt32(PlayerData.Playroom)
	r.GameId = int32(PlayroomMod.GameId)
	r.Defense = Work
	r.Emoji = GoUtil.MapIntToInt32(PlayerData.Emoji)
	r.Chip = int32(PlayerData.Chip)
	r.PetName = p.PlayMod.getBaseMod().GetPetName()
	Items := make(map[int32]*proto.ItemInfo, 0)
	for k, v := range PlayroomMod.GameReward {
		Items[int32(k)] = &proto.ItemInfo{
			Id:  int32(v.Id),
			Num: int32(v.Num),
		}
	}
	r.Items = Items
	r.Status = int32(PlayroomMod.GameStatus)
	p.PushClientRes(r)
}

func GetVisitorPlayer(p *Player) int {
	PlayroomMod := p.PlayMod.getPlayroomMod()
	VisitorList := PlayroomMod.GetVisitor()
	HasVisit := PlayroomMod.GetHasVisit()
	type sortData struct {
		Uid  int
		Time int64
	}
	PlayerList := make([]sortData, 0)

	Now := GoUtil.Now()
	for k, v := range VisitorList {
		if _, ok := HasVisit[k]; ok {
			continue
		}
		if v.Time < Now-86400 {
			continue
		}
		PlayerList = append(PlayerList, sortData{k, v.Time})
	}
	if len(PlayerList) != 0 {
		sort.Slice(PlayerList, func(i, j int) bool {
			return PlayerList[i].Time < PlayerList[j].Time
		})
		return PlayerList[0].Uid
	}
	FriendMod := p.PlayMod.getFriendMod()
	PlayerList2 := make([]sortData, 0)
	for _, v := range PlayerList {
		if FriendMod.CheckFriend(v.Uid) {
			continue
		}
	}
	if len(PlayerList2) != 0 {
		sort.Slice(PlayerList2, func(i, j int) bool {
			return PlayerList2[i].Time < PlayerList2[j].Time
		})
		return PlayerList2[0].Uid
	}
	L := GetRecommendPlayer(p, 1)
	return L[0]
}

func GetRecommendPlayer(p *Player, Num int) []int {
	PlayerList := G_GameLogicPtr.RankMgr.getAllRank(RANK_TYPE_USER)
	PlayerList1 := make([]int, 0)
	FriendMod := p.PlayMod.getFriendMod()
	for _, v := range PlayerList {
		if v.Score < 15 {
			continue
		}
		if v.Uid == int(p.M_DwUin) {
			continue
		}
		if FriendMod.CheckSendApply(v.Uid) {
			continue
		}
		if FriendMod.CheckFriend(v.Uid) {
			continue
		}
		PlayerSimpleData := G_GameLogicPtr.GetSimplePlayerByUid(v.Uid)
		if GoUtil.Now()-PlayerSimpleData.Loginout > 86400 {
			continue
		}
		if PlayerSimpleData.Level < 4 {
			continue
		}
		PlayerList1 = append(PlayerList1, v.Uid)
	}
	if len(PlayerList1) == 0 {
		for _, v := range PlayerList {
			if v.Uid == int(p.M_DwUin) {
				continue
			}
			PlayerList1 = append(PlayerList1, v.Uid)
		}
	}
	return GoUtil.RandSliceNum(PlayerList1, Num)
}

// 发射器退役第一步 不再生成此发射器订单
func EmitRetireTrigger1(p *Player) {
	ChessMod := p.PlayMod.getChessMod()
	EmitList := ChessMod.GetEmitList()
	EmitId := make(map[string]struct{}, 0)
	for _, v := range EmitList {
		Emit_Id := mergeDataCfg.GetEmitId(v)
		if Emit_Id == "" {
			continue
		}
		EmitId[Emit_Id] = struct{}{}
	}
	EmitId1 := make([]string, 0)
	for k := range EmitId {
		EmitId1 = append(EmitId1, k)
	}
	if len(EmitId1) <= 5 {
		return
	}
	sort.Slice(EmitId1, func(i, j int) bool {
		return EmitId1[i] < EmitId1[j]
	})
	OrderMod := p.PlayMod.getOrderMod()
	OrderMod.Retire(EmitId1[0])
	ChessMod.BeginRetire(EmitId1[0])
}

// 发射器退役第二步 生成清理订单
func EmitRetireTrigger2(p *Player) {
	ChessMod := p.PlayMod.getChessMod()
	OrderMod := p.PlayMod.getOrderMod()
	OrderList := OrderMod.GetOrderList()
	AllChess := make(map[string]struct{}, 0)
	for _, v := range OrderList {
		for _, v1 := range v.MergeId {
			Color := mergeDataCfg.GetColorById(v1)
			AllChess[Color] = struct{}{}
		}
	}
	RetireEmit := ChessMod.GetRetireEmit()
	for k, v := range RetireEmit {
		if k == "" {
			continue
		}
		if v != 1 {
			continue
		}
		NeedFinishOrder := false
		Produce := mergeDataCfg.GetEmitProduce(k)
		for _, v1 := range Produce {
			if _, ok := AllChess[v1]; ok {
				NeedFinishOrder = true
				break
			}
		}
		if NeedFinishOrder {
			continue
		}
		ChessMod.RetireOrder(k)
	}
	for _, v := range OrderList {
		if v.Type == order.Clean_type {
			return
		}
	}
	RetireEmit1 := ChessMod.GetRetireEmit()
	for k, v := range RetireEmit1 {
		if k == "" {
			continue
		}
		if v != 2 {
			continue
		}
		ChessList := ChessMod.GetRetireChess(k)
		// 清理完成
		if len(ChessList) == 0 {
			ChessMod.FinishRetire(k)
			ChargeMod := p.PlayMod.getChargeMod()
			ChargeMod.InitChessShop(ChessMod.GetEmitList())
			p.PushClientRes(ChargeMod.BackData())
			continue
		}
		OrderMod.CreateCleanOrder(ChessList)
		return
	}
}

func LoignBack(p *Player) {
	BaseMod := p.PlayMod.getBaseMod()
	if BaseMod.LoginBack {
		return
	}
	PlayBaseMod := p.GetPlayerBaseMod()
	Num1, Num2 := mailCfg.GetLoginBack(PlayBaseMod.Data.UserName)
	Items := make([]*item.Item, 0)
	if Num1 != 0 {
		Items = append(Items, &item.Item{Id: item.ITEM_DIAMOND_ID, Num: Num1})
	}
	if Num2 != 0 {
		Items = append(Items, &item.Item{Id: item.ITEM_DIAMOND_ID, Num: Num2})
	}
	if len(Items) != 0 {
		MailMod := p.PlayMod.getMailMod()
		MailMod.Send("Test Players' Refund",
			`Welcome back to our game!
	Here comes your refund for your scene progress and payment in test version!
	Have fun in new version!`, Items)
	}
	BaseMod.LoginBack = true
}

func Benchmark(player *Player) {
	ChampshipMod := player.PlayMod.getChampshipMod()
	ChampshipMod.AddScore([]int{949, 941, 10})
	player.HandleInChampshipRank()
	player.HandleInUserRank()
}

func GetUidByFaceBook(Fb string) (int, error) {
	sqlStr := "SELECT dwUin FROM t_player_baseinfo WHERE FaceBookId = ?"
	type Result struct {
		Uid int `db:"dwUin"`
	}
	R := Result{}
	err := db.SqlDb.Get(&R, sqlStr, Fb)
	log.Debug("Fb :%s;Uid :%d", Fb, R.Uid)
	return R.Uid, err
}

func NotifyAllFriend(p *Player, m *msg.Msg) {
	FriendMod := p.PlayMod.getFriendMod()
	for k := range FriendMod.FriendList {
		if k == int(p.M_DwUin) {
			continue
		}
		m.To = k
		FriendMgrSend(m)
	}
}
