package catnip

import (
	"fmt"
	catnipCfg "server/conf/catnip"
	"server/game/mod/item"
	GoUtil "server/game_util"
)

type CatnipMod struct {
	Id               int
	Game             map[int]*CatnipGame
	Mul              int                 // 倍数
	IsGetGrandReward bool                // 是否领取过大丰收奖励
	InviteList       map[int]*InviteInfo // 邀请列表，key: 邀请者ID, value: 被邀请者ID
	BeInvitedList    map[int]*InviteInfo // 被邀请列表，key: 被邀请者ID, value: 邀请者ID
}

type InviteInfo struct {
	InviteId int   // 邀请者ID
	Time     int64 // 邀请时间
}

type CatnipGame struct {
	Id         int   // 游戏ID
	Partner    int   // 伙伴ID
	Progress   int   // 进度
	PartnerAdd int   // 伙伴贡献
	Reward     []int // 已领取阶段奖励
	Status     int   // 0: Not Started, 1: In Progress, 2: Completed
	SendEmoji  int   // 发送的表情ID
	EmojiId    int   // 表情ID
}

const (
	GAME_STATUS_IDLE        = 0 // 游戏未开始
	GAME_STATUS_IN_PROGRESS = 1 // 游戏进行中
	GAME_STATUS_COMPLETED   = 2 // 游戏已完成
)

func (c *CatnipMod) InitData() {
	if c.Game == nil {
		c.Game = make(map[int]*CatnipGame)
	}
	if c.InviteList == nil {
		c.InviteList = make(map[int]*InviteInfo)
	}
	if c.BeInvitedList == nil {
		c.BeInvitedList = make(map[int]*InviteInfo)
	}
}

// 登录 判断是否需要重置数据
func (c *CatnipMod) Login(Id int) (int, []*item.Item) {
	OldId := c.Id
	if Id == 0 {
		c.Id = 0
		return OldId, nil
	}
	if c.Id == Id {
		return 0, nil
	}
	Items := c.GetUnGetReward()
	c.Id = Id
	c.IsGetGrandReward = false // Reset grand reward status on login
	c.Game = make(map[int]*CatnipGame)
	c.Mul = 1                             // Default multiplier
	GameNum := catnipCfg.GetGameNum(c.Id) // Assuming 1 is the default game ID
	c.InviteList = make(map[int]*InviteInfo)
	c.BeInvitedList = make(map[int]*InviteInfo)
	for i := 1; i <= GameNum; i++ {
		c.Game[i] = &CatnipGame{
			Id:       i,
			Partner:  0,                // No partner initially
			Progress: 0,                // Initial progress
			Status:   GAME_STATUS_IDLE, // Not started
		}
	}
	return OldId, Items
}

func (c *CatnipMod) ZeroUpdate(Id int) {
	c.Login(Id)
}

// 邀请好友
func (c *CatnipMod) Invite(Uid, Id int) error {
	if c.InviteList[Uid] != nil {
		return fmt.Errorf("user with ID %d is already invited", Uid)
	}

	c.InviteList[Uid] = &InviteInfo{
		InviteId: Id,
		Time:     GoUtil.Now(),
	}
	return nil
}

// 被邀请
func (c *CatnipMod) BeInvited(Uid int, Time int64) error {
	// Check if the user is already invited
	invite := c.BeInvitedList[Uid]
	if invite != nil {
		return fmt.Errorf("user with ID %d has already been invited ", Uid)
	}
	c.BeInvitedList[Uid] = &InviteInfo{
		InviteId: Uid,
		Time:     Time,
	}
	return nil
}

// 同意邀请
func (c *CatnipMod) Agree(Id, Uid int) ([]int, error) {
	_, exists := c.BeInvitedList[Uid]
	if !exists {
		return nil, fmt.Errorf("user with ID %d is not invited to game ID %d", Uid, Id)
	}
	delete(c.BeInvitedList, Uid)
	for _, GameInfo := range c.Game {
		if GameInfo.Partner == 0 {
			GameInfo.Partner = Uid
			GameInfo.Status = GAME_STATUS_IN_PROGRESS
			return nil, nil
		}
	}
	return nil, nil
}

// 同意邀请-指定格子
func (c *CatnipMod) BeAgree(Id, Uid int) ([]int, error) {
	info, exists := c.InviteList[Uid]
	if !exists {
		return nil, fmt.Errorf("user with ID %d is not invited to game ID %d", Uid, Id)
	}
	delete(c.InviteList, Uid)
	GameInfo := c.Game[info.InviteId]
	if GameInfo.Partner == 0 {
		GameInfo.Partner = Uid
		GameInfo.Status = GAME_STATUS_IN_PROGRESS
		return nil, nil
	}
	// 目标格子已有伙伴，分配到第一个空闲格
	for _, GameInfo := range c.Game {
		if GameInfo.Partner == 0 {
			GameInfo.Partner = Uid
			GameInfo.Status = GAME_STATUS_IN_PROGRESS
			return nil, nil
		}
	}
	return nil, nil
}

// 删除邀请
func (c *CatnipMod) DelInvited(Id, Uid int) error {
	delete(c.InviteList, Uid)
	return nil
}

// 设置倍数
func (c *CatnipMod) Multiply(Mul int) error {
	c.Mul = Mul
	return nil
}

// 拒绝邀请
func (c *CatnipMod) Refuse(Id, Uid int) error {
	delete(c.BeInvitedList, Uid)
	return nil
}

// 玩游戏
func (c *CatnipMod) Play(Id int) (int, int, int, []*item.Item, []*item.Item, int, error) {
	GameInfo, ok := c.Game[Id]
	if !ok {
		return 0, 0, 0, nil, nil, 0, fmt.Errorf("game with ID %d does not exist", Id)
	}
	if GameInfo.Status != GAME_STATUS_IN_PROGRESS {
		return 0, 0, 0, nil, nil, 0, fmt.Errorf("game with ID %d is not in progress", Id)
	}
	Id, Items, Growth, FriendItems := catnipCfg.GetJackpotItem(c.Mul)
	Growth = Growth * c.Mul
	if Growth > 0 {
		c.Growth(Id, Growth)
	}
	ItemCost := catnipCfg.GetItemCost(c.Id, c.Mul)
	GameInfo.Progress += Growth
	return Id, Growth, GameInfo.Partner, Items, ItemCost, FriendItems, nil
}

// 领取奖励
func (c *CatnipMod) Reward(Id int) ([]*item.Item, *CatnipGame, error) {
	GameInfo, ok := c.Game[Id]
	if !ok {
		return nil, nil, fmt.Errorf("game with Progress %d does not exist", Id)
	}
	Items, Ids := catnipCfg.GetProgressReward(c.Id, GameInfo.Reward, GameInfo.Progress)
	ProgressNum := catnipCfg.GetProgressNum(c.Id)
	GameInfo.Reward = append(GameInfo.Reward, Ids...)
	if len(GameInfo.Reward) == ProgressNum {
		GameInfo.Status = GAME_STATUS_COMPLETED
	}
	if Items == nil {
		return nil, nil, fmt.Errorf("no reward found for progress %d in game ID %d", GameInfo.Progress, Id)
	}
	return Items, GameInfo, nil
}

// 领取大奖励
func (c *CatnipMod) GrandReward() ([]*item.Item, error) {
	for _, game := range c.Game {
		if game.Status != GAME_STATUS_COMPLETED {
			return nil, fmt.Errorf("game with ID %d is not completed", game.Id)
		}
	}
	if c.IsGetGrandReward {
		return nil, fmt.Errorf("grand reward has already been claimed")
	}
	c.IsGetGrandReward = true
	return catnipCfg.GetGrandReward(c.Id), nil
}

// 进度增加
func (c *CatnipMod) Growth(Id, Growth int) {
	GameInfo, ok := c.Game[Id]
	if !ok {
		return // Game does not exist
	}
	if GameInfo.Status != GAME_STATUS_IN_PROGRESS {
		return // Game is not in progress
	}
	GameInfo.Progress += Growth
	if GameInfo.Progress >= catnipCfg.GetGameMaxProgress(c.Id) {
		GameInfo.Status = GAME_STATUS_COMPLETED
	}
}

// 伙伴贡献增加
func (c *CatnipMod) GrowthByUid(Uid, Growth int) {
	for _, v := range c.Game {
		if v.Partner == Uid {
			v.Progress += Growth
			v.PartnerAdd += Growth
			if v.Progress >= catnipCfg.GetGameMaxProgress(c.Id) {
				v.Status = GAME_STATUS_COMPLETED
			}
		}
	}

}

// 设置表情
func (c *CatnipMod) SetEmoji(Uid, EmojiId int) {
	for _, v := range c.Game {
		if v.Partner == Uid {
			v.EmojiId = EmojiId
			return
		}
	}
}

func (c *CatnipMod) GetMultiple() int {
	return c.Mul
}

func (c *CatnipMod) GetGameInfo(Id int) *CatnipGame {
	return c.Game[Id]
}

func (c *CatnipMod) SetSendEmoji(Id, EmojiId int) {
	c.Game[Id].SendEmoji = EmojiId
}

// 获取未领取的奖励
func (c *CatnipMod) GetUnGetReward() []*item.Item {
	var rewards []*item.Item
	for _, v := range c.Game {
		Items, _, _ := c.Reward(v.Id)
		rewards = append(rewards, Items...)
	}
	BigReward, err := c.GrandReward()
	if err == nil {
		rewards = append(rewards, BigReward...)
	}
	return rewards
}
