package mergeDataCfg

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

const (
	CFG_NAME       = "MergeData"
	CONST_NAME     = "MergeDataConst"
	CFG_MERGE_EMIT = "MergeDataEmit"

	// 棋子类型
	CHESS_PRODUCT_MAIN_TYPE      = 1 // 主产物
	CHESS_PRODUCT_SECONDARY_TYPE = 2 // 次产物
	CHESS_PRODUCT_SUB_TYPE       = 3 // 子发射器产物
)

func init() {
	gamedata.InitCfg(CFG_NAME)
	gamedata.InitCfg(CONST_NAME)
	gamedata.InitCfg(CFG_MERGE_EMIT)
}

func GetEmitTypeByColor(Color string) string {
	data, err := gamedata.GetData(CFG_MERGE_EMIT)
	if err != nil {
		return ""
	}
	for k, v := range data {
		ColorList := strings.Split(gamedata.GetStringValue(v, "Order_Type"), ",")
		if GoUtil.InStringArray(Color, ColorList) {
			return k
		}
	}
	return ""
}

func GetEmitProduce(EmitType string) []string {
	data, err := gamedata.GetDataByKey(CFG_MERGE_EMIT, EmitType)
	if err != nil {
		log.Debug("GetEmitProduce GetOne EmitType:%s not found", EmitType)
		return []string{}
	}
	return strings.Split(gamedata.GetStringValue(data, "Product_Type"), ",")
}

func GetEmitOrderProduce(EmitType string) []string {
	data, err := gamedata.GetDataByKey(CFG_MERGE_EMIT, EmitType)
	if err != nil {
		log.Debug("GetEmitProduce GetOne EmitType:%s not found", EmitType)
		return []string{}
	}
	return strings.Split(gamedata.GetStringValue(data, "Order_Type"), ",")
}

// 获取单个数据
func GetOne(Id int) (*gamedata.MergeDataRecord, error) {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, Id)
	if err != nil {
		log.Debug("MergeDataCfg GetOne Id:%v not found", Id)
		return &gamedata.MergeDataRecord{}, errors.New("not found")
	}
	return &gamedata.MergeDataRecord{
		Id:           gamedata.GetIntValue(data, "Id"),
		Lv:           gamedata.GetIntValue(data, "Lv"),
		MaxLv:        gamedata.GetIntValue(data, "MaxLv"),
		SellType:     gamedata.GetStringValue(data, "SellType"),
		SellNum:      gamedata.GetIntValue(data, "SellNum"),
		SellDiamond:  gamedata.GetIntValue(data, "SellDiamond"),
		Color:        gamedata.GetStringValue(data, "Color"),
		Star:         gamedata.GetIntValue(data, "Star"),
		Type:         gamedata.GetStringValue(data, "Type"),
		Emit_Product: gamedata.GetStringValue(data, "Emit_Product"),
		CoolTime:     gamedata.GetIntValue(data, "CoolTime"),
		Emit_Type:    gamedata.GetStringValue(data, "Emit_Type"),
	}, nil
}

// 根据id获取棋子获得的星星
func GetStarById(Id int) int {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, Id)
	if err != nil {
		log.Debug("MergeDataCfg GetOne Id:%v not found", Id)
		return 0
	}
	return gamedata.GetIntValue(data, "Star")
}

func GetNameById(Id int) string {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, Id)
	if err != nil {
		log.Debug("MergeDataCfg GetOne Id:%v not found", Id)
		return ""
	}
	return gamedata.GetStringValue(data, "Title")
}

// 根据等级和颜色获取棋子id
func GetChessIdByLvAndColor(Lv int, Color string) int {
	if Lv == 0 || Color == "" {
		return 0
	}
	data, err := gamedata.GetData(CFG_NAME)
	if err != nil {
		// log.Debug("MergeDataCfg GetChessIdByLvAndColor lv:%v Color:%v not found", Lv, Color)
		return 0
	}
	for k, v := range data {
		lv := gamedata.GetIntValue(v, "Lv")
		color := gamedata.GetStringValue(v, "Color")
		if Lv == lv && color == Color {
			Id, _ := strconv.Atoi(k)
			return Id
		}
	}
	// log.Debug("MergeDataCfg GetChessIdByLvAndColor lv:%v Color:%v not found", Lv, Color)
	return 0
}

// 根据Id获取棋子等级
func GetLvById(Id int) int {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, Id)
	if err != nil {
		//log.Debug("GetLvById GetOne Id:%v not found", Id)
		return 0
	}
	return gamedata.GetIntValue(data, "Lv")
}

// 根据Id获取棋子最大等级
func GetMaxLvById(Id int) int {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, Id)
	if err != nil {
		// log.Debug("GetMaxLvById GetOne Id:%v not found", Id)
		return 0
	}
	return gamedata.GetIntValue(data, "MaxLv")
}

// 根据Id获取棋子最大等级
func GetMaxLvByColor(Color string) int {
	ChessId := GetChessIdByLvAndColor(1, Color)
	data, err := gamedata.GetDataByIntKey(CFG_NAME, ChessId)
	if err != nil {
		return 0
	}
	return gamedata.GetIntValue(data, "MaxLv")
}

// 根据Id获取发射器最小等级
func GetEmitMinLvById(Id string) int {
	data, err := gamedata.GetDataByKey(CFG_MERGE_EMIT, Id)
	if err != nil {
		// log.Debug("GetEmitMinLvById GetOne Id:%v not found", Id)
		return 0
	}
	return gamedata.GetIntValue(data, "Emit_Min_Lv")
}

// 根据Id获取发射器修正系数
func GetEmitRatio(Id string) float64 {
	data, err := gamedata.GetDataByKey(CFG_MERGE_EMIT, Id)
	if err != nil {
		// log.Debug("GetEmitRatio GetOne Id:%v not found", Id)
		return 0
	}
	return gamedata.GetFloatValue(data, "Ratio")
}

func GetEmitRetire(Id string) int {
	data, err := gamedata.GetDataByKey(CFG_MERGE_EMIT, Id)
	if err != nil {
		log.Debug("GetEmitRetire GetOne Id:%v not found", Id)
		return 0
	}
	return gamedata.GetIntValue(data, "Retire")
}

func GetEmitProductNumByColor(Id string) int {
	data, err := gamedata.GetData(CFG_MERGE_EMIT)
	if err != nil {
		log.Debug("GetEmitProductNumByColor GetOne Id:%v not found", Id)
		return 0
	}
	for _, v := range data {
		ColorList := strings.Split(gamedata.GetStringValue(v, "Product_Type"), ",")
		if GoUtil.InStringArray(Id, ColorList) {
			return len(strings.Split(gamedata.GetStringValue(v, "Product_Type"), ","))
		}
	}
	return 0
}

// 根据Id获取棋子类型
func GetTypeById(Id int) string {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, Id)
	if err != nil {
		log.Debug("GetTypeById GetOne Id:%v not found", Id)
		return ""
	}
	return gamedata.GetStringValue(data, "Type")
}

// 根据Id获取棋子类型
func GetColorById(Id int) string {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, Id)
	if err != nil {
		log.Debug("GetColorById GetOne Id:%v not found", Id)
		return ""
	}
	return gamedata.GetStringValue(data, "Color")
}

// 根据Id获取棋子类型
func GetSellNumById(Id int) int {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, Id)
	if err != nil {
		log.Debug("GetSellNumById GetOne Id:%v not found", Id)
		return 0
	}
	return gamedata.GetIntValue(data, "SellNum")
}

// 根据Id获取发射器产出类型
func GetEmitProduceType(Id int) []string {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, Id)
	if err != nil {
		log.Debug("GetEmitProduceType GetOne Id:%v not found", Id)
		return []string{}
	}

	return strings.Split(gamedata.GetStringValue(data, "Emit_Product"), ",")
}

// 根据Id获取发射器产出类型
func GetEmitProduceChessType(Id int) []string {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, Id)
	if err != nil {
		//log.Debug("GetEmitProduceChessType GetOne Id:%v not found", Id)
		return []string{}
	}

	value := gamedata.GetStringValue(data, "Product_Type")
	if value == "" {
		return []string{}
	}
	return strings.Split(value, ",")
}

// 根据Id获取发射器Id
func GetEmitId(Id int) string {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, Id)
	if err != nil {
		// log.Debug("GetEmitId GetOne Id:%v not found", Id)
		return ""
	}

	return gamedata.GetStringValue(data, "Emit_ID")
}

func GetAllId() []int {
	data, err := gamedata.GetData(CFG_NAME)
	if err != nil {
		return []int{}
	}
	key := make([]int, 0, len(data))
	for k := range data {
		key = append(key, GoUtil.Int(k))
	}
	return key
}

func GetEmitType(Id int) string {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, Id)
	if err != nil {
		log.Debug("GetEmitType GetOne Id:%v not found", Id)
		return ""
	}

	return gamedata.GetStringValue(data, "Emit_Type")
}

func GetEmitN(EmitSeries string) int {
	data, err := gamedata.GetDataByKey(CFG_MERGE_EMIT, EmitSeries)
	if err != nil {
		log.Debug("GetEmitN GetOne EmitSeries:%v not found", EmitSeries)
		return 0
	}
	return gamedata.GetIntValue(data, "N")
}

// 获取常量
func GetConst(Key string) string {
	data, err := gamedata.GetDataByKey(CONST_NAME, Key)
	if err != nil {
		log.Debug("GetConst GetOne Id:%s not found", Key)
		return ""
	}

	return gamedata.GetStringValue(data, "Value")
}

// 获取常量
func GetConstInt(Key string) int {
	data, err := gamedata.GetDataByKey(CONST_NAME, Key)
	if err != nil {
		log.Debug("GetConst GetOne Id:%s not found", Key)
		return 0
	}
	return gamedata.GetIntValue(data, "Value")
}

func GetExtraEmitId() map[string]struct{} {
	Value := GetConst("EmitId_Extra_Order")
	arr := strings.Split(Value, ",")
	var r = make(map[string]struct{})
	for _, v := range arr {
		r[v] = struct{}{}
	}
	return r
}

func GetChessBagMaxGrid() int {
	return GetConstInt("chess_bag_max")
}

func GetChessBagBugNum() int {
	return GetConstInt("chess_bag_buy")
}

func GetChessBagInitNum() int {
	return GetConstInt("chess_bag_init")
}

func GetSourceChestItem() []*item.Item {
	data, err := gamedata.GetDataByKey(CONST_NAME, "source_chest_reward")
	if err != nil {
		log.Debug("GetSourceChestItem GetOne not found")
		return nil
	}

	Str := gamedata.GetStringValue(data, "Value")
	A1 := strings.Split(Str, "|")
	var r []*item.Item
	if len(A1) < 2 {
		return r
	}
	A2 := strings.Split(A1[0], "/")
	A3 := GoUtil.StringToInt(A2)
	A4 := GoUtil.RandSlice(A3)
	r = append(r, item.NewItem(item.ITEM_DIAMOND_ID, A4))

	B2 := strings.Split(A1[1], "/")
	B3 := GoUtil.StringToInt(B2)
	B4 := GoUtil.RandSlice(B3)
	r = append(r, item.NewItem(item.ITEM_ENERGY_ID, B4))
	return r
}

func GetHighSourceChestItem() []*item.Item {
	data, err := gamedata.GetDataByKey(CONST_NAME, "high_source_chest_reward")
	if err != nil {
		log.Debug("GetHighSourceChestItem GetOne not found")
		return nil
	}
	Str := gamedata.GetStringValue(data, "Value")
	A1 := strings.Split(Str, "|")
	var r []*item.Item
	if len(A1) < 2 {
		return r
	}
	A2 := strings.Split(A1[0], "/")
	A3 := GoUtil.StringToInt(A2)
	A4 := GoUtil.RandSlice(A3)
	r = append(r, item.NewItem(item.ITEM_DIAMOND_ID, A4))

	B2 := strings.Split(A1[1], "/")
	B3 := GoUtil.StringToInt(B2)
	B4 := GoUtil.RandSlice(B3)
	r = append(r, item.NewItem(item.ITEM_ENERGY_ID, B4))
	return r
}

func GetRetireReward() []*item.Item {
	data, err := gamedata.GetDataByKey(CONST_NAME, "retire_reward")
	if err != nil {
		log.Debug("GetRetireReward GetOne not found")
		return nil
	}
	return gamedata.GetItemList(data, "Value")
}

func DynamicLevRev(Lv int, EmitId int, Color string) int {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, EmitId)
	if err != nil {
		// log.Debug("DynamicLev GetOne EmitId:%v not found", EmitId)
		return Lv
	}
	DynamicLv := gamedata.GetStringValue(data, "Dynamic")
	if DynamicLv == "" {
		return Lv
	}
	Arr := strings.Split(DynamicLv, ",")
	for _, v := range Arr {
		Arr2 := strings.Split(v, "=")
		if len(Arr2) != 2 {
			continue
		}
		if Color == Arr2[0] {
			NewLv, _ := strconv.Atoi(Arr2[1])
			return Lv + NewLv
		}
	}
	return Lv
}
func DynamicLev(Lv int, EmitId int, Color string) int {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, EmitId)
	if err != nil {
		//log.Debug("DynamicLev GetOne EmitId:%v not found", EmitId)
		return Lv
	}
	DynamicLv := gamedata.GetStringValue(data, "Dynamic")
	if DynamicLv == "" {
		return Lv
	}
	Arr := strings.Split(DynamicLv, ",")
	for _, v := range Arr {
		Arr2 := strings.Split(v, "=")
		if len(Arr2) != 2 {
			continue
		}
		if Color == Arr2[0] {
			NewLv, _ := strconv.Atoi(Arr2[1])
			return Lv - NewLv
		}
	}
	return Lv
}
func DynamicLev2(Lv int, EmitId int, Color1 string, Color2 string) int {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, EmitId)
	if err != nil {
		//log.Debug("DynamicLev GetOne EmitId:%v not found", EmitId)
		return Lv
	}
	DynamicLv := gamedata.GetStringValue(data, "Dynamic")
	if DynamicLv == "" {
		return Lv
	}
	Arr := strings.Split(DynamicLv, ",")
	BaseLv := Lv
	for _, v := range Arr {
		Arr2 := strings.Split(v, "=")
		if len(Arr2) != 2 {
			continue
		}
		if Color1 == Arr2[0] {
			NewLv, _ := strconv.Atoi(Arr2[1])
			BaseLv = Lv + NewLv
		}
	}
	for _, v := range Arr {
		Arr2 := strings.Split(v, "=")
		if len(Arr2) != 2 {
			continue
		}
		if Color2 == Arr2[0] {
			NewLv, _ := strconv.Atoi(Arr2[1])
			return BaseLv - NewLv
		}
	}
	return Lv
}

func DynamicAdjust(EmitId int, Color string, EnergyMul int) int {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, EmitId)
	if err != nil {
		//log.Debug("DynamicLev GetOne EmitId:%v not found", EmitId)
		return 0
	}
	DynamicLv := ""
	switch EnergyMul {
	case 0:
		DynamicLv = gamedata.GetStringValue(data, "Dynamic")
	case 1, 2:
		DynamicLv = gamedata.GetStringValue(data, "Dynamic1")
	case 3, 4:
		DynamicLv = gamedata.GetStringValue(data, "Dynamic2")
	default:
		DynamicLv = gamedata.GetStringValue(data, "Dynamic3")
	}

	if DynamicLv == "" {
		return 0
	}
	Arr := strings.Split(DynamicLv, ",")
	for _, v := range Arr {
		Arr2 := strings.Split(v, "=")
		if len(Arr2) != 2 {
			continue
		}
		if Color == Arr2[0] {
			NewLv, _ := strconv.Atoi(Arr2[1])
			return NewLv
		}
	}
	return 0
}

func GetAdjust(EmitId int, Color string, EnergyMul int) int {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, EmitId)
	if err != nil {
		//log.Debug("DynamicLev GetOne EmitId:%v not found", EmitId)
		return 0
	}
	AdjustLv := ""
	switch EnergyMul {
	case 0:
		AdjustLv = gamedata.GetStringValue(data, "Dynamic")
	case 1, 2:
		AdjustLv = gamedata.GetStringValue(data, "Dynamic1")
	case 3, 4:
		AdjustLv = gamedata.GetStringValue(data, "Dynamic2")
	default:
		AdjustLv = gamedata.GetStringValue(data, "Dynamic3")
	}
	if AdjustLv == "" {
		return 0
	}
	Arr := strings.Split(AdjustLv, ",")
	for _, v := range Arr {
		Arr2 := strings.Split(v, "=")
		if len(Arr2) != 2 {
			continue
		}
		if Color == Arr2[0] {
			NewLv, _ := strconv.Atoi(Arr2[1])
			return NewLv
		}
	}
	return 0
}

func GetSellDiamondMul(EmitId int, Color string) int {
	data, err := gamedata.GetDataByIntKey(CFG_NAME, EmitId)
	if err != nil {
		log.Debug("GetSellDiamondMul GetOne EmitId:%v not found", EmitId)
		return 0
	}
	ProductEmit := gamedata.GetStringValue(data, "Emit_Product")
	if ProductEmit == "" {
		return 1
	}
	Arr := strings.Split(ProductEmit, ",")
	if Color == Arr[0] {
		return 1
	}
	if !GoUtil.InStringArray(Color, Arr) {
		return 1
	}
	Emit_List := gamedata.GetStringValue(data, "Emit_List")
	MainProb := getColorProb(Emit_List, Arr[0])
	SubProb := getColorProb(Emit_List, Color)
	return int(MainProb / SubProb)
}

func getColorProb(Emit_List string, Color string) float64 {
	Arr := strings.Split(Emit_List, ",")
	Prob := 0.0
	for _, v := range Arr {
		Arr2 := strings.Split(v, "=")
		A1 := GoUtil.Int(Arr2[0])
		A2, _ := strconv.ParseFloat(Arr2[1], 64)
		A1Color := GetColorById(A1)
		if A1Color != Color {
			continue
		}
		Prob += A2 * float64(A1%10)
	}
	return Prob
}

func GetMergeStar(MergeList []int) int {
	Star := 0
	for _, v := range MergeList {
		Star += GetStarById(v)
	}
	return Star
}

func GetAllChessBySeries(Series string) []int {
	data, err := gamedata.GetData(CFG_NAME)
	ProductList := GetEmitProduce(Series)
	if err != nil {
		return []int{}
	}
	var r []int
	for k, v := range data {
		Type := gamedata.GetStringValue(v, "Type")
		if Type == "Emitter" {
			EmitId := gamedata.GetStringValue(v, "Emit_ID")
			if EmitId == Series {
				r = append(r, GoUtil.Int(k))
			}
		}
		if Type == "Product" {
			Color := gamedata.GetStringValue(v, "Color")
			if GoUtil.InStringArray(Color, ProductList) {
				r = append(r, GoUtil.Int(k))
			}
		}
	}
	return r
}
