package chargeCfg

import (
	"server/game/mod/item"
	GoUtil "server/game_util"
	"server/gamedata"
	"server/pkg/github.com/name5566/leaf/log"
	"sort"
	"strings"
)

const (
	CFG_CHARGE         = "Charge"
	CFG_DIAMOND_SHOP   = "DiamondShop"   // 钻石商店
	CFG_ENERGY_SHOP    = "EnergyShop"    // 体力商店
	CFG_SEPCIAL_SHOP   = "SpecialShop"   // 特惠商店
	CFG_FREE_SHOP      = "FreeShop"      // 免费商店
	CFG_CHARGE_CONST   = "ChargeConst"   // 充值常量配置
	CFG_CHARGE_GIFT    = "ChargeGift"    // 充值礼包
	CFG_CHARGE_WISH    = "ChargeWish"    // 许愿配置
	CFG_CHARGE_PETCOIN = "ChargePetCoin" // 宠物币充值配置
	CFG_CHARGE_AD      = "ChargeAD"      // 广告充值配置
)

func init() {
	gamedata.InitCfg(CFG_CHARGE)
	gamedata.InitCfg(CFG_DIAMOND_SHOP)
	gamedata.InitCfg(CFG_ENERGY_SHOP)
	gamedata.InitCfg(CFG_SEPCIAL_SHOP)
	gamedata.InitCfg(CFG_FREE_SHOP)
	gamedata.InitCfg(CFG_CHARGE_CONST)
	gamedata.InitCfg(CFG_CHARGE_GIFT)
	gamedata.InitCfg(CFG_CHARGE_WISH)
	gamedata.InitCfg(CFG_CHARGE_PETCOIN)
	gamedata.InitCfg(CFG_CHARGE_AD)
}

func GetADReward(ChargeId int) ([]*item.Item, int) {
	data, err := gamedata.GetData(CFG_CHARGE_AD)
	if err != nil {
		log.Debug("GetADReward err:%v, ChargeId=%d", err, ChargeId)
		return nil, 0
	}
	for _, v := range data {
		if gamedata.GetIntValue(v, "ChargeId") == ChargeId {
			return item.ParseItem(gamedata.GetValue(v, "Items")), gamedata.GetIntValue(v, "PetWork")
		}
	}
	return nil, 0
}

func GetWeeklyDiscountDay() int {
	data, err := gamedata.GetDataByKey(CFG_CHARGE_CONST, "weekly_discount_day")
	if err != nil {
		log.Debug("GetWeeklyDiscountDay err:%v", err)
		return -1
	}
	return gamedata.GetIntValue(data, "Value")
}

func GetMoneyCharge(ChargeId int) float64 {
	data, err := gamedata.GetDataByIntKey(CFG_CHARGE, ChargeId)
	if err != nil {
		log.Debug("GetMoneyCharge err:%v, ChargeId=%d", err, ChargeId)
		return 0
	}
	return gamedata.GetFloatValue(data, "Money")
}

func GetDiamondShopReward(ChargeId int) []*item.Item {
	data, err := gamedata.GetData(CFG_DIAMOND_SHOP)
	if err != nil {
		log.Debug("GetDiamondShopReward err:%v, ChargeId=%d", err, ChargeId)
		return nil
	}
	for _, v := range data {
		if gamedata.GetIntValue(v, "ChargeId") == ChargeId {
			return []*item.Item{item.NewItem(item.ITEM_DIAMOND_ID, gamedata.GetIntValue(v, "Diamond"))}
		}
	}
	return nil
}

func GetEnergyShopId(ChargeId int) int {
	data, err := gamedata.GetData(CFG_ENERGY_SHOP)
	if err != nil {
		log.Debug("GetEnergyShopId err:%v, ChargeId=%d", err, ChargeId)
		return 0
	}
	for k, v := range data {
		if gamedata.GetIntValue(v, "ChargeId") == ChargeId {
			return GoUtil.Int(k)
		}
	}
	return 0
}

func GetWeeklyInfo(Pos int) (int, int) {
	data, err := gamedata.GetDataByKey(CFG_CHARGE_CONST, "weekly_chess_shop")
	if err != nil {
		log.Debug("GetWeeklyInfo err:%v, Pos=%d", err, Pos)
		return 0, 0
	}
	valueData, ok := data["Value"]
	if !ok {
		log.Debug("GetWeeklyInfo: Value field not found")
		return 0, 0
	}
	r, ok := valueData.([]interface{})
	if !ok {
		log.Debug("GetWeeklyInfo: Value is not []interface{}")
		return 0, 0
	}
	for _, v := range r {
		v1, ok := v.(map[string]interface{})
		if !ok {
			continue
		}
		Id := GoUtil.Int(v1["Id"])
		if Id == Pos {
			return GoUtil.Int(v1["Discount"]), GoUtil.Int(v1["Limit"])
		}
	}
	return 0, 0
}

func GetWeeklyInfoAll() map[int]gamedata.WeeklyDiscountInfo {
	data, err := gamedata.GetDataByKey(CFG_CHARGE_CONST, "weekly_chess_shop")
	if err != nil {
		log.Debug("GetWeeklyInfoAll err:%v", err)
		return nil
	}
	valueData, ok := data["Value"]
	if !ok {
		log.Debug("GetWeeklyInfoAll: Value field not found")
		return nil
	}
	r, ok := valueData.([]interface{})
	if !ok {
		log.Debug("GetWeeklyInfoAll: Value is not []interface{}")
		return nil
	}
	res := make(map[int]gamedata.WeeklyDiscountInfo, len(r))
	for _, v := range r {
		v1, ok := v.(map[string]interface{})
		if !ok {
			continue
		}
		Id := GoUtil.Int(v1["Id"])
		res[Id] = gamedata.WeeklyDiscountInfo{
			Id:          GoUtil.Int(v1["Id"]),
			Discount:    GoUtil.Int(v1["Discount"]),
			WeeklyLimit: GoUtil.Int(v1["Limit"]),
		}
	}
	return res
}

func GetEnergyShopReward(ChargeId int, First bool) []*item.Item {
	data, err := gamedata.GetData(CFG_ENERGY_SHOP)
	if err != nil {
		log.Debug("GetEnergyShopReward err:%v, ChargeId=%d", err, ChargeId)
		return nil
	}
	for _, v := range data {
		if gamedata.GetIntValue(v, "ChargeId") == ChargeId {
			Energy := gamedata.GetIntValue(v, "Energy")
			if !First {
				Energy += gamedata.GetIntValue(v, "FirstCharge")
			}
			return []*item.Item{item.NewItem(item.ITEM_ENERGY_ID, Energy)}
		}
	}
	return nil
}

func GetSpecialShopReward(ChargeId int) []*item.Item {
	data, err := gamedata.GetData(CFG_SEPCIAL_SHOP)
	if err != nil {
		log.Debug("GetSpecialShopReward err:%v, ChargeId=%d", err, ChargeId)
		return nil
	}
	for _, v := range data {
		if gamedata.GetIntValue(v, "ChargeId") == ChargeId {
			return item.ParseItem(gamedata.GetValue(v, "Items"))
		}
	}
	return nil
}

func GetSpecialShopType(ChargeId int) int {
	data, err := gamedata.GetData(CFG_SEPCIAL_SHOP)
	if err != nil {
		log.Debug("GetSpecialShopType err:%v, ChargeId=%d", err, ChargeId)
		return 0
	}
	for _, v := range data {
		if gamedata.GetIntValue(v, "ChargeId") == ChargeId {
			return gamedata.GetIntValue(v, "Type")
		}
	}
	return 0
}

func GetFreeShopReward(ChargeId int) []*item.Item {
	data, err := gamedata.GetDataByIntKey(CFG_FREE_SHOP, ChargeId)
	if err != nil {
		log.Debug("GetFreeShopReward err:%v, ChargeId=%d", err, ChargeId)
		return nil
	}
	Item := gamedata.GetValue(data, "Items")
	return item.ParseItem(Item)
}

func GetSpecialShopGrade(Money float64, Type int) int {
	type grade struct {
		id    int
		money float64
	}
	data, err := gamedata.GetData(CFG_SEPCIAL_SHOP)
	if err != nil {
		log.Debug("GetSpecialShopGrade err:%v, Money=%.2f, Type=%d", err, Money, Type)
		return 0
	}
	l := make([]grade, 0, len(data))
	for _, v := range data {
		if gamedata.GetIntValue(v, "Type") != Type {
			continue
		}
		l = append(l, grade{
			id:    gamedata.GetIntValue(v, "Grade"),
			money: GetMoneyCharge(gamedata.GetIntValue(v, "ChargeId")),
		})
	}
	sort.Slice(l, func(i, j int) bool {
		return l[i].money > l[j].money
	})

	if len(l) == 0 {
		return 0
	}
	maxMoney := 0.0
	for _, v := range l {
		if Money >= v.money {
			maxMoney = max(maxMoney, v.money)
		}
	}
	for _, v := range l {
		if v.money == maxMoney {
			return v.id
		}
	}
	return l[0].id
}

func GetUnlockShopLv() int {
	data, err := gamedata.GetDataByKey(CFG_CHARGE_CONST, "shop_unlock_lv")
	if err != nil {
		log.Debug("GetUnlockShopLv err:%v", err)
		return 0
	}
	return gamedata.GetIntValue(data, "Value")
}

func GetSpecialShopCount() int {
	data, err := gamedata.GetDataByKey(CFG_CHARGE_CONST, "special_shop_count")
	if err != nil {
		log.Debug("GetSpecialShopCount err:%v", err)
		return 0
	}
	return gamedata.GetIntValue(data, "Value")
}

func GetAdChargeId() int {
	data, err := gamedata.GetDataByKey(CFG_CHARGE_CONST, "ad_charge_id")
	if err != nil {
		log.Debug("GetAdChargeId err:%v", err)
		return 0
	}
	return gamedata.GetIntValue(data, "Value")
}

func GetPiggyDuration() int {
	data, err := gamedata.GetDataByKey(CFG_CHARGE_CONST, "pig_duration")
	if err != nil {
		log.Debug("GetPiggyDuration err:%v", err)
		return 0
	}
	return gamedata.GetIntValue(data, "Value")
}

func GetPiggyMaxDia() int {
	data, err := gamedata.GetDataByKey(CFG_CHARGE_CONST, "pig_max_diamond")
	if err != nil {
		log.Debug("GetPiggyMaxDia err:%v", err)
		return 0
	}
	return gamedata.GetIntValue(data, "Value")
}

func GetPiggyRandDia() (int, int) {
	data, err := gamedata.GetDataByKey(CFG_CHARGE_CONST, "pig_diamond_rand")
	if err != nil {
		log.Debug("GetPiggyRandDia err:%v", err)
		return 0, 0
	}
	str := gamedata.GetStringValue(data, "Value")
	strArr := strings.Split(str, ",")
	if len(strArr) != 2 {
		return 0, 0
	}
	return GoUtil.Int(strArr[0]), GoUtil.Int(strArr[1])
}

func GetPiggyBankChargeId() int {
	data, err := gamedata.GetDataByKey(CFG_CHARGE_CONST, "pig_charge_id")
	if err != nil {
		log.Debug("GetPiggyBankChargeId err:%v", err)
		return 0
	}
	return gamedata.GetIntValue(data, "Value")
}

func GetGiftReward(ChargeId int) []*item.Item {
	data, err := gamedata.GetData(CFG_CHARGE_GIFT)
	if err != nil {
		log.Debug("GetGiftReward err:%v, ChargeId=%d", err, ChargeId)
		return nil
	}
	for _, v := range data {
		if gamedata.GetIntValue(v, "ChargeId") == ChargeId {
			return item.ParseItem(gamedata.GetValue(v, "Items"))
		}
	}
	return nil
}

func GetGiftLimit(ChargeId int) int {
	data, err := gamedata.GetData(CFG_CHARGE_GIFT)
	if err != nil {
		log.Debug("GetGiftLimit err:%v, ChargeId=%d", err, ChargeId)
		return 0
	}
	for _, v := range data {
		if gamedata.GetIntValue(v, "ChargeId") == ChargeId {
			return gamedata.GetIntValue(v, "Count")
		}
	}
	return 0
}
func GetGiftId(ChargeId int) int {
	data, err := gamedata.GetData(CFG_CHARGE_GIFT)
	if err != nil {
		log.Debug("GetGiftId err:%v, ChargeId=%d", err, ChargeId)
		return 0
	}
	for k, v := range data {
		if gamedata.GetIntValue(v, "ChargeId") == ChargeId {
			return GoUtil.Int(k)
		}
	}
	return 0
}

func GetChargeInfo(ChargeId int) (float64, string) {
	data, err := gamedata.GetDataByIntKey(CFG_CHARGE, ChargeId)
	if err != nil {
		log.Debug("GetChargeInfo err:%v, ChargeId=%d", err, ChargeId)
		return 0, ""
	}
	return gamedata.GetFloatValue(data, "Money"), gamedata.GetStringValue(data, "Unit")
}

func GetProduceName(ChargeId int) string {
	data, err := gamedata.GetDataByIntKey(CFG_CHARGE, ChargeId)
	if err != nil {
		log.Debug("GetProduceName err:%v, ChargeId=%d", err, ChargeId)
		return ""
	}
	return gamedata.GetStringValue(data, "Remark")
}

func GetWishCount(ItemId int) int {
	data, err := gamedata.GetDataByIntKey(CFG_CHARGE_WISH, ItemId)
	if err != nil {
		log.Debug("GetWishCount err:%v, ItemId=%d", err, ItemId)
		return 0
	}
	return gamedata.GetIntValue(data, "Wish")
}

func GetPetCoinShopReward(ChargeId int) []*item.Item {
	data, err := gamedata.GetData(CFG_CHARGE_PETCOIN)
	if err != nil {
		log.Debug("GetPetCoinShopReward err:%v, ChargeId=%d", err, ChargeId)
		return nil
	}
	for _, v := range data {
		if gamedata.GetIntValue(v, "ChargeId") == ChargeId {
			return gamedata.GetItemList(v, "Items")
		}
	}
	return nil
}

func GetWeeklyDiscountStartEnd() (int64, int64) {
	data, err := gamedata.GetDataByKey(CFG_CHARGE_CONST, "weekly_discount_time")
	if err != nil {
		log.Debug("GetWeeklyDiscountStartEnd err:%v", err)
		return 0, 0
	}
	str := gamedata.GetStringValue(data, "Value")
	strArr := strings.Split(str, "|")
	if len(strArr) != 2 {
		return 0, 0
	}
	return GoUtil.ParseTime(strArr[0]), GoUtil.ParseTime(strArr[1])
}
