package input

import (
	"blazing/logic/service/fight/info"

	"blazing/modules/blazing/model"
	"reflect"

	"github.com/mohae/deepcopy"
	"github.com/tnnmigga/enum"
)

// 战斗结束原因枚举
type EnumEffectType int

var EffectType = enum.New[struct {
	Skill  EnumEffectType `enum:"1000000"` //技能
	Prop   EnumEffectType `enum:"2000000"` //属性
	Status EnumEffectType `enum:"3000000"` //状态
	Damage EnumEffectType `enum:"4000000"` //伤害

}]()
var NodeM = make(map[int]Effect, 0)

func InitEffect(etype EnumEffectType, id int, t Effect) {

	NodeM[id+int(etype)] = t
}
func Geteffect(etype EnumEffectType, id int) *EffectID {

	//todo 获取前GetEffect
	ret, ok := NodeM[id+int(etype)]
	if ok {
		//todo 获取前GetEffect
		eff := deepcopy.Copy(ret).(Effect)
		return &EffectID{
			ID:     id + int(etype),
			Effect: eff,
		}
		//todo 获取后GetEffect
	}
	return &EffectID{}
}

// * battle_lv: atk(0), def(1), sp_atk(2), sp_def(3), spd(4), accuracy(5)
// 是否需要真实提升
func (c *Input) GetProp(id int, istue bool) int {
	// 获取基础属性值
	baseValue := int(c.AttackValue.Prop[id])

	// 命中情况直接返回基础值（优先判断）
	if id >= 5 {
		return baseValue
	}

	// 处理id < 5的情况
	if istue {
		return baseValue
	}

	// 计算实际值（这里可以插入后续优化的函数调用）
	realValue := info.CalculateRealValue(int(c.CurrentPet.Info.Prop[id]), baseValue)

	// todo: 插入获取后处理函数，例如：
	// realValue = postProcessValue(realValue, id, c)

	return realValue

}

func (c *Input) GetEffect(etype EnumEffectType, id int) Effect {
	rer, _ := c.Effects.Load(id + int(etype))

	return rer
}

type EffectID struct {
	ID     int
	Effect Effect
}

func (c *Input) GetCurrAttr(id int) *model.PetInfo {

	//todo 获取前GetEffect
	return c.CurrentPet.Info

	//todo 获取后GetEffect
}
func getTypeName(v interface{}) string {
	// 获取类型信息
	t := reflect.TypeOf(v)

	// 如果是指针类型，需要先获取其指向的元素类型
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}

	// 如果是结构体类型，返回其名称
	if t.Kind() == reflect.Struct {
		return t.Name()
	}

	// 非结构体类型返回空或对应的类型名
	return t.Kind().String()
}

func (c *Input) AddEffect(e *EffectID) {
	if e.ID == 0 {
		return
	}
	//todo 免疫
	//TODO 先激活

	// 如果已有同 ID 的效果，尝试叠加
	eff, ok := c.Effects.Load(e.ID)
	if !ok {
		// 否则新加入
		c.Effects.Store(e.ID, e.Effect)
		return
	}
	if !eff.Alive() { //如果不存活
		c.Effects.Store(e.ID, e.Effect)
		return
	}

	c.Effects.Range(func(key int, value Effect) bool {
		if e.ID == key {
			//设置输入源
			if value.Stack() < value.GetMaxStack() { //如果小于最大叠层
				value.Stack(value.Stack()) //获取到当前叠层数然后叠加
			} else {

				//这里,说明是延续回合效果

				value.Duration(value.Duration())
			}
			return false
		}

		return true
	})

}

// ForEachEffectBool 遍历所有 Effect，执行“无参数、返回 bool”的方法
// 参数 fn：接收单个 Effect，返回 bool（如 func(e Effect) bool { return e.OnBattleStart() }）
// 返回值：所有 Effect 的方法返回值列表
func (c *Input) Exec(fn func(Effect) bool) bool {
	c.Effects.Range(func(key int, value Effect) bool {
		if value.Alive() {
			result := fn(value)
			if !result {
				return result //如果是false,说明存在阻止向下执行的effect，比如免疫能力提升效果
			}

		}
		return true
	})

	return true
}

// 消除回合类效果  efftype 输入是消对方的还是自己的,false是自己,true是对方
func (c *Input) CancelTurn(efftype bool) {

	c.Effects.Range(func(key int, value Effect) bool {
		if value.Duration() > 0 { //false是自身,true是对方,反转后为真就是自己的
			//slice = append(slice[:i], slice[i+1:]...)
			value.NotALive()
		}
		return true
	})

}
