#!/usr/bin/env python3
"""
LootForge: Procedural loot generation.
Level x Rarity x Affinity = Item. Deterministic. Seedable. O(1).

No dependencies. Pure Python.
"""
import random
import time

# === THE LATTICE: loot tables ===
RARITY_TIERS = {
    "common":    {"weight": 50, "color": "\033[90m", "stat_mult": 1.0},
    "uncommon":  {"weight": 25, "color": "\033[92m", "stat_mult": 1.5},
    "rare":      {"weight": 15, "color": "\033[96m", "stat_mult": 2.5},
    "epic":      {"weight": 7,  "color": "\033[95m", "stat_mult": 4.0},
    "legendary": {"weight": 2,  "color": "\033[93m", "stat_mult": 7.0},
    "mythic":    {"weight": 1,  "color": "\033[91m", "stat_mult": 12.0}
}

ITEM_BASES = {
    "sword":  {"base_dmg": 10, "base_spd": 5, "affinity": ["fire", "ice", "lightning", "holy", "dark"]},
    "axe":    {"base_dmg": 15, "base_spd": 2, "affinity": ["earth", "fire", "blood"]},
    "bow":    {"base_dmg": 8,  "base_spd": 8, "affinity": ["wind", "ice", "poison"]},
    "staff":  {"base_dmg": 12, "base_spd": 4, "affinity": ["arcane", "fire", "nature", "holy", "dark"]},
    "dagger": {"base_dmg": 6,  "base_spd": 10,"affinity": ["poison", "shadow", "blood"]},
    "mace":   {"base_dmg": 14, "base_spd": 3, "affinity": ["holy", "earth", "lightning"]},
    "spear":  {"base_dmg": 11, "base_spd": 5, "affinity": ["wind", "earth", "ice"]},
    "hammer": {"base_dmg": 18, "base_spd": 1, "affinity": ["earth", "fire", "lightning"]},
    "scythe": {"base_dmg": 13, "base_spd": 4, "affinity": ["dark", "blood", "shadow"]},
    "wand":   {"base_dmg": 5,  "base_spd": 12,"affinity": ["arcane", "nature", "ice"]}
}

PREFIXES = {
    "fire":     {"name": "Flame",      "stat": "dmg", "mult": 1.3, "desc": "burns foes"},
    "ice":      {"name": "Frost",      "stat": "spd", "mult": 1.2, "desc": "freezes foes"},
    "lightning":{"name": "Thunder",    "stat": "spd", "mult": 1.4, "desc": "shocks foes"},
    "holy":     {"name": "Divine",     "stat": "dmg", "mult": 1.2, "desc": "blesses wielder"},
    "dark":     {"name": "Shadow",     "stat": "dmg", "mult": 1.3, "desc": "curses foes"},
    "earth":    {"name": "Stone",      "stat": "dmg", "mult": 1.4, "desc": "crushes armor"},
    "wind":     {"name": "Gale",       "stat": "spd", "mult": 1.3, "desc": "swift strikes"},
    "poison":   {"name": "Venom",      "stat": "dmg", "mult": 1.1, "desc": "poisons foes"},
    "blood":    {"name": "Bloodletting","stat":"dmg", "mult": 1.5, "desc": "drains life"},
    "arcane":   {"name": "Arcane",     "stat": "dmg", "mult": 1.2, "desc": "mana flows"},
    "nature":   {"name": "Verdant",    "stat": "spd", "mult": 1.1, "desc": "nature aids"},
    "shadow":   {"name": "Umbral",     "stat": "spd", "mult": 1.2, "desc": "strikes from shadow"}
}

AFFINITY_PREFIX_LOOKUP = {}
for base, info in ITEM_BASES.items():
    for aff in info["affinity"]:
        AFFINITY_PREFIX_LOOKUP[(base, aff)] = aff

def roll_rarity(rng: random.Random) -> str:
    """O(1) rarity roll weighted by tier."""
    tiers = list(RARITY_TIERS.keys())
    weights = [RARITY_TIERS[t]["weight"] for t in tiers]
    return rng.choices(tiers, weights=weights, k=1)[0]

def roll_base(rng: random.Random) -> str:
    """O(1) base weapon roll."""
    return rng.choice(list(ITEM_BASES.keys()))

def roll_affinity(rng: random.Random, base: str) -> str:
    """O(1) affinity roll for the base."""
    affinities = ITEM_BASES[base]["affinity"]
    return rng.choice(affinities)

def generate_item(level: int, seed: int = None) -> dict:
    """O(1) item generation. Deterministic with seed."""
    rng = random.Random(seed) if seed is not None else random.Random()

    base = roll_base(rng)
    rarity = roll_rarity(rng)
    affinity = roll_affinity(rng, base)

    base_stats = ITEM_BASES[base]
    rarity_mult = RARITY_TIERS[rarity]["stat_mult"]
    level_mult = 1.0 + (level - 1) * 0.1
    prefix = PREFIXES[affinity]

    if prefix["stat"] == "dmg":
        damage = int(base_stats["base_dmg"] * rarity_mult * level_mult * prefix["mult"])
        speed = base_stats["base_spd"]
    else:
        damage = int(base_stats["base_dmg"] * rarity_mult * level_mult)
        speed = int(base_stats["base_spd"] * rarity_mult * level_mult * prefix["mult"])

    return {
        "name": f"{prefix['name']} {base.title()}",
        "rarity": rarity,
        "affinity": affinity,
        "level": level,
        "damage": damage,
        "speed": speed,
        "effect": prefix["desc"],
        "seed": seed
    }

# === DEMO ===
def demo():
    print("=" * 50)
    print("  LootForge: Procedural loot, O(1) generation")
    print("=" * 50)
    print()
    print("  Dropping 10 items at level 15...")
    print()

    for i in range(10):
        start = time.perf_counter_ns()
        item = generate_item(level=15, seed=42+i)
        elapsed = time.perf_counter_ns() - start

        rarity_color = RARITY_TIERS[item["rarity"]]["color"]
        reset = "\033[0m"
        print(f"  [{item['seed']}] {rarity_color}{item['rarity'].upper():10s}{reset} {item['name']:25s} "
              f"DMG:{item['damage']:4d} SPD:{item['speed']:3d} [{elapsed}ns]")

    print()
    print("=" * 50)
    print("  Same seed = same item. Deterministic. O(1).")
    print("=" * 50)

if __name__ == "__main__":
    demo()
