package game

import (
	"encoding/gob"
	"fmt"
	"server/GoUtil"
	mergeCluster "server/cluster"
	"server/conf"
	"server/game/mod/card"
	"server/game/mod/item"
	"server/game/mod/msg"
	"server/pkg/github.com/name5566/leaf/log"
)

type FriendMgr struct {
	*ServerMod
}

type FirendData struct {
	Id         int64
	List       map[int][]*msg.Msg // 本服信箱
	ClusterMsg map[int][]*msg.Msg // 集群信箱
}

func (f *FriendMgr) Init() {

	gob.Register(card.CardInfo{})
	gob.Register(item.Item{})
	gob.Register([]*item.Item{}) // 注册 []*item.Item 类型

	f.key = FRIEND_MGR_KEY
	f.data = &FirendData{
		List:       make(map[int][]*msg.Msg),
		ClusterMsg: make(map[int][]*msg.Msg),
	}
	// 注册处理函数
	f.init()
	if f.data.(*FirendData).List == nil {
		f.data.(*FirendData).List = make(map[int][]*msg.Msg)
	}
	if f.data.(*FirendData).ClusterMsg == nil {
		f.data.(*FirendData).ClusterMsg = make(map[int][]*msg.Msg)
	}
	f.RegisterHandler(msg.HANDLE_TYPE_APPLY, f.sendToPlayer)
	f.RegisterHandler(msg.HADNLE_TYPE_AGREE, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_DEL, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_SYNC, f.sync)
	f.RegisterHandler(msg.HANDLE_TYPE_REFUSE, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_INVITE_ADD_FRIEND, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_INVITE_FRIEND, f.sendToPlayer)

	// 卡牌消息
	f.RegisterHandler(msg.HANDLE_TYPE_REQ_CARD, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_AGREE_CARD, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_REG_CARD_REFUSE, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_REG_CARD_FINISH, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_AGREE_CARD_FAIL, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_EX_CARD, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_SELECT_EX_CARD, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_ARGREE_EX_CARD, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_REFUSE_SELECT_CARD, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_REFUSE_EX_CARD, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_SEND_CARD, f.sendToPlayer)
	f.RegisterHandler(msg.HANDLE_TYPE_PLAYROOM_LOSE, f.sendToPlayer)

	f.RegisterHandler(msg.FRIEND_TREASURE_HANDLE, f.sendToPlayer)
}

func (f *FriendMgr) getData() *FirendData {
	return f.data.(*FirendData)
}

func (f *FriendMgr) ZeroUpdate(m *msg.Msg) (interface{}, error) {
	Now := GoUtil.Now()
	for k, v := range f.getData().List {
		for j, msg := range v {
			if msg.End < Now-7*24*3600 {
				f.getData().List[k] = append(f.getData().List[k][:j], f.getData().List[k][j+1:]...)
			}
		}
	}
	return nil, nil
}

// 通知玩家
func (f *FriendMgr) sendToPlayer(m *msg.Msg) (interface{}, error) {
	f.getData().Id++
	m.Id = f.getData().Id
	err := sendToPlayer(m)
	if err == nil {
		m.H = 1
	}
	ToServerId := GoUtil.GetServerIdByUid(m.To)
	if ToServerId != conf.Server.ServerID {
		f.getData().ClusterMsg[m.To] = append(f.getData().ClusterMsg[m.To], m) // 保存到集群消息
	} else {
		f.getData().List[m.To] = append(f.getData().List[m.To], m) // 保存到本地消息
	}
	log.Debug("send to player success")
	return nil, nil
}

// 同步信息
func (f *FriendMgr) sync(m *msg.Msg) (interface{}, error) {
	data := f.getData().List[m.From]
	for _, v := range data {
		v.H = 1
	}
	log.Debug("sync friendMgr msg to player %d success mailbox %v", m.From, data)
	return data, nil
}

// 发送消息给玩家
func sendToPlayer(m *msg.Msg) error {
	p := G_GameLogicPtr.GetPlayer(int64(m.To))
	if p == nil || p.stop {
		return fmt.Errorf("player %d not online", m.To)
	}
	p.Send(m)
	return nil
}

func FriendMgrSend(m *msg.Msg) error {
	ToServer := GoUtil.GetServerIdByUid(m.To)
	if ToServer != conf.Server.ServerID {
		err := mergeCluster.SendServerMsg(m, ToServer)
		if err != nil { // 区服不在线
			G_GameLogicPtr.FriendMgrSend(m)
			log.Debug("send to server %d error : %s\n", ToServer, err)
			return err
		}
		return nil
	}
	log.Debug("send to server %d success, %d", ToServer, conf.Server.ServerID)
	G_GameLogicPtr.FriendMgrSend(m)
	return nil
}

// 集群好友消息同步
func ClusterFriendSync(m *msg.Msg) error {
	log.Debug("ClusterFriendSync")
	if v, ok := G_GameLogicPtr.FriendMgr.getData().ClusterMsg[m.To]; ok {
		for _, msg := range v {
			mergeCluster.SendServerMsg(msg, m.To)
		}
	}
	return nil
}

func FriendMgrCall(m *msg.Msg) interface{} {
	return G_GameLogicPtr.FriendMgrCall(m)
}
