package limitedTimeEventCfg

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

const (
	CFG_LIMITED_TIME_EVENT               = "LimitedTimeEvent"
	CFG_LIMITED_TIME_EVENT_METEOR        = "LimitedTimeEventMeteor"
	CFG_LIMITED_TIME_EVENT_CHEST         = "LimitedTimeEventChest"
	CFG_LIMITED_TIME_EVENT_ORDER         = "LimitedTimeEventOrder"
	CFG_LIMITED_TIME_EVENT_SENCE         = "LimitedTimeEventSence"
	CFG_LIMITED_TIME_EVENT_SENCE_JACKPOT = "LimitedTimeEventSenceJackpot"
	CFG_LIMITED_TIME_EVENT_FAST          = "LimitedTimeEventFast"
	CFG_LIMITED_TIME_EVENT_JACKPOT       = "LimitedTimeEventJackpot"
	CFG_LIMITED_TIME_EVENT_CHEST_JACKPOT = "LimitedTimeEventChestJackpot"
	CFG_LIMITED_TIME_EVENT_CONST         = "LimitedTimeEventConst"
	CFG_LIMITED_TIME_EVENT_BONUS         = "LimitedTimeEventBonus"
	CFG_LIMITED_TIME_EVENT_MONEY         = "LimitedTimeEventMoney"
	CFG_LIMITED_TIME_EVENT_LUCKY         = "LimitedTimeEventLucky"
	CFG_LIMITED_TIME_EVENT_CAT_TRICK     = "LimitedTimeEventCatTrick"
	CFG_LIMTTED_TIME_EVENT_DECORATE_OFF  = "LimitedTimeEventDecorateOff"
)

func init() {
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT)
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT_METEOR)
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT_CHEST)
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT_ORDER)
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT_SENCE)
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT_SENCE_JACKPOT)
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT_FAST)
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT_JACKPOT)
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT_CONST)
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT_BONUS)
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT_CHEST_JACKPOT)
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT_MONEY)
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT_LUCKY)
	gamedata.InitCfg(CFG_LIMITED_TIME_EVENT_CAT_TRICK)
	gamedata.InitCfg(CFG_LIMTTED_TIME_EVENT_DECORATE_OFF)
}

// 获取限时事件触发列表
func GetLimitedTimeEventCfg() []*gamedata.LimitedTimeEventData {
	return nil
}

func GetEventName(Id int) string {
	data, err := gamedata.GetDataByIntKey(CFG_LIMITED_TIME_EVENT, Id)
	if err != nil {
		log.Debug("GetEventName err:%v, Id=%d", err, Id)
		return ""
	}
	return gamedata.GetStringValue(data, "Name")
}

// 获取流星雨加成
func GetMeteorAdd(ChessLv int) int {
	data, err := gamedata.GetDataByIntKey(CFG_LIMITED_TIME_EVENT_METEOR, ChessLv)
	if err != nil {
		log.Debug("GetMeteorAdd err:%v, ChessLv=%d", err, ChessLv)
		return 0
	}
	return gamedata.GetIntValue(data, "Add")
}

// 获取宝箱雨奖励
func GetChestReward(Star int) []*item.Item {
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_CHEST)
	if err != nil {
		log.Debug("GetChestReward err:%v, Star=%d", err, Star)
		return nil
	}

	for _, v := range data {
		Min := gamedata.GetIntValue(v, "Min")
		Max := gamedata.GetIntValue(v, "Max")
		if Star >= Min && Star <= Max {
			return gamedata.GetItemList(v, "Items")
		}
	}
	return nil

}

// 获取超级订单奖励
func GetSuperOrderReward(energy int) []*item.Item {
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_ORDER)
	if err != nil {
		log.Debug("GetSuperOrderReward err:%v, energy=%d", err, energy)
		return nil
	}
	star := energy
	for _, v := range data {
		Min := gamedata.GetIntValue(v, "Min")
		Max := gamedata.GetIntValue(v, "Max")
		if star >= Min && star <= Max {
			return gamedata.GetItemList(v, "Items")
		}
	}
	return nil
}

// 获取场景冲刺奖励
func GetSceneDashReward(Sence, Progress int) (int, []*item.Item) {
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_SENCE)
	if err != nil {
		log.Debug("GetSceneDashReward err:%v, Sence=%d, Progress=%d", err, Sence, Progress)
		return 0, nil
	}
	for k, v := range data {
		if Sence == gamedata.GetIntValue(v, "Sence") && Progress == gamedata.GetIntValue(v, "Progress") {
			return GoUtil.Int(k), gamedata.GetItemList(v, "Items")
		}
	}
	return 0, nil
}

// 获取场景冲刺奖池
func GetSenceJackpotProb() map[int]int {
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_SENCE_JACKPOT)
	if err != nil {
		log.Debug("GetSenceJackpotProb err:%v", err)
		return nil
	}
	r := make(map[int]int, len(data))
	for k, v := range data {
		Id := GoUtil.Int(k)
		r[Id] = gamedata.GetIntValue(v, "Prob")
	}
	return r
}

// 获取场景冲刺奖励
func GetSenceJackpotReward(Id int) []*item.Item {
	data, err := gamedata.GetDataByIntKey(CFG_LIMITED_TIME_EVENT_SENCE_JACKPOT, Id)
	if err != nil {
		log.Debug("GetSenceJackpotReward err:%v, Id=%d", err, Id)
		return nil
	}
	return gamedata.GetItemList(data, "Items")
}

// 获取连击快手奖励
func GetFastProduceReward(Energy int) []*item.Item {
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_FAST)
	if err != nil {
		log.Debug("GetFastProduceReward err:%v, Energy=%d", err, Energy)
		return nil
	}
	if len(data) == 0 {
		return nil
	}
	// Convert map to slice for sorting
	type sortData struct {
		Id     string
		Energy float64
	}
	sortedList := make([]sortData, 0, len(data))
	energy := float64(Energy) / 10.0
	for k, v := range data {
		dataEnergy := gamedata.GetFloatValue(v, "EnergyValue")
		sortedList = append(sortedList, sortData{k, math.Abs(energy - dataEnergy)})
	}
	// Sort by Energy in ascending order
	sort.Slice(sortedList, func(i, j int) bool {
		return sortedList[i].Energy < sortedList[j].Energy
	})

	return gamedata.GetItemList(data[sortedList[0].Id], "Items")
}

// 获取连击快手最大次数
func GetFastProduceMaxTimes() int {
	Max := 0
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_FAST)
	if err != nil {
		log.Debug("GetFastProduceMaxTimes err:%v", err)
		return 0
	}
	for _, v := range data {
		Max = max(gamedata.GetIntValue(v, "Times"), Max)
	}
	return Max
}

// 获取进度最大值
func GetProgressMax(Lv, Num int) int {
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_BONUS)
	if err != nil {
		log.Debug("GetProgressMax err:%v, Lv=%d, Num=%d", err, Lv, Num)
		return 0
	}
	for _, v := range data {
		Min := gamedata.GetIntValue(v, "Min")
		Max := gamedata.GetIntValue(v, "Max")
		if Lv >= Min && Lv <= Max {
			OrderNumStr := gamedata.GetStringValue(v, "OrderNum")
			OrderNum := GoUtil.SplitInt(OrderNumStr, ",")
			if Num >= len(OrderNum) {
				return OrderNum[len(OrderNum)-1]
			} else {
				return OrderNum[Num]
			}
		}
	}
	return 0
}

func GetBonusLv(Lv int) int {
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_BONUS)
	if err != nil {
		log.Debug("GetBonusLv err:%v, Lv=%d", err, Lv)
		return 0
	}
	for k, v := range data {
		Min := gamedata.GetIntValue(v, "Min")
		Max := gamedata.GetIntValue(v, "Max")
		if Lv >= Min && Lv <= Max {
			return GoUtil.Int(k)
		}
	}
	return 0
}

// 获取进度奖励随机
func GetProgressRewardRand(Lv int) map[int]int {
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_JACKPOT)
	if err != nil {
		log.Debug("GetProgressRewardRand err:%v, Lv=%d", err, Lv)
		return nil
	}
	r := make(map[int]int, len(data))
	for k, v := range data {
		if Lv >= gamedata.GetIntValue(v, "BonusLv") {
			Id := GoUtil.Int(k)
			r[Id] = gamedata.GetIntValue(v, "Prob")
		}
	}
	return r
}

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

// 获取进度选择数量
func GetProgressSelectNum(Lv int) int {
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_BONUS)
	if err != nil {
		log.Debug("GetProgressSelectNum err:%v, Lv=%d", err, Lv)
		return 0
	}
	for _, v := range data {
		Min := gamedata.GetIntValue(v, "Min")
		Max := gamedata.GetIntValue(v, "Max")
		if Lv >= Min && Lv <= Max {
			return gamedata.GetIntValue(v, "Option")
		}
	}
	return 0
}

// 获取进度奖励
func GetProgressReward(RewardId int) []*item.Item {
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_JACKPOT)
	if err != nil {
		log.Debug("GetProgressReward err:%v, RewardId=%d", err, RewardId)
		return nil
	}
	for k, v := range data {
		Id := GoUtil.Int(k)
		if Id == RewardId {
			return gamedata.GetItemList(v, "Items")
		}
	}
	return nil
}

// 获取进度奖励类型
func GetProgressRewardType(RewardId int) int {
	data, err := gamedata.GetDataByIntKey(CFG_LIMITED_TIME_EVENT_JACKPOT, RewardId)
	if err != nil {
		log.Debug("GetProgressRewardType err:%v, RewardId=%d", err, RewardId)
		return 0
	}
	return gamedata.GetIntValue(data, "Type")
}

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

func GetCatSaleCD() int64 {
	data, err := gamedata.GetDataByKey(CFG_LIMITED_TIME_EVENT_CONST, "Event_Cooldown_7days")
	if err != nil {
		log.Debug("GetCatSaleCD err:%v", err)
		return 0
	}
	return int64(gamedata.GetIntValue(data, "Value"))
}

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

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

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

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

func GetThiefProb() int {
	data, err := gamedata.GetDataByKey(CFG_LIMITED_TIME_EVENT_CONST, "Thief_Prob")
	if err != nil {
		log.Debug("GetThiefProb err:%v", err)
		return 0
	}
	value := gamedata.GetStringValue(data, "Value")
	a1 := strings.Split(value, "|")
	prob := make(map[int]int, len(a1))
	for _, v := range a1 {
		a2 := strings.Split(v, ":")
		prob[GoUtil.Int(a2[0])] = GoUtil.Int(a2[1])
	}
	return GoUtil.RandMap(prob)
}

// 招财猫

func GetMoneyCat(Id int) (float64, int) {
	data, err := gamedata.GetDataByIntKey(CFG_LIMITED_TIME_EVENT_MONEY, Id)
	if err != nil {
		log.Debug("GetMoneyCat err:%v, Id=%d", err, Id)
		return 0.0, 0
	}
	return gamedata.GetFloatValue(data, "Mul"), gamedata.GetIntValue(data, "Cd")
}

func GetMoneyCatMax() int {
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_MONEY)
	if err != nil {
		log.Debug("GetMoneyCatMax err:%v", err)
		return 0
	}
	return len(data)
}

func GetLuckyCatMaxEarning(Remain int) int {
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_LUCKY)
	if err != nil {
		log.Debug("GetLuckyCatMaxEarning err:%v, Remain=%d", err, Remain)
		return 0
	}
	type d struct {
		t int
		e int
	}
	l := make([]d, 0, len(data))
	for k, v := range data {
		t := GoUtil.Int(k)
		e := gamedata.GetIntValue(v, "Earn")
		l = append(l, d{t, e})
	}
	sort.Slice(l, func(i, j int) bool {
		return l[i].t < l[j].t
	})
	for _, v := range l {
		if Remain <= v.t {
			return v.e
		}
	}
	return 0
}

func GetCatTrickType(Duartion int) int {
	data, err := gamedata.GetData(CFG_LIMITED_TIME_EVENT_CAT_TRICK)
	if err != nil {
		log.Debug("GetCatTrickType err:%v, Duartion=%d", err, Duartion)
		return 1
	}
	for k, v := range data {
		D := gamedata.GetIntValue(v, "Duration")
		if Duartion == D {
			return GoUtil.Int(k)
		}
	}
	return gamedata.GetIntValue(data, "Type")
}

func GetCatTrickDiamond(Type int) (int, int) {
	data, err := gamedata.GetDataByIntKey(CFG_LIMITED_TIME_EVENT_CAT_TRICK, Type)
	if err != nil {
		log.Debug("GetCatTrickDiamond err:%v, Type=%d", err, Type)
		return 0, 0
	}
	return gamedata.GetIntValue(data, "Diamond"), gamedata.GetIntValue(data, "Energy")
}

func GetDecorateOffDiscount(AreaId, StepId int) int {
	data, err := gamedata.GetData(CFG_LIMTTED_TIME_EVENT_DECORATE_OFF)
	if err != nil {
		log.Debug("GetDecorateOffDiscount err:%v, AreaId=%d, StepId=%d", err, AreaId, StepId)
		return 100
	}
	for _, v := range data {
		StartAreaId := gamedata.GetIntValue(v, "StartArea")
		EndAreaId := gamedata.GetIntValue(v, "EndArea")
		StartStepId := gamedata.GetIntValue(v, "StartStep")
		EndStepId := gamedata.GetIntValue(v, "EndStep")
		if AreaId >= StartAreaId && AreaId <= EndAreaId && StepId >= StartStepId && StepId <= EndStepId {
			return gamedata.GetIntValue(v, "Off")
		}
	}
	return 100
}
