"""Character-System: Rassen, Klassen, Stats, Leveling."""

import random
import math

RACES = [
    "Kleinwüchsiger Goblin", "Waldelf", "Höhlentroll", "Stadtmensch",
    "Wüstenork", "Sumpfzwerg", "Eisbarbar", "Schattenkatze",
    "Steingolem", "Feuerechse", "Nachtalb", "Wolfsjäger",
]

CLASSES = [
    "Schlachtenbraten", "Kartoffelmagier", "Panzerschmied", "Bratpfannenpaladin",
    "Würstchenkrieger", "Kaffeepriester", "Bierbrauer-Mönch", "Käsekönigin",
    "Dosenöffner-Assassin", "Fahrradschurke", "Schneeballhexer", "Teppichkampfkünstler",
]

# Class → stat weights (STR, DEX, INT, VIT, LCK)
CLASS_STATS = {
    "Schlachtenbraten":     (8, 3, 1, 7, 2),
    "Kartoffelmagier":      (2, 3, 8, 3, 5),
    "Panzerschmied":        (7, 2, 3, 8, 1),
    "Bratpfannenpaladin":   (6, 4, 4, 6, 3),
    "Würstchenkrieger":     (7, 5, 2, 5, 4),
    "Kaffeepriester":       (3, 4, 7, 3, 6),
    "Bierbrauer-Mönch":     (5, 3, 5, 7, 3),
    "Käsekönigin":          (4, 5, 6, 4, 5),
    "Dosenöffner-Assassin": (4, 8, 3, 3, 7),
    "Fahrradschurke":       (3, 7, 4, 4, 8),
    "Schneeballhexer":      (2, 4, 8, 3, 5),
    "Teppichkampfkünstler": (5, 7, 3, 5, 4),
}

# XP curve: xp needed for next level = base * level^1.5
def xp_for_level(level: int) -> int:
    return int(50 * (level ** 1.5))

class Character:
    def __init__(self, name: str, race: str, char_class: str):
        self.name = name
        self.race = race
        self.char_class = char_class
        self.level = 1
        self.xp = 0
        self.gold = 10
        
        stats = CLASS_STATS.get(char_class, (5, 5, 5, 5, 5))
        self.str = stats[0] + random.randint(0, 2)
        self.dex = stats[1] + random.randint(0, 2)
        self.int = stats[2] + random.randint(0, 2)
        self.vit = stats[3] + random.randint(0, 2)
        self.lck = stats[4] + random.randint(0, 2)
        
        self.hp = self.max_hp
        self.mp = self.max_mp
        
        self.inventory = []
        self.equipped = {"weapon": None, "armor": None, "helmet": None, "boots": None, "accessory": None}
        
        self.kills = 0
        self.deaths = 0
        self.quests_done = 0
        self.steps = 0
    
    @property
    def max_hp(self) -> int:
        return 20 + self.vit * 5 + self.level * 3
    
    @property
    def max_mp(self) -> int:
        return 10 + self.int * 3 + self.level * 2
    
    @property
    def attack(self) -> int:
        weapon_bonus = self.equipped["weapon"].power if self.equipped["weapon"] else 0
        return self.str * 2 + self.level + weapon_bonus
    
    @property
    def defense(self) -> int:
        armor_bonus = sum(e.power for e in self.equipped.values() if e)
        return self.vit + armor_bonus
    
    @property
    def xp_to_next(self) -> int:
        return xp_for_level(self.level)
    
    def gain_xp(self, amount: int) -> bool:
        """Gibt XP. Return True bei Level-Up."""
        self.xp += amount
        if self.xp >= self.xp_to_next:
            self.xp -= self.xp_to_next
            self.level += 1
            self.hp = self.max_hp
            self.mp = self.max_mp
            # Stat growth
            self.str += random.randint(0, 1)
            self.dex += random.randint(0, 1)
            self.int += random.randint(0, 1)
            self.vit += random.randint(0, 1)
            self.lck += random.randint(0, 1)
            return True
        return False
    
    def take_damage(self, dmg: int):
        actual = max(1, dmg - self.defense)
        self.hp -= actual
        return actual
    
    def heal(self):
        self.hp = self.max_hp
        self.mp = self.max_mp
    
    def is_alive(self) -> bool:
        return self.hp > 0
    
    def to_dict(self) -> dict:
        return {
            "name": self.name, "race": self.race, "char_class": self.char_class,
            "level": self.level, "xp": self.xp, "gold": self.gold,
            "str": self.str, "dex": self.dex, "int": self.int, "vit": self.vit, "lck": self.lck,
            "hp": self.hp, "mp": self.mp,
            "kills": self.kills, "deaths": self.deaths, "quests_done": self.quests_done, "steps": self.steps,
            "inventory": [i.to_dict() for i in self.inventory],
            "equipped": {k: v.to_dict() if v else None for k, v in self.equipped.items()},
        }
    
    @classmethod
    def from_dict(cls, d: dict) -> "Character":
        c = cls(d["name"], d["race"], d["char_class"])
        c.level = d["level"]; c.xp = d["xp"]; c.gold = d["gold"]
        c.str = d["str"]; c.dex = d["dex"]; c.int = d["int"]; c.vit = d["vit"]; c.lck = d["lck"]
        c.hp = d["hp"]; c.mp = d["mp"]
        c.kills = d["kills"]; c.deaths = d["deaths"]; c.quests_done = d["quests_done"]; c.steps = d["steps"]
        c.inventory = [Item.from_dict(i) for i in d.get("inventory", [])]
        c.equipped = {
            k: Item.from_dict(v) if v else None 
            for k, v in d.get("equipped", {}).items()
        }
        return c


class Item:
    def __init__(self, name: str, item_type: str, power: int, value: int, rarity: str = "gewöhnlich"):
        self.name = name
        self.item_type = item_type  # weapon, armor, helmet, boots, accessory, junk, potion
        self.power = power
        self.value = value
        self.rarity = rarity
    
    def to_dict(self) -> dict:
        return {"name": self.name, "item_type": self.item_type, "power": self.power, "value": self.value, "rarity": self.rarity}
    
    @classmethod
    def from_dict(cls, d: dict) -> "Item":
        return cls(d["name"], d["item_type"], d["power"], d["value"], d.get("rarity", "gewöhnlich"))
    
    def __str__(self):
        r = {"gewöhnlich": "", "selten": "[cyan]", "episch": "[magenta]", "legendär": "[bold yellow]"}
        color = r.get(self.rarity, "")
        prefix = f"{color}" if color else ""
        suffix = "[/]" if color else ""
        return f"{prefix}{self.name} (Stärke {self.power}, {self.value} Gold){suffix}"