package game

import (
	"fmt"
	activityCfg "server/conf/activity"
	catnipCfg "server/conf/catnip"
	guesscolorCfg "server/conf/guess_color"
	languageCfg "server/conf/language"
	miningCfg "server/conf/mining"
	passCfg "server/conf/pass"
	raceCfg "server/conf/race"
	"server/game/mod/activity"
	"server/game/mod/item"
	"server/game/mod/mail"
	GoUtil "server/game_util"
	"server/msg"
)

// 活动模块 登录
func (p *Player) ActivityLogin() {
	ItemMod := p.PlayMod.getItemMod()

	// 通用登录处理：检查旧Activity道具并通过邮件退还
	handleSimpleLogin := func(actType int, loginFn func(int) int) {
		ActivityId := p.GetActivityId(actType)
		OldId := loginFn(ActivityId)
		if OldId == 0 {
			return
		}
		ItemId := guesscolorCfg.GetActivityItemId(OldId)
		ItemNum := ItemMod.GetItem(ItemId)
		if ItemNum != 0 {
			ItemMod.AddItem(ItemId, -ItemNum)
			p.SendActivityMail(ItemId, ItemNum, ActivityId, nil)
		}
	}

	// 挖矿
	handleSimpleLogin(activity.ACT_TYPE_MINING, p.PlayMod.getMiningMod().Login)
	// 猜颜色
	handleSimpleLogin(activity.ACT_TYPE_GUESS_COLOR, p.PlayMod.getGuessColorMod().Login)
	// 赛跑
	handleSimpleLogin(activity.ACT_TYPE_RACE, p.PlayMod.getRaceMod().Login)
	// 猫草大作战
	CatnipActivityId := p.GetActivityId(activity.ACT_TYPE_CATNIP)
	CatnipMod := p.PlayMod.getCatnipMod()
	OldId, CatnipUnReward := CatnipMod.Login(CatnipActivityId)
	if OldId != 0 && len(CatnipUnReward) > 0 {
		// 清空猫草大作战数据无需发邮件
		MailMod := p.PlayMod.getMailMod()
		MailMod.SendMail(&mail.MailStruct{
			Title:          languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, "backend_gardenend_mail_title"),
			TitleEn:        languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, "backend_gardenend_mail_title"),
			Content:        languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, "backend_gardenend_mail_content"),
			ContentEn:      languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, "backend_gardenend_mail_content"),
			TitlePtBr:      languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, "backend_gardenend_mail_title"),
			ContentPtBr:    languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, "backend_gardenend_mail_content"),
			TitleEsLatam:   languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, "backend_gardenend_mail_title"),
			ContentEsLatam: languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, "backend_gardenend_mail_content"),
			Items:          CatnipUnReward,
			Type:           mail.MAIL_TYPE_NORMAL,
		})
	}

	// 通行证
	PassActivityId := p.GetActivityId(activity.ACT_TYPE_PASS)
	PassMod := p.PlayMod.getPassMod()
	PassOldId := PassMod.Login(PassActivityId)
	if PassOldId != 0 {
		ItemId := passCfg.GetActivityItemId(PassOldId)
		ItemNum := PassMod.Num
		RewardItems, _ := PassMod.GetRewardItems()
		if ItemNum != 0 {
			ItemMod.AddItem(ItemId, -ItemNum)
			p.SendActivityMail(ItemId, ItemNum, PassActivityId, RewardItems)
		}
	}
}

// 发送活动邮件
func (p *Player) SendActivityMail(ItemId, ItemNum, ActivityId int, RewardItems []*item.Item) {
	MailMod := p.PlayMod.getMailMod()
	activity_title_key, mail_title_key, mail_content_key := activityCfg.GetActivityRecycleMail(ActivityId)
	activity_title_zh := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, activity_title_key)
	activity_title_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, activity_title_key)
	activity_title_pt := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, activity_title_key)
	activity_title_es := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, activity_title_key)
	mt_zh := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, mail_title_key)
	mc_zh := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, mail_content_key)
	mt_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, mail_title_key)
	mc_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, mail_content_key)
	mt_pt := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, mail_title_key)
	mc_pt := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, mail_content_key)
	mt_es := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, mail_title_key)
	mc_es := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, mail_content_key)
	Items := []*item.Item{item.NewItem(ItemId, ItemNum)}
	Items = append(Items, RewardItems...)
	MailMod.SendMail(&mail.MailStruct{
		Title:          fmt.Sprintf(mt_zh, activity_title_zh),
		Content:        fmt.Sprintf(mc_zh, activity_title_zh),
		TitleEn:        fmt.Sprintf(mt_en, activity_title_en),
		ContentEn:      fmt.Sprintf(mc_en, activity_title_en),
		TitlePtBr:      fmt.Sprintf(mt_pt, activity_title_pt),
		ContentPtBr:    fmt.Sprintf(mc_pt, activity_title_pt),
		TitleEsLatam:   fmt.Sprintf(mt_es, activity_title_es),
		ContentEsLatam: fmt.Sprintf(mc_es, activity_title_es),
		Items:          Items,
		Type:           mail.MAIL_TYPE_NORMAL,
	})
}

// 活动模块 零点更新
func (p *Player) ActivityZeroUpdate() {
	p.ActivityLogin()

	type zeroHandler struct {
		actType  int
		updateFn func(int)
	}
	handlers := []zeroHandler{
		{activity.ACT_TYPE_MINING, func(id int) { p.PlayMod.getMiningMod().ZeroUpdate(id) }},
		{activity.ACT_TYPE_GUESS_COLOR, func(id int) { p.PlayMod.getGuessColorMod().ZeroUpdate(id) }},
		{activity.ACT_TYPE_RACE, func(id int) { p.PlayMod.getRaceMod().ZeroUpdate(id) }},
		{activity.ACT_TYPE_PASS, func(id int) { p.PlayMod.getPassMod().ZeroUpdate(id) }},
		{activity.ACT_TYPE_CATNIP, func(id int) { p.PlayMod.getCatnipMod().ZeroUpdate(id) }},
	}
	for _, h := range handlers {
		if info := p.GetActivityInfo(h.actType); info != nil {
			h.updateFn(info.Id)
		}
	}
}

// 获取活动信息
func (p *Player) GetActivityInfo(actType int) *ActivityInfo {
	for _, v := range p.activity {
		if v.Type == actType {
			return v
		}
	}
	return nil
}

// 获取活动ID
func (p *Player) GetActivityId(actType int) int {
	for _, v := range p.activity {
		if v.Type == actType {
			return v.Id
		}
	}
	return 0
}

// 根据活动ID获取活动信息
func (p *Player) GetActivityInfoById(Id int) *ActivityInfo {
	for _, v := range p.activity {
		if v.Id == Id {
			return v
		}
	}
	return nil
}

// 获取活动状态
func (p *Player) GetActivityStatus(actType int) int {
	ActivityInfo := p.GetActivityInfo(actType)
	if ActivityInfo == nil {
		return ACT_STATUS_NOT_START
	}
	Now := GoUtil.Now()
	if Now < ActivityInfo.StartT {
		return ACT_STATUS_NOT_START
	}
	if Now > ActivityInfo.EndT {
		return ACT_STATUS_END
	}
	return ACT_STATUS_START
}

// 挖矿活动数据返回
func (p *Player) MiningBackData() {
	ActivityInfo := p.GetActivityInfo(activity.ACT_TYPE_MINING)
	if ActivityInfo == nil {
		return
	}
	Status := p.GetActivityStatus(activity.ACT_TYPE_MINING)
	Template := miningCfg.GetTemplate(ActivityInfo.Id)
	MiningMod := p.PlayMod.getMiningMod()
	p.PushClientRes(&msg.ResMining{
		Id:       int32(ActivityInfo.Id),
		Status:   int32(Status),
		EndTime:  int32(ActivityInfo.EndT),
		Template: int32(Template),
		Pass:     int32(MiningMod.GetPass()),
		Gem:      GoUtil.IntToInt32(MiningMod.GetGem()),
		Map:      MiningMod.GetMap(),
		Mining:   int32(MiningMod.GetMining()),
	})
}

// 猜颜色活动数据返回
func (p *Player) GuessColorBackData() {
	ActivityInfo := p.GetActivityInfo(activity.ACT_TYPE_GUESS_COLOR)
	if ActivityInfo == nil {
		return
	}

	Status := p.GetActivityStatus(activity.ACT_TYPE_GUESS_COLOR)
	GuessColorMod := p.PlayMod.getGuessColorMod()
	MapList := make([]*msg.GuessColorInfo, 0, len(GuessColorMod.MapList))
	for _, v := range GuessColorMod.MapList {
		MapList = append(MapList, &msg.GuessColorInfo{
			Map: v,
		})
	}
	p.PushClientRes(&msg.ResGuessColor{
		Id:      int32(ActivityInfo.Id),
		Status:  int32(Status),
		EndTime: int32(ActivityInfo.EndT),
		Pass:    int32(GuessColorMod.Pass),
		Opponent: &msg.Opponent{
			Name:     GuessColorMod.Opponent.Name,
			Face:     int32(GuessColorMod.Opponent.Face),
			Avatar:   int32(GuessColorMod.Opponent.Avatar),
			Progress: int32(GuessColorMod.Opponent.Progress),
		},
		WinTime: int32(GuessColorMod.WinTime),
		MapList: MapList,
		OMap:    GuessColorMod.OMap,
	})
}

// 赛跑活动数据返回
func (p *Player) RaceBackData() {
	ActivityInfo := p.GetActivityInfo(activity.ACT_TYPE_RACE)
	if ActivityInfo == nil {
		return
	}
	Status := p.GetActivityStatus(activity.ACT_TYPE_RACE)
	RaceMod := p.PlayMod.getRaceMod()
	Opponent := make([]*msg.Raceopponent, 0, len(RaceMod.Opponent))
	for _, v := range RaceMod.Opponent {
		Opponent = append(Opponent, &msg.Raceopponent{
			Id:       int32(v.Id),
			Name:     v.Name,
			Face:     int32(v.Face),
			Avatar:   int32(v.Avatar),
			Progress: int32(v.Progress),
		})
	}
	p.PushClientRes(&msg.ResRace{
		Id:            int32(ActivityInfo.Id),
		Status:        int32(Status),
		EndTime:       int32(ActivityInfo.EndT),
		Pass:          int32(RaceMod.Pass),
		GameStartTime: int32(RaceMod.StartTime),
		Progress:      int32(RaceMod.Progress),
		GameEndTime:   int32(RaceMod.EndTime),
		Opponent:      Opponent,
		Rank:          int32(RaceMod.Rank),
	})
}

// 红点数据返回
func (p *Player) RedBackData() {
	result := make(map[int32]int32)
	Now := GoUtil.Now()
	for _, v := range p.activity {
		if v.StartT < Now && v.EndT > Now {
			result[int32(v.Type)] = int32(p.GetRed(v))
		}
	}
	p.PushClientRes(&msg.ResActRed{Red: result})
}

// 通行证活动数据返回
func (p *Player) ActPassBackData() {
	ActivityInfo := p.GetActivityInfo(activity.ACT_TYPE_PASS)
	if ActivityInfo == nil {
		return
	}
	Status := p.GetActivityStatus(activity.ACT_TYPE_PASS)
	Template := passCfg.GetTemplate(ActivityInfo.Id)
	PassMod := p.PlayMod.getPassMod()
	p.PushClientRes(&msg.ResActPass{
		Id:       int32(ActivityInfo.Id),
		Status:   int32(Status),
		Template: int32(Template),
		EndTime:  int32(ActivityInfo.EndT),
		LowPass:  PassMod.LowPass > 0,
		HighPass: PassMod.HighPass > 0,
		Score:    int32(PassMod.Num),
		Reward:   GoUtil.IntToInt32(PassMod.Reward),
	})
}

// 获取活动道具
func (p *Player) GetActivityItem(ActType []int) []*item.Item {
	Items := make([]*item.Item, 0)
	Now := GoUtil.Now()
	for _, v := range ActType {
		ActivityInfo := p.GetActivityInfo(v)
		if ActivityInfo == nil {
			continue
		}
		Status := ACT_STATUS_START
		if Now < ActivityInfo.StartT {
			Status = ACT_STATUS_NOT_START
		} else if Now > ActivityInfo.EndT {
			Status = ACT_STATUS_END
		}
		if Status != ACT_STATUS_START {
			continue
		}
		switch v {
		case activity.ACT_TYPE_MINING:
			Item := miningCfg.GetLoseItem(ActivityInfo.Id)
			Items = item.Merge(Items, Item)
		case activity.ACT_TYPE_GUESS_COLOR:
			Item := guesscolorCfg.GetLoseItem(ActivityInfo.Id)
			Items = item.Merge(Items, Item)
		case activity.ACT_TYPE_RACE:
			ItemId := raceCfg.GetCoin(ActivityInfo.Id)
			Item := item.NewItem(ItemId, 1)
			Items = append(Items, Item)
		case activity.ACT_TYPE_PASS:
			ItemId := passCfg.GetActivityItemId(ActivityInfo.Id)
			Item := item.NewItem(ItemId, 1)
			Items = append(Items, Item)
		}
	}
	return Items
}

// 猫草大作战活动数据返回
func (p *Player) CatnipBackData() {
	ActivityInfo := p.GetActivityInfo(activity.ACT_TYPE_CATNIP)
	if ActivityInfo == nil {
		return
	}
	CatnipMod := p.PlayMod.getCatnipMod()
	Status := p.GetActivityStatus(activity.ACT_TYPE_CATNIP)
	if CatnipMod == nil {
		return
	}
	FriendMod := p.PlayMod.getFriendMod()
	GameList := make([]*msg.CatnipGame, 0, len(CatnipMod.Game))
	for _, v := range CatnipMod.Game {
		GameInfo := &msg.CatnipGame{
			Id:             int32(v.Id),
			Progress:       int32(v.Progress),
			Status:         int32(v.Status),
			Reward:         GoUtil.SliceIntToInt32(v.Reward),
			Emoji:          int32(v.EmojiId),
			FriendProgress: int32(v.PartnerAdd),
			SendEmoji:      int32(v.SendEmoji),
		}
		if v.Partner != 0 {
			PlayerData := G_getGameLogic().GetResSimplePlayerByUid(v.Partner)
			if PlayerData != nil {
				GameInfo.Partner = PlayerData
			}
		}

		GameList = append(GameList, GameInfo)
	}
	tmpData := make(map[int]*msg.CatnipInvite)
	for uid, info := range CatnipMod.InviteList {
		tmpData[uid] = &msg.CatnipInvite{
			Uid:  int64(uid),
			Time: info.Time,
			Type: 1,
		}
	}
	for uid, info := range CatnipMod.BeInvitedList {
		tmpData[uid] = &msg.CatnipInvite{
			Uid:  int64(uid),
			Time: info.Time,
			Type: 2,
		}
	}

	for uid := range FriendMod.NewFriendList {
		partnerList := p.GetCatnipPartner(uid)
		if len(GoUtil.IntSlice(partnerList)) >= 4 {
			tmpData[uid] = &msg.CatnipInvite{
				Uid:  int64(uid),
				Type: 3,
			}
			continue
		}
		if _, ok := tmpData[uid]; !ok {
			tmpData[uid] = &msg.CatnipInvite{
				Uid:  int64(uid),
				Type: 0,
			}
		}
	}
	for _, v := range CatnipMod.Game {
		if invite, ok := tmpData[v.Partner]; ok {
			invite.Type = 4 // 已参与游戏的好友不显示邀请
		}
	}
	InviteList := make([]*msg.CatnipInvite, 0, len(tmpData))
	for _, v := range tmpData {
		ResPlayerSimple := G_getGameLogic().GetResSimplePlayerByUid(int(v.Uid))
		if ResPlayerSimple != nil {
			v.Player = ResPlayerSimple
		}
		InviteList = append(InviteList, v)
	}

	Template := catnipCfg.GetTemplateId(CatnipMod.Id)
	res := &msg.ResCatnip{
		Id:         int32(CatnipMod.Id),
		EndTime:    int32(ActivityInfo.EndT),
		Status:     int32(Status),
		Template:   int32(Template),
		GameList:   GameList,
		Multiply:   int32(CatnipMod.Mul),
		FriendList: InviteList,
	}
	p.PushClientRes(res)
}
