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"         // x2.5 loot
	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)
}

// DefaultBuffs defines the base buff definitions.
var DefaultBuffs = map[BuffType]Buff{
	BuffRush: {
		Type: BuffRush, Name: "Rush",
		Duration: 5 * time.Minute, Magnitude: 0.5, // +50% movement
		CooldownDuration: 15 * time.Minute,
	},
	BuffRage: {
		Type: BuffRage, Name: "Rage",
		Duration: 3 * time.Minute, Magnitude: 1.0, // +100% damage
		CooldownDuration: 10 * time.Minute,
	},
	BuffShield: {
		Type: BuffShield, Name: "Shield",
		Duration: 5 * time.Minute, Magnitude: 0.5, // -50% incoming damage
		CooldownDuration: 12 * time.Minute,
	},
	BuffLuck: {
		Type: BuffLuck, Name: "Luck",
		Duration: 30 * time.Minute, Magnitude: 1.5, // x2.5 loot
		CooldownDuration: 2 * time.Hour,
	},
	BuffResurrection: {
		Type: BuffResurrection, Name: "Resurrection",
		Duration: 10 * time.Minute, Magnitude: 0.5, // revive with 50% HP
		CooldownDuration: 30 * time.Minute,
	},
	BuffHeal: {
		Type: BuffHeal, Name: "Heal",
		Duration: 1 * time.Second, Magnitude: 0.5, // +50% HP (instant)
		CooldownDuration: 5 * time.Minute,
	},
	BuffPowerPotion: {
		Type: BuffPowerPotion, Name: "Power Potion",
		Duration: 5 * time.Minute, Magnitude: 1.5, // +150% damage
		CooldownDuration: 20 * time.Minute,
	},
	BuffWarCry: {
		Type: BuffWarCry, Name: "War Cry",
		Duration: 3 * time.Minute, Magnitude: 1.0, // +100% attack speed
		CooldownDuration: 10 * time.Minute,
	},
}

// ---- 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)
}

// DefaultDebuffs defines the base debuff definitions.
var DefaultDebuffs = map[DebuffType]Debuff{
	DebuffPoison: {
		Type: DebuffPoison, Name: "Poison",
		Duration: 5 * time.Second, Magnitude: 0.02, // -2% HP/sec
	},
	DebuffFreeze: {
		Type: DebuffFreeze, Name: "Freeze",
		Duration: 3 * time.Second, Magnitude: 0.50, // -50% attack speed
	},
	DebuffBurn: {
		Type: DebuffBurn, Name: "Burn",
		Duration: 4 * time.Second, Magnitude: 0.03, // -3% HP/sec
	},
	DebuffStun: {
		Type: DebuffStun, Name: "Stun",
		Duration: 2 * time.Second, Magnitude: 1.0, // no attacks
	},
	DebuffSlow: {
		Type: DebuffSlow, Name: "Slow",
		Duration: 4 * time.Second, Magnitude: 0.40, // -40% movement
	},
	DebuffWeaken: {
		Type: DebuffWeaken, Name: "Weaken",
		Duration: 5 * time.Second, Magnitude: 0.30, // -30% hero outgoing damage
	},
	DebuffIceSlow: {
		Type: DebuffIceSlow, Name: "Ice Slow",
		Duration: 4 * time.Second, Magnitude: 0.20, // -20% attack speed (Ice Guardian spec §4.2)
	},
}

// 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
}
