package charge

import (
	"fmt"
	"server/GoUtil"
	chargeCfg "server/conf/charge"
	mergeDataCfg "server/conf/mergeData"
	"server/game/mod/item"
	"server/msg"
	"server/pkg/github.com/name5566/leaf/log"
)

type ChargeMod struct {
	FirstCharge   int64            // 首次充值时间
	LastCharge    int64            // 最后一次充值时间
	EnergyShop    map[int]struct{} // 能量购买次数商店
	MaxCharge     float64          // 最大充值金额
	Charge        float64          // 总充值金额
	Total         int              // 总充值次数
	SpecialCharge float64          // 近35天最大充值金额

	SpecialShop map[int]*SepcialShop // 特殊商店
	FreeShop    int                  // 已领取免费商店档次

	ChessShop map[int]*ChessShop // 棋子商店

	Gift map[int]int // 礼包

	Ad bool // 是否购买免广告
}
type Rand struct {
	ChessId int
	Diamond int
}
type ChessShop struct {
	Diamond int
	Count   int
	Id      int
}

type SepcialShop struct {
	Grade int
	Count int
}

var ChessDiamondCfg = map[int]int{
	1: 5,
	2: 10,
	3: 20,
	4: 50,
}

const (
	SPECIAL_TYPE_1 = 1 // 特惠礼包1
	SPECIAL_TYPE_2 = 2 // 特惠礼包2

)

func (c *ChargeMod) InitData() {
	if c.SpecialShop == nil {
		c.SpecialShop = make(map[int]*SepcialShop)
	}
	if c.EnergyShop == nil {
		c.EnergyShop = make(map[int]struct{})
	}
	if c.Gift == nil {
		c.Gift = make(map[int]int)
	}
}

func (c *ChargeMod) GetMaxCharge() float64 {
	return c.MaxCharge
}

// 零点更新
func (c *ChargeMod) ZeroUpdate(Emit []int) {
	Now := GoUtil.Now()
	if c.LastCharge != 0 && Now-c.LastCharge > 35*24*3600 {
		c.SpecialCharge = 0
	}
	c.FreeShop = 0
	SpecialGrade := 1
	c.SpecialShop = make(map[int]*SepcialShop)
	SpecialShopCount := chargeCfg.GetSpecialShopCount()
	for i := 1; i <= 2; i++ {
		if c.Total == 0 {
			c.SpecialShop[i] = &SepcialShop{Grade: SpecialGrade, Count: 2}
			continue
		}
		m := c.SpecialCharge
		M := chargeCfg.GetSpecialShopGrade(m, i)
		a := min(2, GoUtil.FullWeeksSince(c.LastCharge))
		SpecialGrade = max(1, M-a)
		c.SpecialShop[i] = &SepcialShop{Grade: SpecialGrade, Count: SpecialShopCount}
	}
	c.InitChessShop(Emit)
}

// 十二点更新 重置商店
func (c *ChargeMod) NoonUpdate(Emit []int) {
	c.InitChessShop(Emit)
}

// 充值
func (c *ChargeMod) Fire(ChargeId int) (Item []*item.Item) {
	Money := chargeCfg.GetMoneyCharge(ChargeId)
	if Money == 0 {
		return
	}
	c.Charge += Money
	c.Total++
	Now := GoUtil.Now()
	if c.FirstCharge == 0 {
		c.FirstCharge = Now
	}
	if c.LastCharge != 0 && Now-c.LastCharge > 35*24*3600 {
		c.SpecialCharge = 0

	}
	c.LastCharge = Now
	if Money > c.MaxCharge {
		c.MaxCharge = Money
	}
	c.SpecialCharge = max(c.SpecialCharge, Money)
	Item = c.FireDiamondShop(ChargeId)
	if Item != nil {
		return
	}
	Item = c.FireEnergyShop(ChargeId)
	if Item != nil {
		return
	}
	Item = c.FireSpecialShop(ChargeId)
	if Item != nil {
		return
	}
	Item = c.FireGift(ChargeId)
	c.FireAd(ChargeId)
	return
}

// 钻石商店
func (c *ChargeMod) FireDiamondShop(ChargeId int) []*item.Item {
	return chargeCfg.GetDiamondShopReward(ChargeId)
}

// 能量商店
func (c *ChargeMod) FireEnergyShop(ChargeId int) []*item.Item {
	id := chargeCfg.GetEnergyShopId(ChargeId)
	_, ok := c.EnergyShop[id]
	c.EnergyShop[id] = struct{}{}
	return chargeCfg.GetEnergyShopReward(ChargeId, ok)
}

// 特惠礼包
func (c *ChargeMod) FireSpecialShop(ChargeId int) []*item.Item {
	Type := chargeCfg.GetSpecialShopType(ChargeId)
	if _, ok := c.SpecialShop[Type]; !ok {
		return nil
	}
	if c.SpecialShop[Type].Count < 1 {
		log.Debug("special shop recharge max, type: %d, charge id: %d", Type, ChargeId)
		return nil
	}
	c.SpecialShop[Type].Count--
	return chargeCfg.GetSpecialShopReward(ChargeId)
}

// 通用礼包
func (c *ChargeMod) FireGift(ChargeId int) []*item.Item {
	Limit := chargeCfg.GetGiftLimit(ChargeId)
	if Limit == 0 {
		return nil
	}
	Id := chargeCfg.GetGiftId(ChargeId)

	if v, ok := c.Gift[Id]; ok {
		if v >= Limit {
			return nil
		}
	}
	c.Gift[Id]++
	return chargeCfg.GetGiftReward(ChargeId)
}

// 免广告礼包
func (c *ChargeMod) FireAd(ChargeId int) []*item.Item {
	AdChargeId := chargeCfg.GetAdChargeId()
	if ChargeId != AdChargeId {
		return nil
	}
	c.Ad = true
	return nil
}

// 免费商店
func (c *ChargeMod) FireFreeShop() ([]*item.Item, error) {
	if c.FreeShop >= 2 {
		return nil, fmt.Errorf(" free shop reward max")
	}
	c.FreeShop++
	return chargeCfg.GetFreeShopReward(c.FreeShop), nil
}

// 返回数据
func (c *ChargeMod) BackData() *msg.ResCharge {
	SpecialShop := make(map[int32]*msg.ResSpecialShop)
	ChessShop := make(map[int32]*msg.ResChessShop)
	for k, v := range c.SpecialShop {
		SpecialShop[int32(k)] = &msg.ResSpecialShop{
			Grade: int32(v.Grade),
			Count: int32(v.Count),
		}
	}

	for k, v := range c.ChessShop {
		ChessShop[int32(k)] = &msg.ResChessShop{
			Diamond: int32(v.Diamond),
			Count:   int32(v.Count),
			ChessId: int32(v.Id),
		}
	}

	return &msg.ResCharge{
		Charge:      float32(c.Charge),
		Total:       int32(c.Total),
		First:       GoUtil.MapIntToSlice(c.EnergyShop),
		SpecialShop: SpecialShop,
		FreeShop:    int32(c.FreeShop),
		ChessShop:   ChessShop,
		Gift:        GoUtil.MapIntToInt32(c.Gift),
		Ad:          c.Ad,
	}
}

func (c *ChargeMod) InitChessShop(Emit []int) {
	if len(Emit) == 0 {
		return
	}
	c.ChessShop = make(map[int]*ChessShop)
	ColorList := make([]string, 0)
	for _, v := range Emit {
		ProduceList := mergeDataCfg.GetEmitProduceType(v)
		ColorList = append(ColorList, ProduceList...)
	}

	RandList := make([]*Rand, 0)
	for _, v := range ColorList {
		ColorType := mergeDataCfg.GetColorType(v)
		r := make([]*Rand, 0)
		if ColorType == mergeDataCfg.CHESS_PRODUCT_MAIN_TYPE {
			r = getChessMainRand(v)
		} else if ColorType == mergeDataCfg.CHESS_PRODUCT_SECONDARY_TYPE {
			r = getChessSecondaryRand(v)
		} else if ColorType == mergeDataCfg.CHESS_PRODUCT_SUB_TYPE {
			r = getChessSubRand(v)
		}
		RandList = append(RandList, r...)
	}
	randList := make([]interface{}, len(RandList))
	for k, v := range RandList {
		randList[k] = v
	}
	L := GoUtil.RandSliceNum2(randList, 5)
	for k, v := range L {
		Diamond := v.(*Rand).Diamond
		ChessId := v.(*Rand).ChessId
		c.ChessShop[k+1] = &ChessShop{Diamond: Diamond, Count: 5, Id: ChessId}
	}
}

func (c *ChargeMod) BuyChess(Chess int) ([]*item.Item, []*item.Item, int, error) {
	v, ok := c.ChessShop[Chess]
	if !ok {
		return nil, nil, 0, fmt.Errorf("BuyChess chess id not exist id:%d", Chess)
	}

	if v.Count <= 0 {
		return nil, nil, 0, fmt.Errorf("BuyChess chess count less zero id:%d", Chess)
	}
	v.Count--
	return []*item.Item{
			item.NewItem(item.ITEM_DIAMOND_ID, v.Diamond),
		}, []*item.Item{
			item.NewItem(v.Id, 1),
		}, v.Id, nil
}

func (c *ChargeMod) TriggerChargeUnlock(Lv int, Emit []int) {
	UnlockLv := chargeCfg.GetUnlockShopLv()
	if Lv != UnlockLv {
		return
	}
	c.InitChessShop(Emit)
}
