package model

import "math/rand"

// GearItem represents any equippable item across all slots.
type GearItem struct {
	ID            int64         `json:"id"`
	Slot          EquipmentSlot `json:"slot"`
	FormID        string        `json:"formId"`
	Name          string        `json:"name"`
	Subtype       string        `json:"subtype"`
	Rarity        Rarity        `json:"rarity"`
	Ilvl          int           `json:"ilvl"`
	BasePrimary   int           `json:"basePrimary"`
	PrimaryStat   int           `json:"primaryStat"`
	StatType      string        `json:"statType"`
	SpeedModifier float64       `json:"speedModifier"`
	CritChance    float64       `json:"critChance"`
	AgilityBonus  int           `json:"agilityBonus"`
	SetName       string        `json:"setName,omitempty"`
	SpecialEffect string        `json:"specialEffect,omitempty"`
}

// GearFamily is a template for generating gear drops from the unified catalog.
type GearFamily struct {
	Slot          EquipmentSlot `json:"slot"`
	FormID        string        `json:"formId"`
	Name          string        `json:"name"`
	Subtype       string        `json:"subtype"` // "daggers", "sword", "axe", "light", "medium", "heavy", ""
	BasePrimary   int           `json:"basePrimary"`
	StatType      string        `json:"statType"`
	SpeedModifier float64       `json:"speedModifier"`
	BaseCrit      float64       `json:"baseCrit"`
	AgilityBonus  int           `json:"agilityBonus"`
	SetName       string        `json:"setName,omitempty"`
	SpecialEffect string        `json:"specialEffect,omitempty"`
}

// GearCatalog is the unified catalog of all gear families.
var GearCatalog []GearFamily
var defaultGearCatalog []GearFamily

// ArmorSetBonuses maps set names to their bonus description.
var GearSetBonuses = map[string]string{
	"Assassin's Set":         "+crit_chance",
	"Knight's Set":           "+defense",
	"Berserker's Set":        "+attack",
	"Ancient Guardian's Set": "+all_stats",
}

func init() {
	// Weapons -> main_hand
	for _, w := range legacyWeapons {
		GearCatalog = append(GearCatalog, GearFamily{
			Slot:          SlotMainHand,
			FormID:        "gear.form.main_hand." + string(w.Type),
			Name:          w.Name,
			Subtype:       string(w.Type),
			BasePrimary:   w.Damage,
			StatType:      "attack",
			SpeedModifier: w.Speed,
			BaseCrit:      w.CritChance,
			SpecialEffect: w.SpecialEffect,
		})
	}

	// Armors -> chest
	for _, a := range legacyArmors {
		GearCatalog = append(GearCatalog, GearFamily{
			Slot:          SlotChest,
			FormID:        "gear.form.chest." + string(a.Type),
			Name:          a.Name,
			Subtype:       string(a.Type),
			BasePrimary:   a.Defense,
			StatType:      "defense",
			SpeedModifier: a.SpeedModifier,
			AgilityBonus:  a.AgilityBonus,
			SetName:       a.SetName,
			SpecialEffect: a.SpecialEffect,
		})
	}

	// Extended equipment families -> head, feet, neck, hands, legs, cloak, finger, wrist
	for slot, families := range legacyEquipmentFamilies {
		for _, f := range families {
			GearCatalog = append(GearCatalog, GearFamily{
				Slot:          slot,
				FormID:        f.FormID,
				Name:          f.Name,
				BasePrimary:   f.BasePrimary,
				StatType:      f.StatType,
				SpeedModifier: 1.0,
			})
		}
	}

	// Build the by-slot-and-rarity index.
	gearBySlot = make(map[EquipmentSlot][]GearFamily)
	for _, gf := range GearCatalog {
		gearBySlot[gf.Slot] = append(gearBySlot[gf.Slot], gf)
	}
	defaultGearCatalog = append([]GearFamily(nil), GearCatalog...)
}

var gearBySlot map[EquipmentSlot][]GearFamily

func SetGearCatalog(families []GearFamily) {
	if len(families) == 0 {
		return
	}

	merged := append([]GearFamily(nil), families...)
	slotsFromDB := make(map[EquipmentSlot]struct{}, len(families))
	for _, gf := range families {
		slotsFromDB[gf.Slot] = struct{}{}
	}
	for _, fallback := range defaultGearCatalog {
		if _, ok := slotsFromDB[fallback.Slot]; ok {
			continue
		}
		merged = append(merged, fallback)
	}

	GearCatalog = merged
	gearBySlot = make(map[EquipmentSlot][]GearFamily)
	for _, gf := range GearCatalog {
		gearBySlot[gf.Slot] = append(gearBySlot[gf.Slot], gf)
	}
}

// PickGearFamily selects a random gear family for the given slot.
// Returns nil if no families exist for the slot.
func PickGearFamily(slot EquipmentSlot) *GearFamily {
	families := gearBySlot[slot]
	if len(families) == 0 {
		return nil
	}
	f := families[rand.Intn(len(families))]
	return &f
}

// NewGearItem creates a GearItem from a family template with ilvl and rarity scaling applied.
func NewGearItem(family *GearFamily, ilvl int, rarity Rarity) *GearItem {
	primary := ScalePrimary(family.BasePrimary, ilvl, rarity)
	return &GearItem{
		Slot:          family.Slot,
		FormID:        family.FormID,
		Name:          family.Name,
		Subtype:       family.Subtype,
		Rarity:        rarity,
		Ilvl:          ilvl,
		BasePrimary:   family.BasePrimary,
		PrimaryStat:   primary,
		StatType:      family.StatType,
		SpeedModifier: family.SpeedModifier,
		CritChance:    family.BaseCrit,
		AgilityBonus:  family.AgilityBonus,
		SetName:       family.SetName,
		SpecialEffect: family.SpecialEffect,
	}
}

// ---------- Legacy data (moved from weapon.go, armor.go, equipment.go) ----------

// legacyWeaponEntry holds weapon catalog data for building the GearCatalog.
type legacyWeaponEntry struct {
	Name          string
	Type          string
	Rarity        Rarity
	Damage        int
	Speed         float64
	CritChance    float64
	SpecialEffect string
}

var legacyWeapons = []legacyWeaponEntry{
	// Daggers
	{Name: "Rusty Dagger", Type: "daggers", Rarity: RarityCommon, Damage: 3, Speed: 1.3, CritChance: 0.05},
	{Name: "Iron Dagger", Type: "daggers", Rarity: RarityUncommon, Damage: 5, Speed: 1.3, CritChance: 0.08},
	{Name: "Assassin's Blade", Type: "daggers", Rarity: RarityRare, Damage: 8, Speed: 1.35, CritChance: 0.20},
	{Name: "Phantom Edge", Type: "daggers", Rarity: RarityEpic, Damage: 12, Speed: 1.4, CritChance: 0.25},
	{Name: "Fang of the Void", Type: "daggers", Rarity: RarityLegendary, Damage: 18, Speed: 1.5, CritChance: 0.30},
	// Swords
	{Name: "Iron Sword", Type: "sword", Rarity: RarityCommon, Damage: 7, Speed: 1.0, CritChance: 0.03},
	{Name: "Steel Sword", Type: "sword", Rarity: RarityUncommon, Damage: 10, Speed: 1.0, CritChance: 0.05},
	{Name: "Longsword", Type: "sword", Rarity: RarityRare, Damage: 15, Speed: 1.0, CritChance: 0.08},
	{Name: "Excalibur", Type: "sword", Rarity: RarityEpic, Damage: 22, Speed: 1.05, CritChance: 0.10},
	{Name: "Soul Reaver", Type: "sword", Rarity: RarityLegendary, Damage: 30, Speed: 1.1, CritChance: 0.12, SpecialEffect: "lifesteal"},
	// Axes
	{Name: "Rusty Axe", Type: "axe", Rarity: RarityCommon, Damage: 12, Speed: 0.7, CritChance: 0.02},
	{Name: "Battle Axe", Type: "axe", Rarity: RarityUncommon, Damage: 18, Speed: 0.7, CritChance: 0.04},
	{Name: "War Axe", Type: "axe", Rarity: RarityRare, Damage: 25, Speed: 0.75, CritChance: 0.06},
	{Name: "Infernal Axe", Type: "axe", Rarity: RarityEpic, Damage: 35, Speed: 0.75, CritChance: 0.08},
	{Name: "Godslayer's Edge", Type: "axe", Rarity: RarityLegendary, Damage: 50, Speed: 0.8, CritChance: 0.10, SpecialEffect: "splash"},
}

// legacyArmorEntry holds armor catalog data for building the GearCatalog.
type legacyArmorEntry struct {
	Name          string
	Type          string
	Rarity        Rarity
	Defense       int
	SpeedModifier float64
	AgilityBonus  int
	SetName       string
	SpecialEffect string
}

var legacyArmors = []legacyArmorEntry{
	// Light armor
	{Name: "Leather Armor", Type: "light", Rarity: RarityCommon, Defense: 3, SpeedModifier: 1.05, AgilityBonus: 3},
	{Name: "Ranger's Vest", Type: "light", Rarity: RarityUncommon, Defense: 5, SpeedModifier: 1.08, AgilityBonus: 5},
	{Name: "Shadow Cloak", Type: "light", Rarity: RarityRare, Defense: 8, SpeedModifier: 1.10, AgilityBonus: 8, SetName: "Assassin's Set", SpecialEffect: "crit_bonus"},
	{Name: "Phantom Garb", Type: "light", Rarity: RarityEpic, Defense: 12, SpeedModifier: 1.12, AgilityBonus: 12, SetName: "Assassin's Set", SpecialEffect: "crit_bonus"},
	{Name: "Whisper of the Void", Type: "light", Rarity: RarityLegendary, Defense: 16, SpeedModifier: 1.15, AgilityBonus: 18, SetName: "Assassin's Set", SpecialEffect: "crit_bonus"},
	// Medium armor
	{Name: "Chainmail", Type: "medium", Rarity: RarityCommon, Defense: 7, SpeedModifier: 1.0},
	{Name: "Reinforced Mail", Type: "medium", Rarity: RarityUncommon, Defense: 10, SpeedModifier: 1.0},
	{Name: "Battle Armor", Type: "medium", Rarity: RarityRare, Defense: 15, SpeedModifier: 1.0, SetName: "Knight's Set", SpecialEffect: "def_bonus"},
	{Name: "Royal Guard", Type: "medium", Rarity: RarityEpic, Defense: 22, SpeedModifier: 1.0, SetName: "Knight's Set", SpecialEffect: "def_bonus"},
	{Name: "Crown of Eternity", Type: "medium", Rarity: RarityLegendary, Defense: 30, SpeedModifier: 1.0, SetName: "Knight's Set", SpecialEffect: "def_bonus"},
	// Heavy armor
	{Name: "Iron Plate", Type: "heavy", Rarity: RarityCommon, Defense: 14, SpeedModifier: 0.7, AgilityBonus: -3},
	{Name: "Steel Plate", Type: "heavy", Rarity: RarityUncommon, Defense: 20, SpeedModifier: 0.7, AgilityBonus: -3},
	{Name: "Fortress Armor", Type: "heavy", Rarity: RarityRare, Defense: 28, SpeedModifier: 0.7, AgilityBonus: -5, SetName: "Berserker's Set", SpecialEffect: "atk_bonus"},
	{Name: "Dragon Scale", Type: "heavy", Rarity: RarityEpic, Defense: 38, SpeedModifier: 0.7, AgilityBonus: -5, SetName: "Berserker's Set", SpecialEffect: "atk_bonus"},
	{Name: "Dragon Slayer", Type: "heavy", Rarity: RarityLegendary, Defense: 50, SpeedModifier: 0.7, AgilityBonus: -5, SetName: "Berserker's Set", SpecialEffect: "atk_bonus"},
	// Ancient Guardian's Set
	{Name: "Guardian's Plate", Type: "heavy", Rarity: RarityRare, Defense: 30, SpeedModifier: 0.7, AgilityBonus: 2, SetName: "Ancient Guardian's Set", SpecialEffect: "all_stats"},
	{Name: "Guardian's Bastion", Type: "heavy", Rarity: RarityEpic, Defense: 42, SpeedModifier: 0.7, AgilityBonus: 4, SetName: "Ancient Guardian's Set", SpecialEffect: "all_stats"},
	{Name: "Ancient Guardian's Aegis", Type: "heavy", Rarity: RarityLegendary, Defense: 55, SpeedModifier: 0.7, AgilityBonus: 6, SetName: "Ancient Guardian's Set", SpecialEffect: "all_stats"},
}

// legacyEquipmentFamily is the template used by the old equipment system.
type legacyEquipmentFamily struct {
	Name        string
	FormID      string
	BasePrimary int
	StatType    string
}

var legacyEquipmentFamilies = map[EquipmentSlot][]legacyEquipmentFamily{
	SlotHead: {
		{Name: "Leather Cap", FormID: "gear.form.head.cap", BasePrimary: 2, StatType: "defense"},
		{Name: "Iron Helmet", FormID: "gear.form.head.helmet", BasePrimary: 4, StatType: "defense"},
		{Name: "Crown", FormID: "gear.form.head.crown", BasePrimary: 3, StatType: "mixed"},
	},
	SlotFeet: {
		{Name: "Sandals", FormID: "gear.form.feet.sandals", BasePrimary: 1, StatType: "speed"},
		{Name: "Leather Boots", FormID: "gear.form.feet.boots", BasePrimary: 3, StatType: "defense"},
		{Name: "Iron Greaves", FormID: "gear.form.feet.greaves", BasePrimary: 5, StatType: "defense"},
	},
	SlotNeck: {
		{Name: "Wooden Pendant", FormID: "gear.form.neck.pendant", BasePrimary: 2, StatType: "mixed"},
		{Name: "Silver Amulet", FormID: "gear.form.neck.amulet", BasePrimary: 4, StatType: "attack"},
		{Name: "Crystal Necklace", FormID: "gear.form.neck.necklace", BasePrimary: 3, StatType: "defense"},
	},
	SlotHands: {
		{Name: "Leather Gloves", FormID: "gear.form.hands.gloves", BasePrimary: 2, StatType: "defense"},
		{Name: "Iron Gauntlets", FormID: "gear.form.hands.gauntlets", BasePrimary: 4, StatType: "defense"},
		{Name: "Dragonhide Gloves", FormID: "gear.form.hands.gloves", BasePrimary: 3, StatType: "mixed"},
	},
	SlotLegs: {
		{Name: "Leather Leggings", FormID: "gear.form.legs.leggings", BasePrimary: 2, StatType: "defense"},
		{Name: "Iron Greaves", FormID: "gear.form.legs.greaves", BasePrimary: 4, StatType: "defense"},
	},
	SlotCloak: {
		{Name: "Leather Cloak", FormID: "gear.form.cloak.cloak", BasePrimary: 2, StatType: "defense"},
		{Name: "Iron Cape", FormID: "gear.form.cloak.cape", BasePrimary: 4, StatType: "defense"},
		{Name: "Dragonhide Cloak", FormID: "gear.form.cloak.cloak", BasePrimary: 3, StatType: "mixed"},
	},
	SlotFinger: {
		{Name: "Wooden Ring", FormID: "gear.form.finger.ring", BasePrimary: 2, StatType: "mixed"},
		{Name: "Silver Ring", FormID: "gear.form.finger.ring", BasePrimary: 4, StatType: "attack"},
		{Name: "Crystal Ring", FormID: "gear.form.finger.ring", BasePrimary: 3, StatType: "defense"},
	},
	SlotWrist: {
		{Name: "Leather Bracers", FormID: "gear.form.wrist.bracers", BasePrimary: 2, StatType: "defense"},
		{Name: "Iron Wristguards", FormID: "gear.form.wrist.wristguards", BasePrimary: 4, StatType: "defense"},
		{Name: "Dragonhide Wristguards", FormID: "gear.form.wrist.wristguards", BasePrimary: 3, StatType: "mixed"},
	},
}
