package input

import (
	"blazing/logic/service/common"
	"blazing/logic/service/fight/info"
	"fmt"
	"math"

	"github.com/gogf/gf/v2/util/gconv"
	"github.com/jinzhu/copier"
	"github.com/mohae/deepcopy"
	"github.com/shopspring/decimal"
)

type Input struct {
	CanChange  bool                  //是否可以死亡切换CanChange
	CurrentPet *info.BattlePetEntity //当前精灵
	AllPet     []*info.BattlePetEntity
	Player     common.PlayerI
	Finished   bool //是否加载完成
	*info.AttackValue
	FightC common.FightI
	//	info.BattleActionI
	Effects []Effect        //effects 实际上全局就是effect无限回合 //effects容器 技能的
	Damage  decimal.Decimal //造成伤害
	First   bool            //是否先手
}

func NewInput(c common.FightI, p common.PlayerI) *Input {
	ret := &Input{FightC: c, Player: p}
	t, _ := ret.GetDamageEffect(1)
	ret.AddEffect(deepcopy.Copy(t).(Effect)) //添加默认基类,实现继承
	p.SetFightC(c)                           //给玩家设置战斗容器
	return ret

}
func (i *Input) GetPetInfo() *info.BattlePetEntity {

	return i.CurrentPet

}

// 这个每回合都会调用
func (i *Input) InitAttackValue() {
	i.AttackValue = info.NewAttackValue(i.Player.GetInfo().UserID)

}
func (i *Input) GetPet(id uint32) (ii *info.BattlePetEntity, Reason info.ChangePetInfo) {
	for _, v := range i.AllPet {
		if v.Info.CatchTime == uint32(id) {
			copier.Copy(&Reason, &v.Info)
			Reason.UserId = i.Player.GetInfo().UserID

			ii = v
		}

	}
	return

}

// GetStatusBonus 获取最高的状态倍率
// 遍历状态数组，返回存在的状态中最高的倍率（无状态则返回1.0）
func (i *Input) GetStatusBonus() float64 {
	// 异常状态倍率映射表（状态索引 -> 倍率）
	var statusBonuses = map[info.EnumBattleStatus]float64{
		info.BattleStatus.Paralysis: 1.5,
		info.BattleStatus.Poisoned:  1.5,
		info.BattleStatus.Sleep:     2.0,
		// /info.BattleStatus.Frozen:    2.0,
	}
	maxBonus := 1.0 // 默认无状态倍率

	for statusIdx := 0; statusIdx < 20; statusIdx++ {
		t, ok := i.GetStatusEffect(statusIdx)

		// 检查状态是否存在（数组中值为1表示存在该状态）
		if ok && t.Stack(0) > 0 {
			if bonus, exists := statusBonuses[info.EnumBattleStatus(statusIdx)]; exists && bonus > maxBonus {
				maxBonus = bonus
			}
		}
	}

	return maxBonus
}

// 特殊胶囊必定成功
// CaptureParams 捕捉参数
// type CaptureParams struct {
// 	PetID      int      // 精灵ID
// 	MaxHP      int      // 目标最大HP
// 	CurrentHP  int      // 目标当前HP
// 	CatchRate  int      // 目标捕获率分子
// 	CatchDenom int      // 捕获率分母（如100、1000）
// 	ItemID     int      // 使用的道具ID
// 	Statuses   [20]byte // 异常状态数组，存在的状态对应位置为1
// 	OwnedCount int      // 已拥有数量（-1=保底，0=锁定，≥1=衰减）
// }
// 胶囊配置（ItemID -> Bonus）
// var capsuleBonuses = map[int]float64{
// 	300001: 1.0,   // 普通精灵胶囊
// 	300002: 1.5,   // 中级精灵胶囊
// 	300003: 2.0,   // 高级精灵胶囊
// 	300004: 3.0,   // 超级精灵胶囊
// 	300005: 4.0,   // 特级精灵胶囊
// 	300006: 256.0, // 无敌精灵胶囊
// 	300007: 256.0, // 超能胶囊
// 	300008: 2.0,   // 赫星精灵胶囊
// 	300009: 256.0, // 时空精灵胶囊
// 	300010: 256.0, // 无敌精灵胶囊Ω
// }
//

// -1是保底模式，0是锁定模式，》0是衰减模式
// Capture 执行捕捉  ,捕捉精灵，使用的道具，模式
func (c *Input) Capture(pet *info.BattlePetEntity, ItemID uint32, ownerpet int) (bool, CaptureDetails) {

	if getItemBonus(ItemID) >= 255 {
		return true, CaptureDetails{
			Success:        true,
			Mode:           "特殊胶囊必定成功",
			BaseRate:       100.0,
			ModifiedRate:   100.0,
			GuaranteeBonus: 0,
			StatusBonus:    c.GetStatusBonus(),
			Details:        fmt.Sprintf("道具ID=%d，必定成功", ItemID),
		}
	}

	// 锁定模式
	if ownerpet == 0 {
		return false, CaptureDetails{
			Success:        false,
			Mode:           "锁定模式",
			BaseRate:       0,
			ModifiedRate:   0,
			GuaranteeBonus: 0,
			StatusBonus:    c.GetStatusBonus(),
			Details:        "已拥有数量为0，无法捕捉",
		}
	}

	// 计算基础捕捉率
	baseRate := c.calcBaseRate(pet, ItemID)
	denominator := c.Player.GetPlayerCaptureContext().Denominator
	numerator := int(baseRate * float64(denominator))

	// 衰减模式
	if ownerpet > 0 {
		decay := math.Pow(1-c.Player.GetPlayerCaptureContext().DecayFactor, float64(ownerpet))
		baseRate *= decay
		if baseRate < 0.01 {
			baseRate = 0.01 // 最低1%成功率
		}
		numerator = int(baseRate * float64(denominator))
	}

	// 走统一保底判定
	success, basePct, bonusPct := c.Player.Roll(numerator, denominator)

	return success, CaptureDetails{
		Success:        success,
		Mode:           map[int]string{-1: "保底模式", 0: "锁定模式", 1: "衰减模式"}[ownerpet],
		BaseRate:       basePct,
		ModifiedRate:   basePct + bonusPct,
		GuaranteeBonus: bonusPct,
		StatusBonus:    c.GetStatusBonus(),
		Details:        fmt.Sprintf("a=%d, 分子=%d, 分母=%d", c.calcBaseA(pet, ItemID), numerator, denominator),
	}
}

// calcBaseA 按公式计算a值
func (c *Input) calcBaseA(pet *info.BattlePetEntity, ItemID uint32) int {
	catchRate := gconv.Int(pet.CatchRate)
	catchRate = (catchRate * c.Player.GetPlayerCaptureContext().Denominator) / 1000 // 归一化到1000分母
	if catchRate < 3 {
		catchRate = 3
	}

	currentHP := pet.Info.Hp
	if currentHP <= 0 {
		currentHP = 1
	}

	hpRatio := (3.0*float64(pet.Info.MaxHp) - 2.0*float64(currentHP)) / (3.0 * float64(pet.Info.MaxHp))
	if hpRatio < 0 {
		hpRatio = 0
	}

	itemBonus := getItemBonus(ItemID)
	statusBonus := c.GetStatusBonus()

	return int(hpRatio * float64(catchRate) * itemBonus * statusBonus)
}

// calcBaseRate 按公式计算基础成功率
func (c *Input) calcBaseRate(pet *info.BattlePetEntity, ItemID uint32) float64 {
	if getItemBonus(ItemID) >= 255 {
		return 1.0
	}

	a := c.calcBaseA(pet, ItemID)
	if a >= 255 {
		return 1.0
	}

	g := int(1048560.0 / math.Floor(math.Sqrt(math.Floor(math.Sqrt(math.Floor(16711680.0/float64(a)))))))
	return math.Pow(float64(g)/65536.0, 4.0)
}
