package game

import (
	"math"
	"server/GoUtil"
	"server/MergeConst"
	"server/conf"
	champshipCfg "server/conf/champship"
	mergeDataCfg "server/conf/mergeData"
	"server/db"
	"server/game/mod/chess"
	"server/game/mod/item"
	"server/game/mod/order"
	"server/msg"
	"server/pkg/github.com/name5566/leaf/log"
	"sort"
	"time"
)

func TriggerShippingOrder(player *Player, req *msg.ReqShippingOrder) {
	OrderSn := req.OrderSn
	Status := int(req.Status)
	if Status == MergeConst.ORDER_STATUS_CANCEL { // 取消支付
		CancelOrder(player, OrderSn)
		player.PushClientRes(&msg.ResShippingOrder{
			Code: msg.RES_CODE_SUCCESS,
			Msg:  "cancel success",
		})
		return
	}
	OrderData := &db.SqlChargeOrderStruct{}
	var err error
	n := 0
	for {
		n++
		if n > 5 {
			break
		}
		OrderData, err = GoogleVerify(player, OrderSn, req.ProduceId, req.Token)
		if err != nil {
			log.Debug("GoogleVerify parmas OrderSn：%s; ProduceId:%s; Token:%s", OrderSn, req.ProduceId, req.Token)
			log.Debug("GoogleVerify err:%v", err)
			time.Sleep(1 * time.Second)
			continue
		}
		if OrderData.PayStatus != MergeConst.ORDER_STATUS_PAY {
			time.Sleep(1 * time.Second)
			continue
		}
		if OrderData.PayStatus == MergeConst.ORDER_STATUS_PAY {
			break
		}

	}
	if OrderData == nil {
		return
	}
	log.Debug("[order verify success] Uid:%d;OrderSn:%s;PayOrder:%s;", player.M_DwUin, OrderData.OrderId, OrderData.PayChannelOrderId)
	player.lock.Lock()
	defer player.lock.Unlock()
	Charge(player, int(OrderData.ProductId))
	OrderData.PayStatus = MergeConst.ORDER_STATUS_SHIP
	db.UpdatePlayerChargeData(OrderData)
	player.PlayMod.save()
	orderDataMap := map[string]interface{}{
		"AppId":             conf.Server.AppID,
		"ServerId":          conf.Server.ServerID,
		"OrderId":           OrderData.OrderId,
		"PayChannelOrderId": OrderData.PayChannelOrderId,
		"ProductId":         OrderData.ProductId,
		"CreateTime":        OrderData.CreateTime,
		"PayTime":           OrderData.PayTime,
		"Price":             OrderData.Price,
		"PayType":           OrderData.PayType,
	}
	player.Kafka("pay", orderDataMap)
	player.SendClientRes()
}

func TriggerComfortOrder(p *Player) {
	BaseMod := p.PlayMod.getBaseMod()
	Now := GoUtil.Now()
	Lv := BaseMod.GetLevel()

	if Now-BaseMod.GetLogoutTime() < 7*86400 || Lv < 6 {
		return
	}
	OrderMod := p.PlayMod.getOrderMod()
	ChessMod := p.PlayMod.getChessMod()
	ChessList := ChessMod.GetUnlockChessList()
	TriggerType := 1
	for _, Order := range OrderMod.GetOrderList() {
		if GoUtil.IsContain(ChessList, Order.MergeId) {
			continue
		}
		if Order.Diff == order.DIFF_LOW {
			return
		}
		if Order.Diff == order.DIFF_MID {
			TriggerType = 2
		}
	}
	EmitList := ChessMod.GetEmitList()
	EnergyMul := BaseMod.GetEnergyMul()
	if TriggerType == 1 {
		OrderMod.CreateComfortOrder(Lv, EmitList, EnergyMul, order.DIFF_LOW, 2)
		OrderMod.CreateComfortOrder(Lv, EmitList, EnergyMul, order.DIFF_LOW, 3)
		OrderMod.CreateComfortOrder(Lv, EmitList, EnergyMul, order.DIFF_MID, 2)
	} else {
		OrderMod.CreateComfortOrder(Lv, EmitList, EnergyMul, order.DIFF_LOW, 2)
		OrderMod.CreateComfortOrder(Lv, EmitList, EnergyMul, order.DIFF_LOW, 3)
	}
}

func TriggerSeed(player *Player) {
	ChampshipMod := player.PlayMod.getChampshipMod()
	Items, Score := champshipCfg.GetRewardItems(ChampshipMod.Reward + 1)
	if Score < 50 {
		return
	}
	b := false
	for _, v := range Items {
		if v.Id == item.ITEM_ENERGY_ID {
			b = true
			break
		}
	}
	BaseMod := player.PlayMod.getBaseMod()
	if !b {
		BaseMod.SetSeed(false)
	} else {
		BaseMod.SetSeed(true)
	}
}

func TriggerSeedSource(player *Player) {
	BaseMod := player.PlayMod.getBaseMod()
	if !BaseMod.GetSeed() {
		return
	}
	Total := 0
	Energy := BaseMod.GetEnergy()
	Total += Energy

	ChessMod := player.PlayMod.getChessMod()
	ChessList := ChessMod.GetUnlockChessList()
	ChessBuff := ChessMod.GetChessBuf()
	AllChess := append(ChessList, ChessBuff...)
	for _, v := range AllChess {
		ChessColor := mergeDataCfg.GetColorById(v)
		if ChessColor == "Energy" {
			Total += mergeDataCfg.GetSellNumById(v)
		}
		if v == chess.CHESS_ENERGY_CHEST {
			Total += 50
		}
		if v == chess.CHESS_SURPRISE_CHEST_LOCK || v == chess.CHESS_SURPRISE_CHEST {
			Total += 10
		}
		if v == chess.CHESS_SOURCE_CHEST {
			Total += 100
		}
		if v == chess.CHESS_HIGH_SOURCE_CHEST {
			Total += 250
		}
	}

	Total += (5 - BaseMod.EnergyAD) * 25
	BaseMod.SetSource(Total)
}

func TriggerSeedOrder(player *Player) *order.Order {
	OrderMod := player.PlayMod.getOrderMod()
	ChessMod := player.PlayMod.getChessMod()
	BaseMod := player.PlayMod.getBaseMod()
	if !BaseMod.GetSeed() {
		return nil
	}
	OrderMod.CreatOrderPool(BaseMod.Level, ChessMod.GetOrderEmit(), BaseMod.EnergyMul)
	ChampshipMod := player.PlayMod.getChampshipMod()
	NeedScore := champshipCfg.GetRewardTotalScore(ChampshipMod.Reward + 1)
	E := BaseMod.GetSource()
	ChessList := ChessMod.GetUnlockChessList()
	ChessBuff := ChessMod.GetChessBuf()
	AllChess := append(ChessList, ChessBuff...)
	NewOrder := &order.Order{}
	MaxQ := 0
	MinQ := 0
	// 计算Q值
	for _, Order := range OrderMod.OrderPool {
		Q := 0
		for _, v := range Order.MergeId {
			Color := mergeDataCfg.GetColorById(v)
			Lv := mergeDataCfg.GetLvById(v)
			Q1 := int(math.Pow(2, float64(Lv))) - 1
			Q2 := 0
			Q3 := 0
			for _, Chess := range AllChess {
				Lv1 := mergeDataCfg.GetLvById(Chess)
				Color1 := mergeDataCfg.GetColorById(Chess)
				Type := mergeDataCfg.GetTypeById(Chess)
				if Type != "Product" {
					continue
				}
				if Color != Color1 {
					continue
				}
				if Lv1 > Lv {
					continue
				}
				Q2 += int(math.Pow(2, float64(Lv1))) - 1
			}
			for _, Chess := range AllChess {
				if Chess == chess.CHESS_ZIXUAN_CHEST {
					if Lv < 3 {
						continue
					}
					Q3 += int(math.Pow(2, 3)) - 1
				}
				if Chess == chess.CHESS_HIGH_ZIXUAN_CHEST {
					if Lv < 7 {
						continue
					}
					Q3 += int(math.Pow(2, 7)) - 1
				}
				if Chess == chess.CHESS_SOURCE_CHEST {
					if Lv < 3 {
						continue
					}
					Q3 += int(math.Pow(2, 3)) - 1
					Q3 += int(math.Pow(2, 4)) - 1
				}
				if Chess == chess.CHESS_HIGH_SOURCE_CHEST {
					if Lv < 7 {
						continue
					}
					Q3 += int(math.Pow(2, 7)) - 1
					Q3 += int(math.Pow(2, 7)) - 1
				}
			}
			Q += max(Q1-Q2-Q3, 0)
			Order.Q = Q
			MaxQ = max(MaxQ, Q)
			MinQ = min(MinQ, Q)
		}
	}

	if E > MaxQ {
		return nil
	}

	if E == MaxQ {
		for _, Order := range OrderMod.OrderPool {
			if Order.Q == MaxQ {
				NewOrder = Order
				break
			}
		}
		EmitTypeList := []string{}
		for _, v := range NewOrder.MergeId {
			Color := mergeDataCfg.GetColorById(v)
			EmitType := mergeDataCfg.GetEmitTypeByColor(Color)
			EmitTypeList = append(EmitTypeList, EmitType)
		}
		ChessList := []int{}
		for _, v := range AllChess {
			Color := mergeDataCfg.GetColorById(v)
			EmitType := mergeDataCfg.GetEmitTypeByColor(Color)
			Lv := mergeDataCfg.GetLvById(v)
			if Lv < 3 || Lv > 4 {
				continue
			}
			if GoUtil.InStringArray(EmitType, EmitTypeList) {
				continue
			}
			ChessList = append(ChessList, v)
		}
		if len(ChessList) != 0 {
			RandChess := GoUtil.RandSlice(ChessList)
			Color := mergeDataCfg.GetColorById(RandChess)
			Lv := mergeDataCfg.GetLvById(RandChess)
			NewChess := mergeDataCfg.GetChessIdByLvAndColor(Lv, Color)
			NewOrder.MergeId = append(NewOrder.MergeId, NewChess)
		}
		return NewOrder
	}

	if E == MinQ {
		for _, Order := range OrderMod.OrderPool {
			if Order.Q == MinQ {
				return Order
			}
		}
	}

	if E < MinQ {
		for _, Order := range OrderMod.OrderPool {
			if Order.Q == MinQ {
				ChessList := []int{}
				for _, v := range AllChess {
					Lv := mergeDataCfg.GetLvById(v)
					if Lv < 5 {
						ChessList = append(ChessList, v)
					}
				}
				if len(ChessList) != 0 {
					NewChess := GoUtil.RandSlice(ChessList)
					Order.MergeId = append(Order.MergeId, NewChess)
				}
				return Order
			}
		}
	}

	if E > MinQ && E < MaxQ {
		L1 := []*order.Order{}
		for _, Order := range OrderMod.OrderPool {
			if Order.Q > E {
				L1 = append(L1, Order)
			}
		}
		Smax := 0
		Smin := 0
		for _, Order := range L1 {
			Score := 0
			for _, v := range Order.MergeId {
				Lv := mergeDataCfg.GetLvById(v)
				Score += champshipCfg.GetChessScore(Lv)
			}
			Smax = max(Score, Smax)
			Smin = min(Score, Smin)
			Order.S = Score
		}

		if NeedScore > Smax {
			for _, Order := range OrderMod.OrderPool {
				if Order.Q == MinQ {
					ChessList := []int{}
					for _, v := range AllChess {
						Lv := mergeDataCfg.GetLvById(v)
						if Lv < 5 {
							ChessList = append(ChessList, v)
						}
					}
					if len(ChessList) != 0 {
						NewChess := GoUtil.RandSlice(ChessList)
						Order.MergeId = append(Order.MergeId, NewChess)
					}
					return Order
				}
			}
		}
		if NeedScore == Smax {
			for _, Order := range L1 {
				if Order.S == Smax {
					return Order
				}
			}
		}

		if NeedScore == Smin {
			for _, Order := range L1 {
				if Order.S == Smin {
					return Order
				}
			}
		}
		L2 := []*order.Order{}
		for _, Order := range L1 {
			if Order.S > NeedScore {
				L2 = append(L2, Order)
			}
		}
		if len(L2) != 0 {
			sort.Slice(L2, func(i, j int) bool {
				return L2[i].Q < L2[j].Q
			})
			return L2[0]
		}
	}
	return NewOrder
}
