package info

import (
	element "blazing/common/data/Element"
	"blazing/common/data/xmlres"
	"blazing/modules/blazing/model"
	"math/rand"

	"context"
	"fmt"
	"strconv"

	"github.com/gogf/gf/v2/os/glog"
	"github.com/shopspring/decimal"
	"github.com/tnnmigga/enum"
)

const BattleSkillEntityCtx = "skill"

// EnumSkillType 技能类型枚举基础类型
type EnumCategory int

// SkillType 技能类型枚举实例（使用enum包创建）
// 与原Java枚举保持相同的数值映射：PHYSICAL=1, SPECIAL=2, STATUS=4
var Category = enum.New[struct {
	PHYSICAL EnumCategory `enum:"1"` // 物理攻击
	SPECIAL  EnumCategory `enum:"2"` // 特殊攻击
	STATUS   EnumCategory `enum:"4"` // 状态技能
	Fixed    EnumCategory // 固定伤害
	Percent  EnumCategory // 百分比伤害
	True     EnumCategory // 真伤
	ALL      EnumCategory //任何类型
}]()

// SkillEntity 战斗技能实体
// 实现了战斗中技能的所有属性和行为，包括PP管理、技能使用、属性获取等
// 战斗中可以修改技能实体值,比如是否暴击,是否必中等
type SkillEntity struct {
	xmlres.Move
	Info *model.SkillInfo

	DamageValue decimal.Decimal // 伤害值
	Rand        *rand.Rand
	Pet         *BattlePetEntity
	//MaxValue    func(ahp, bhp uint32) decimal.Decimal
	Crit       uint32
	AttackTime uint32
}

// CreateSkill 创建战斗技能实例（可指定是否无限PP）
func CreateSkill(skill *model.SkillInfo, rand *rand.Rand, pet *BattlePetEntity) *SkillEntity {
	//如果PP是-1 ,那就是无限PP
	// ID小于10001的视为无效技能

	if skill.ID < 10001 {
		return nil
	}

	var ret SkillEntity
	ret.Rand = rand
	ret.Pet = pet
	// 从资源仓库获取技能数据
	move, ok := xmlres.SkillMap[int(skill.ID)]

	if !ok {
		glog.Error(context.Background(), "技能ID无效", "id", skill.ID)
	}
	ret.Move = move
	// // 解析副作用参数
	// sideEffectArgs := parseSideEffectArgs(move.SideEffectArg)
	// tt := strings.Split(move.SideEffect, " ")
	// rf, err := strSliceToIntSlice(tt)
	// if err == nil {
	// 	ret.SideEffects = rf
	// }
	ret.Info = skill
	// ret.SideEffectArgs = sideEffectArgs

	return &ret
}

// 将字符串切片转换为整数切片
func strSliceToIntSlice(strs []string) ([]int, error) {
	intSlice := make([]int, 0, len(strs)) // 预分配容量，提高性能

	for _, s := range strs {
		// 将字符串转换为整数
		num, err := strconv.Atoi(s)
		if err != nil {
			// 转换失败时返回错误（包含具体的错误信息和失败的字符串）
			return nil, fmt.Errorf("无法将字符串 '%s' 转换为整数: %v", s, err)
		}
		intSlice = append(intSlice, num)
	}

	return intSlice, nil
}

// CanUse 检查技能是否可以使用（PP是否充足）
func (s *SkillEntity) CanUse() bool {
	return s.Info.PP > 0
}

// 获取技能类型
func (s *SkillEntity) Category() EnumCategory {
	return EnumCategory(s.Move.Category)
}

// 获取技能属性
func (s *SkillEntity) Type() *element.ElementCombination {
	ret, _ := element.NewElementCombination(s.Move.Type)
	return ret
}

// // 技能产生effect
// func (u *BattleSkillEntity) NewEffect(ctx context.Context)*node.EffectNode {

// 	ret := node.EffectNode{}
// 	ctx = context.WithValue(ctx, BattleSkillEntityCtx, &ret) //添加用户到上下文
// 	ret.ctx = ctx

// }
// 解析副作用参数字符串为整数列表

// 获取技能名称，为空时使用ID
func getSkillName(move *SkillEntity) string {
	if move.Name == "" {
		return strconv.FormatInt(int64(move.ID), 10)
	}
	return move.Name
}

// 获取副作用列表，处理空值情况
// func getSideEffects(move *BattleSkillEntity) []int {
// 	if move.SideEffect == "" {
// 		return []int{}
// 	}
// 	return move.SideEffects
// }

type EnumsZoneType int

var DamageZone = enum.New[struct {
	add EnumsZoneType // 加区

	nul EnumsZoneType // 乘区
}]()
var DamageC = enum.New[struct {
	boost     EnumsZoneType //增伤区
	reduction EnumsZoneType // 减伤区
}]()

// func (s *BattleSkillEntity) Random() *random.RandomXS128 {
// 	battle, _ := s.ctx.Value(BattleContainerCtx).(*Battle1V1)

// 	return battle.Rand

// }

// func (s *BattleSkillEntity) Pet() (*BattlePetEntity, bool) {
// 	pet, ok := s.ctx.Value(Pet_O_Ctx).(*BattlePetEntity)

// 	return pet, ok

// }

// 计算是否命中
func (s *SkillEntity) AttackTimeC(level int) {
	s.AttackTime = 0 //先重置上一次的
	if s.MustHit != 0 {
		s.AttackTime = 2
	}

	if int64(s.GetAccuracy(level)) > s.Rand.Int63n(100) {
		s.AttackTime = 1
	}

}
func (s *SkillEntity) CriticalsameTypeBonus() decimal.Decimal {

	// 6. 同系加成（属性相同则乘以同系加成倍率，否则1）
	sameTypeBonus := decimal.NewFromFloat(1.0)
	if s.Type() == s.Pet.Type() { //使用本系
		sameTypeBonus = decimal.NewFromFloat(1.5)
	}

	stype := s.Type()
	ptype := s.Pet.Type()

	if stype.Secondary == nil && ptype.Secondary != nil && (stype.Primary == ptype.Primary || stype.Primary == *ptype.Secondary) { //判断技能属性是否是精灵双属性之一
		sameTypeBonus = decimal.NewFromFloat(1.5)
	}
	return sameTypeBonus
}

func (s *SkillEntity) criticalrandom() decimal.Decimal {

	randomnum := s.Rand.Int31n(39) + 217
	// 10. 随机倍率，随机值除以255
	randomFactor := decimal.NewFromInt(int64(randomnum)).Div(decimal.NewFromInt(255))
	return randomFactor

}

// Accuracy 优化版命中率计算（用绝对值和正负判断处理等级）
func (a *SkillEntity) GetAccuracy(level int) uint32 {
	// 基础参数校验
	if a.Accuracy == 0 {
		return 0
	}
	if a.Accuracy >= 100 {
		return 100
	}

	if level > 6 || level == 0 { //强化等级
		return uint32(CalculateRealValue((a.Accuracy), level))
	}
	var temp float64
	switch level {
	case -1:
		temp = 0.85
	case -2:
		temp = 0.7
	case -3:
		temp = 0.55
	case -4:
		temp = 0.45
	case -5:
		temp = 0.35
	case -6:
		temp = 0.25

	}
	return uint32(
		decimal.NewFromInt(int64(a.Accuracy)). // 将b转为decimal类型
							Mul(decimal.NewFromFloat(temp)). // 精确乘以0.85
							Round(0).                        // 四舍五入到整数
							IntPart(),                       // 转为int64
	)
}

// 计算技能威力
func (s *SkillEntity) CalculatePower(deftype *BattlePetEntity) decimal.Decimal {

	// 1. 计算等级因子 (level * 0.4 + 2)
	levelFactor := decimal.NewFromInt(int64(s.Pet.Info.Level)).
		Mul(decimal.NewFromFloat(0.4)).Add(decimal.NewFromInt(2))

	// 2. 计算威力因子 (基础威力 + 加算) * 乘算

	//powerAdd := decimal.NewFromFloat(s.GetAddValue(EnumCategory., true)) //威力加算区
	powerAdd_all := s.Pet.GetAddValue(Category.ALL, DamageC.boost)
	powerMul_all := s.Pet.GetMulValue(Category.ALL, DamageC.boost)

	var (
		powerAdd_p decimal.Decimal //威力加算
		powerMul_p decimal.Decimal //威力乘算
		attackDec  decimal.Decimal //攻击值
		defenseDec decimal.Decimal //防御值
		//damageReduction decimal.Decimal //伤害百分比减免
	)
	switch s.Category() { //判断技能类型
	case Category.PHYSICAL:

		powerAdd_p = powerAdd_all.Add(s.Pet.GetAddValue(Category.PHYSICAL, DamageC.boost))
		powerMul_p = powerMul_all.Add(s.Pet.GetMulValue(Category.PHYSICAL, DamageC.boost))
		attackDec = decimal.NewFromInt(int64(s.Pet.Info.Prop[0]))
		defenseDec = decimal.NewFromInt(int64(s.Pet.Info.Prop[1]))
		//damageReduction = decimal.NewFromFloat(s.DamageZone[DamageMultiplierZoneEnum.ATK_RESISTANCE])

	case Category.SPECIAL:
		powerAdd_p = powerAdd_all.Add(s.Pet.GetAddValue(Category.SPECIAL, DamageC.boost))
		powerMul_p = powerMul_all.Add(s.Pet.GetMulValue(Category.SPECIAL, DamageC.boost))
		attackDec = decimal.NewFromInt(int64(s.Pet.Info.Prop[2]))
		defenseDec = decimal.NewFromInt(int64(s.Pet.Info.Prop[3]))
		//damageReduction = decimal.NewFromFloat(s.DamageZone[DamageMultiplierZoneEnum.SP_ATK_RESISTANCE])

	default:
		return decimal.NewFromInt(0)
	}

	if powerMul_p.IntPart() == 0 {
		powerMul_p = decimal.NewFromInt(1)
	}
	powerZone := decimal.NewFromInt(int64(s.Power)).Add(powerAdd_p).Mul(powerMul_p)
	// 5. 基础伤害公式：等级因子 * 威力因子 * 攻击 / 防御 / 50 + 2
	baseDamage := levelFactor.
		Mul(powerZone).
		Mul(attackDec).
		Div(defenseDec).
		Div(decimal.NewFromInt(50)).
		Add(decimal.NewFromInt(2))

	t, _ := element.NewElementCalculator().GetOffensiveMultiplier(s.Type().ID, deftype.Type().ID)

	typeRate := decimal.NewFromFloat(t)

	damage := baseDamage.
		Mul(s.CriticalsameTypeBonus()). // 同属性加成
		Mul(typeRate).                  // 克制系数

		Mul(s.criticalrandom()) //随机波动

	return damage

}
