package model

import "time"

// ---- Buffs ----

type BuffType string

const (
	BuffRush         BuffType = "rush"         // +attack speed
	BuffRage         BuffType = "rage"         // +damage
	BuffShield       BuffType = "shield"       // -incoming damage
	BuffLuck         BuffType = "luck"         // loot mult from tuning.LuckBuffMultiplier when active
	BuffResurrection BuffType = "resurrection" // revive on death
	BuffHeal         BuffType = "heal"         // +50% HP instantly
	BuffPowerPotion  BuffType = "power_potion" // +150% damage
	BuffWarCry       BuffType = "war_cry"      // +100% attack speed
)

// AllBuffTypes is the complete list of valid buff types.
var AllBuffTypes = []BuffType{
	BuffRush, BuffRage, BuffShield, BuffLuck, BuffResurrection,
	BuffHeal, BuffPowerPotion, BuffWarCry,
}

// ValidBuffType checks if a string is a valid buff type.
func ValidBuffType(s string) (BuffType, bool) {
	bt := BuffType(s)
	for _, t := range AllBuffTypes {
		if t == bt {
			return bt, true
		}
	}
	return "", false
}

type Buff struct {
	ID               int64         `json:"id"`
	Type             BuffType      `json:"type"`
	Name             string        `json:"name"`
	Duration         time.Duration `json:"duration"`
	Magnitude        float64       `json:"magnitude"` // effect strength (e.g., 0.3 = +30%)
	CooldownDuration time.Duration `json:"cooldownDuration"`
}

type ActiveBuff struct {
	Buff      Buff      `json:"buff"`
	AppliedAt time.Time `json:"appliedAt"`
	ExpiresAt time.Time `json:"expiresAt"`
}

// IsExpired returns true if the buff has expired relative to the given time.
func (ab *ActiveBuff) IsExpired(now time.Time) bool {
	return now.After(ab.ExpiresAt)
}

// ---- Debuffs ----

type DebuffType string

const (
	DebuffPoison  DebuffType = "poison"   // -2% HP/sec
	DebuffFreeze  DebuffType = "freeze"   // -50% attack speed
	DebuffBurn    DebuffType = "burn"     // -3% HP/sec
	DebuffStun    DebuffType = "stun"     // no attacks for 2 sec
	DebuffSlow    DebuffType = "slow"     // -40% movement speed (not attack speed)
	DebuffWeaken  DebuffType = "weaken"   // -30% hero outgoing damage
	DebuffIceSlow DebuffType = "ice_slow" // -20% attack speed (Ice Guardian per spec §4.2)
)

// AllDebuffTypes is the complete list of valid debuff types.
var AllDebuffTypes = []DebuffType{
	DebuffPoison, DebuffFreeze, DebuffBurn, DebuffStun, DebuffSlow, DebuffWeaken, DebuffIceSlow,
}

// ValidDebuffType checks if a string is a valid debuff type.
func ValidDebuffType(s string) (DebuffType, bool) {
	dt := DebuffType(s)
	for _, t := range AllDebuffTypes {
		if t == dt {
			return dt, true
		}
	}
	return "", false
}

type Debuff struct {
	ID        int64         `json:"id"`
	Type      DebuffType    `json:"type"`
	Name      string        `json:"name"`
	Duration  time.Duration `json:"duration"`
	Magnitude float64       `json:"magnitude"` // effect strength
}

type ActiveDebuff struct {
	Debuff    Debuff    `json:"debuff"`
	AppliedAt time.Time `json:"appliedAt"`
	ExpiresAt time.Time `json:"expiresAt"`
}

// IsExpired returns true if the debuff has expired relative to the given time.
func (ad *ActiveDebuff) IsExpired(now time.Time) bool {
	return now.After(ad.ExpiresAt)
}

// RemoveBuffType returns buffs without any active entry of the given type (e.g. consume Resurrection on manual revive).
func RemoveBuffType(buff []ActiveBuff, remove BuffType) []ActiveBuff {
	var out []ActiveBuff
	for _, ab := range buff {
		if ab.Buff.Type != remove {
			out = append(out, ab)
		}
	}
	return out
}
