"""Ollama LLM-Integration für dynamische Namen und Ereignisse."""

import httpx
import json
import random
import os

OLLAMA_URL = os.environ.get("OLLAMA_URL", "http://localhost:11434")
DEFAULT_MODEL = os.environ.get("OLLAMA_MODEL", "gemma4:12b")

# Fallback-Listen falls Ollama nicht erreichbar
FALLBACK_MONSTERS = [
    "Wütender Bratwurst-Golem", "Verirrter Bürokrat", "Sabbernder Höhlentroll",
    "Betrunkener Kartoffelgeist", "Kaffeeriese", "Einsamer Würstchenkobold",
    "Müder Bäcker-Ghoul", "Brüllender Dosenöffner", "Schlafender Schneeball",
    "Verzweifelter Parkplatzwächter", "Tanzen Milchgeist", "Rostiger Fahrraddämon",
    "Papiertiger aus Pankow", "Neuköllner Einkaufswagen", "Flüchtiger Socken-Golem",
    "Grammatik-Nazi aus Kreuzberg", "Mitternachts-Brötchen", "Heimtückischer Toaster",
]

FALLBACK_ITEMS = {
    "weapon": ["Rostige Bratpfanne", "Verbeulter Dosenöffner", "Alte Wurstzange", "Verbogenes Fahrrad-Pedal"],
    "armor": ["Kaffeefleck-Kettenhemd", "Pappkarton-Rüstung", "Mülltonnenschild", "Regenmantel des Grauens"],
    "helmet": ["Kochtopf mit Dellen", "Eimer mit Loch", "Tasse als Helm", "Plastik-Eimer"],
    "boots": ["Badeschlappen des Schreckens", "Holzschuhe mit Nagel", "Gummistiefel ohne Sohle"],
    "accessory": ["Rubberband der Macht", "Kaugummi-Kristall", "Wollmütze +2", "Fahrradklingel"],
    "junk": ["Alte Zeitung", "Leerer Kaffeebecher", "Heruntergefallenes Brötchen", "Verbogener Löffel"],
}

FALLBACK_QUESTS = [
    "Bringe 3 Würstchen zum Bürgermeister", "Finde den verlorenen Kaffeelöffel",
    "Befreie das Dorf von der Bratwurst-Plage", "Begleite die Schneeballhexe zum Markt",
    "Sammle 10 leere Pfandflaschen", "Besiege den Riesen-Gartenzwerg",
    "Befreie die gefangene Wurstware", "Finde den verschwundenen Dosenöffner",
    "Reinige die Küche der ewigen Fettflecken", "Begleite den alten Bierbrauer nach Hause",
]

FALLBACK_LOCATIONS = [
    "Neukölln bei Nacht", "Dem Schornstein hinterher", "Das ewige Baustellen-Nirwana",
    "Der Tresen der Verzweiflung", "Die große Kartoffel-Höhle", "Berlin Mitte im Stau",
    "Die Döner-Insel", "Die verlassene Wäscherei", "Der S-Bahn-Ring des Grauens",
]

def _clean_name(result: str) -> str:
    """Säubert LLM-Output: entfernt Metadaten, Anführungszeichen, überflüssige Wörter."""
    if not result:
        return ""
    # Remove metadata-like suffixes: _Wütend_Stufe5, _betrunken, etc.
    result = result.split("_")[0] if "_" in result and not result.startswith("_") else result
    # Remove common LLM preambles
    for prefix in ["Der Name lautet: ", "Name: ", "Monster: ", "Quest: ", "Ort: ", "Hier ist", "Das ist"]:
        if result.lower().startswith(prefix.lower()):
            result = result[len(prefix):]
    # Strip quotes, punctuation, whitespace
    result = result.strip('"\'.!?*#\n\r ')
    # Capitalize first letter
    if result:
        result = result[0].upper() + result[1:]
    return result

def _call_ollama(prompt: str, model: str = None, temperature: float = 0.9) -> str:
    """Ruft Ollama auf und gibt die Antwort als String zurück."""
    model = model or DEFAULT_MODEL
    try:
        with httpx.Client(timeout=30) as client:
            resp = client.post(f"{OLLAMA_URL}/api/generate", json={
                "model": model,
                "prompt": prompt,
                "stream": False,
                "think": False,
                "options": {"temperature": temperature, "num_predict": 60},
            })
            data = resp.json()
            return data.get("response", "").strip()
    except Exception as e:
        return ""


def generate_monster_name(player_level: int, location: str = "") -> str:
    """Generiert einen absurden Monsternamen auf Deutsch."""
    threat = random.choice(["lächerlich", "gefährlich", "müde", "wütend", "verwirrt", "betrunken", "verliebt", "niedergeschlagen"])
    prompt = f"""Du bist ein Generator für absurde deutsche RPG-Monster. Generiere EINEN kurzen, lustigen Monsternamen auf Deutsch.
Der Name soll absurd und komisch sein, wie ein Satire-RPG (Progress Quest).
Kombinationen wie "Bratwurst-Golem", "Bürokraten-Spinne", "Kartoffel-Drache" etc.
Das Monster ist {threat} und auf Stufe {player_level}.

Antworte NUR mit dem Namen, kein Satz, keine Erklärung, keine Anführungszeichen."""

    result = _call_ollama(prompt, temperature=1.0)
    result = _clean_name(result)
    if result and len(result) < 50:
        return result
    return random.choice(FALLBACK_MONSTERS)


def generate_item_name(item_type: str, player_level: int, rarity: str = "gewöhnlich") -> str:
    """Generiert einen absurden Item-Namen auf Deutsch."""
    prompt = f"""Du bist ein Generator für absurde deutsche RPG-Gegenstände. Generiere EINEN kurzen, lustigen Gegenstandsnamen auf Deutsch.
Typ: {item_type} (Waffe, Rüstung, Helm, Stiefel, Accessoire, Schrott)
Seltenheit: {rarity}
Stufe: {player_level}

Beispiele: "Rostige Bratpfanne", "Verbeulter Dosenöffner", "Kaffeefleck-Kettenhemd", "Badeschlappen des Schreckens".

Antworte NUR mit dem Namen, kein Satz, keine Erklärung, keine Anführungszeichen."""

    result = _call_ollama(prompt, temperature=1.0)
    result = _clean_name(result)
    if result and len(result) < 50:
        return result
    return random.choice(FALLBACK_ITEMS.get(item_type, FALLBACK_ITEMS["junk"]))


def generate_quest_name(player_level: int) -> str:
    """Generiert eine absurde Quest-Beschreibung auf Deutsch."""
    prompt = f"""Du bist ein Generator für absurde deutsche RPG-Quests (Progress Quest Stil).
Generiere EINE kurze, lustige Quest-Beschreibung auf Deutsch.
Stufe: {player_level}

Beispiele: "Bringe 3 Würstchen zum Bürgermeister", "Finde den verlorenen Kaffee", "Sammle 10 Pfandflaschen", "Besiege den Riesen-Gartenzwerg".

Antworte NUR mit der Quest, kein Satz, keine Erklärung, keine Anführungszeichen."""

    result = _call_ollama(prompt, temperature=1.0)
    result = _clean_name(result)
    if result and len(result) < 80:
        return result
    return random.choice(FALLBACK_QUESTS)


def generate_location_name() -> str:
    """Generiert einen absurden Ortsnamen auf Deutsch."""
    prompt = f"""Du bist ein Generator für absurde deutsche RPG-Orte (Progress Quest Satire).
Generiere EINEN kurzen, lustigen Ortsnamen auf Deutsch.

Beispiele: "Neukölln bei Nacht", "Die große Kartoffel-Höhle", "Berlin Mitte im Stau", "Die Döner-Insel".

Antworte NUR mit dem Ortsnamen, kein Satz, keine Erklärung, keine Anführungszeichen."""

    result = _call_ollama(prompt, temperature=1.0)
    result = _clean_name(result)
    if result and len(result) < 50:
        return result
    return random.choice(FALLBACK_LOCATIONS)


def generate_combat_text(monster: str, action: str = "attack") -> str:
    """Generiert eine kurze Kampfbeschreibung."""
    if action == "kill":
        return f"Besiegst {monster}!"
    elif action == "loot":
        return f"Durchwühlst die Überreste von {monster}..."
    else:
        return f"Greifst {monster} an..."


# Pre-generate cache to avoid calling LLM too often
class NameCache:
    def __init__(self):
        self.monsters = []
        self.items = {}
        self.quests = []
        self.locations = []
        self._initial_fill()
    
    def _initial_fill(self):
        """Füllt den Cache initial mit Fallback-Werten."""
        self.monsters = FALLBACK_MONSTERS.copy()
        self.quests = FALLBACK_QUESTS.copy()
        self.locations = FALLBACK_LOCATIONS.copy()
        for itype, names in FALLBACK_ITEMS.items():
            self.items[itype] = names.copy()
    
    def get_monster(self, level: int, location: str = "") -> str:
        if not self.monsters:
            self._initial_fill()
        name = self.monsters.pop(random.randint(0, len(self.monsters) - 1))
        return name
    
    def get_item(self, item_type: str, level: int, rarity: str = "gewöhnlich") -> str:
        names = self.items.get(item_type, FALLBACK_ITEMS.get(item_type, FALLBACK_ITEMS["junk"]))
        if not names:
            names = FALLBACK_ITEMS.get(item_type, FALLBACK_ITEMS["junk"])
        return names[random.randint(0, len(names) - 1)]
    
    def get_quest(self, level: int) -> str:
        if not self.quests:
            self._initial_fill()
        return self.quests.pop(random.randint(0, len(self.quests) - 1))
    
    def get_location(self) -> str:
        if not self.locations:
            self._initial_fill()
        return self.locations.pop(random.randint(0, len(self.locations) - 1))
    
    def refill_async(self):
        """Füllt den Cache im Hintergrund mit LLM-generierten Namen auf."""
        try:
            for _ in range(3):
                name = generate_monster_name(1)
                if name and name not in self.monsters:
                    self.monsters.append(name)
            for _ in range(2):
                name = generate_quest_name(1)
                if name and name not in self.quests:
                    self.quests.append(name)
            for _ in range(2):
                name = generate_location_name()
                if name and name not in self.locations:
                    self.locations.append(name)
            for itype in ["weapon", "armor", "helmet", "boots"]:
                name = generate_item_name(itype, 1)
                if name:
                    self.items.setdefault(itype, []).append(name)
        except:
            pass