package model

import (
	"fmt"
	"leafstalk/otherutils/deepcopy"
	"strconv"

	"xorm.io/xorm"
)

// 聊天类型
const (
	ChatTypeConfig  = "config"  // 配置
	ChatTypeWorld   = "world"   // 世界频道
	ChatTypeRecruit = "recruit" // 招募频道
	ChatTypePrivate = "private" // 私聊
)

// 定义三种掩码类型
const (
	ChangedMaskConfig  uint32 = 1 << iota // 配置变动掩码
	ChangedMaskWorld                      // 世界频道变动掩码
	ChangedMaskRecruit                    // 招募频道变动掩码
)

// 玩家聊天数据
type ChatPlayer struct {
	Id          int64              // id
	PlayerId    int64              `xorm:"BIGINT index 'playerid'"` // 玩家ID
	WearFrame   int64              `xorm:"BIGINT 'wearFrame'"`      //当前使用的聊天框
	// EmojiIds    map[int64]struct{} `xorm:" Text 'emojiIds'"`        // 激活的表情Id(花费)
	ChatFrames  map[int64]struct{} `xorm:"Text chatFrames"`         // 激活的框Id(花费)
	ChatFriends map[int64]int64    `xorm:"Text privateFriends"`     // 私聊好友列表 {playerId:lastMsgTime}
	GateId      int64              `xorm:"BIGINT gateId"`           // 最近所在网关
	SendTs      int64              `xorm:"-"`                       // 发言CD时间
}

// TableName 表名
func (m ChatPlayer) TableName() string {
	return "chat_player"
}

func (m *ChatPlayer) QueryExist(eng *xorm.Engine) (bool, error) {
	player := new(ChatPlayer)
	player.PlayerId = m.PlayerId
	return eng.Exist(player)
}

func (m *ChatPlayer) UpdateDB(eng *xorm.Engine) (int64, error) {
	return eng.Where("playerid=?", m.PlayerId).AllCols().Update(m)
}

func (m *ChatPlayer) GetUniqueKey() string {
	return strconv.FormatInt(m.PlayerId, 10)
}

func CopyChat(old *ChatPlayer) *ChatPlayer {
	nu := deepcopy.MustCopy(old).(*ChatPlayer)
	return nu
}

// 聊天数据
type ChatChannel struct {
	Id         int64  // id
	ChatType   string `xorm:"varchar(100) index 'chatType'"` // 类型
	Content    string `xorm:"text json 'content'"`           // 内容
	LastChatTs int64  `xorm:"BIGINT 'lastChatTs'"`           // 最后一条聊天
}

func (m *ChatChannel) TableName() string {
	return "chat_channel"
}

// ChatConfig  配置
// type ChatConfig struct {
// 	ChatBlockedUsers    map[int64]int64  `json:"chatBlockedUsers"`    // 禁止玩家	Key: userID, Value: 截止日期
// 	ChatBlockedChannels map[string]int64 `json:"chatBlockedChannels"` // 禁止频道	Key: channelID, Value: 截止日期
// }

// ChatContent 频道内容
type ChatContent struct {
	Id            string            `json:"id"`       // 聊天Id
	ChatType      string            `json:"chatType"` // 聊天类型
	SenderId      int64             `json:"senderId"`
	SenderName    string            `json:"senderName"`
	SenderHeadId  int64             `json:"senderHeadId"`  // 头像 -1 代表使用 AvatarURL 微信授权头像
	SenderFrameId int64             `json:"senderFrameId"` // 头像框
	SenderLevel   int               `json:"senderLevel"`
	SenderRenow   int               `json:"senderRenow"`
	ChatFrame     int64             `json:"chatFrame"`
	ReceiverId    int64             `json:"receiverId"` // 接收者Id
	MsgType       string            `json:"msgType"`    // text：文本 emoji：表情
	Content       string            `json:"content"`    // 聊天内容
	StrParam      map[string]string `json:"strParam"`   // string参数信息
	CreateTime    int64             `json:"createTime"` // 产生时间(毫秒)
}

// ChannelInfo 频道信息
type ChannelInfo struct {
	ChatType   string         `json:"chatType"`   // 频道类型
	Content    []*ChatContent `json:"content"`    // 频道内容
	LastChatTs int64          `json:"lastChatTs"` // 最后一条聊天
	// Changed    bool           `json:"-"`          // 变动
}

func NewChannelInfo(chatType string) *ChannelInfo {
	return &ChannelInfo{
		ChatType: chatType,
		Content:  make([]*ChatContent, 0),
	}
}

// ChatSysInfo 聊天系统信息
type ChatSysInfo struct {
	BanUsers       map[int64]int64  `json:"users"`    // 禁止玩家	Key: userID, Value: 截止日期
	BanChannels    map[string]int64 `json:"channels"` // 禁止频道	Key: channelID, Value: 截止日期
	WorldChannel   *ChannelInfo     `json:"world"`    // 世界频道
	RecruitChannel *ChannelInfo     `json:"recruit"`  // 招募频道
	ChangedMask    uint32           `json:"-"`
}

// SetChangedMask 设置变动掩码
func (it *ChatSysInfo) SetChangedMask(chatType string) {
	switch chatType {
	case ChatTypeConfig:
		it.ChangedMask |= ChangedMaskConfig
	case ChatTypeWorld:
		it.ChangedMask |= ChangedMaskWorld
	case ChatTypeRecruit:
		it.ChangedMask |= ChangedMaskRecruit
	}
}

// ClearChangedMask 清除变动掩码
func (it *ChatSysInfo) ClearChangedMask() {
	it.ChangedMask = 0
}

func NewChatSysInfo() *ChatSysInfo {
	it := new(ChatSysInfo)
	it.BanChannels = make(map[string]int64)
	it.BanUsers = make(map[int64]int64)
	it.WorldChannel = NewChannelInfo(ChatTypeWorld)
	it.RecruitChannel = NewChannelInfo(ChatTypeRecruit)
	return it
}

// Emojis 聊天表情
type Emojis struct {
	Uid    int64 `json:"Uid"`    // 唯一ID
	ItemId int64 `json:"ItemId"` // 解锁道具Id  0:免费
}

// 私人聊天记录
type ChatPrivate struct {
	Id         int64          // id
	PlayerId1  int64          `xorm:"BIGINT index 'playerid1'"` // 玩家ID
	PlayerId2  int64          `xorm:"BIGINT index 'playerid2'"` // 玩家ID
	Content    []*ChatContent `xorm:"Text content"`             // 频道内容
	LastChatTs int64          `xorm:"updated"`                  // 最后一条聊天"`
	Changed    bool           `xorm:"-"`                        // 变动
}

func (m *ChatPrivate) TableName() string {
	return "chat_private"
}

func (m *ChatPrivate) QueryExist(eng *xorm.Engine) (bool, error) {
	player := new(ChatPrivate)
	player.PlayerId1 = m.PlayerId1
	player.PlayerId2 = m.PlayerId2
	return eng.Exist(player)
}

func (m *ChatPrivate) UpdateDB(eng *xorm.Engine) (int64, error) {
	return eng.Where("playerid1=? and playerid2=?", m.PlayerId1, m.PlayerId2).Update(m)
}

func (m *ChatPrivate) GetUniqueKey() string {
	return fmt.Sprintf("%v:%v", m.PlayerId1, m.PlayerId2)
}

// 实现DeepCopy接口
func CopyChatPrivate(old *ChatPrivate) *ChatPrivate {
	new2 := deepcopy.MustCopy(old).(*ChatPrivate) //
	return new2
}
