"""Fortschritts-Quest — Automatisches RPG mit lokalem LLM."""

import os
import sys
import time
import random
import signal

# Add src to path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

from rich.console import Console
from rich.live import Live
from rich.layout import Layout
from rich.panel import Panel
from rich.table import Table
from rich.text import Text
from rich.progress import Progress, BarColumn, TextColumn
from rich.align import Align
from rich import box

from character import Character, RACES, CLASSES
from engine import GameEngine
from llm import NameCache

console = Console()
SAVE_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "saves")
os.makedirs(SAVE_DIR, exist_ok=True)

BANNER = """
[bold magenta]╔═══════════════════════════════════════════════════════════╗
║          FORTSCHRITTS-QUEST — Das automatische RPG        ║
║           "Wo du nichts tust und alles passiert"           ║
╚═══════════════════════════════════════════════════════════╝[/]
"""

def create_character():
    """Character-Erstellung mit Zufallsoption."""
    console.clear()
    console.print(BANNER)
    console.print("[bold]Character-Erstellung[/]\n")
    
    # Name
    name = console.input("[cyan]Name deines Helden (oder Enter für Zufall): [/]").strip()
    if not name:
        name = random.choice(["Günther", "Brigitte", "Klaus-Dieter", "Waltraud", "Herbert", "Sieglinde", "Wolfgang", "Margot"])
        console.print(f"[dim]Zufälliger Name: {name}[/]")
    
    # Race
    console.print("\n[bold]Verfügbare Rassen:[/]")
    for i, r in enumerate(RACES):
        console.print(f"  [cyan]{i+1}[/] — {r}")
    race_choice = console.input(f"\n[cyan]Rasse wählen (1-{len(RACES)}, Enter=Zufall): [/]").strip()
    if race_choice.isdigit() and 1 <= int(race_choice) <= len(RACES):
        race = RACES[int(race_choice) - 1]
    else:
        race = random.choice(RACES)
        console.print(f"[dim]Zufällige Rasse: {race}[/]")
    
    # Class
    console.print("\n[bold]Verfügbare Klassen:[/]")
    for i, c in enumerate(CLASSES):
        console.print(f"  [cyan]{i+1}[/] — {c}")
    class_choice = console.input(f"\n[cyan]Klasse wählen (1-{len(CLASSES)}, Enter=Zufall): [/]").strip()
    if class_choice.isdigit() and 1 <= int(class_choice) <= len(CLASSES):
        char_class = CLASSES[int(class_choice) - 1]
    else:
        char_class = random.choice(CLASSES)
        console.print(f"[dim]Zufällige Klasse: {char_class}[/]")
    
    char = Character(name, race, char_class)
    
    # Show summary
    console.print(f"\n[bold green]✅ Character erstellt![/]")
    console.print(f"  Name: [bold]{char.name}[/]")
    console.print(f"  Rasse: {char.race}")
    console.print(f"  Klasse: {char.char_class}")
    console.print(f"  Stufe: {char.level}")
    console.print(f"  HP: {char.hp}/{char.max_hp} | MP: {char.mp}/{char.max_mp}")
    console.print(f"  STR: {char.str} | DEX: {char.dex} | INT: {char.int} | VIT: {char.vit} | LCK: {char.lck}")
    console.print(f"  Gold: {char.gold}")
    console.input("\n[dim]Enter drücken um zu starten...[/]")
    
    return char


def render_game(engine: GameEngine) -> Panel:
    """Rendert das komplette Spiel-UI."""
    c = engine.character
    
    # === Character Panel ===
    char_table = Table(show_header=False, box=box.SIMPLE, padding=(0, 1))
    char_table.add_column("Stat", style="cyan", width=8)
    char_table.add_column("Value", style="bold")
    
    char_table.add_row("Name", f"{c.name}")
    char_table.add_row("Rasse", c.race)
    char_table.add_row("Klasse", c.char_class)
    char_table.add_row("Stufe", str(c.level))
    char_table.add_row("XP", f"{c.xp}/{c.xp_to_next}")
    char_table.add_row("HP", f"{c.hp}/{c.max_hp}")
    char_table.add_row("MP", f"{c.mp}/{c.max_mp}")
    char_table.add_row("Angriff", str(c.attack))
    char_table.add_row("Vert.", str(c.defense))
    char_table.add_row("Gold", f"{c.gold} 💰")
    char_table.add_row("Kills", str(c.kills))
    char_table.add_row("Tode", str(c.deaths))
    char_table.add_row("Quests", str(c.quests_done))
    
    # === Equipment Panel ===
    equip_table = Table(show_header=False, box=box.SIMPLE, padding=(0, 1), title="[bold]Ausrüstung[/]")
    equip_table.add_column("Slot", style="cyan", width=10)
    equip_table.add_column("Item")
    
    slot_names = {"weapon": "Waffe", "armor": "Rüstung", "helmet": "Helm", "boots": "Stiefel", "accessory": "Accessoire"}
    for slot, name in slot_names.items():
        item = c.equipped[slot]
        equip_table.add_row(name, str(item) if item else "[dim]leer[/]")
    
    # === Quest Panel ===
    quest_text = Text()
    quest_text.append(f"📜 {engine.current_quest}\n", style="cyan")
    quest_text.append(f"Fortschritt: {engine.quest_progress}/{engine.quest_target}", style="yellow")
    
    # === XP Bar ===
    xp_pct = c.xp / c.xp_to_next
    xp_bar_len = 20
    xp_filled = int(xp_pct * xp_bar_len)
    xp_bar = "█" * xp_filled + "░" * (xp_bar_len - xp_filled)
    
    # HP Bar
    hp_pct = c.hp / c.max_hp
    hp_filled = int(hp_pct * xp_bar_len)
    hp_bar = "█" * hp_filled + "░" * (xp_bar_len - hp_filled)
    
    # === Log Panel ===
    log_text = Text()
    for entry in engine.log[-12:]:
        if isinstance(entry, str):
            log_text.append(entry + "\n")
    
    # === Location ===
    loc_text = f"🌍 {engine.current_location}"
    
    # === Layout ===
    layout = Layout()
    
    # Top: Title bar
    layout.split_column(
        Layout(Panel(f"[bold magenta]FORTSCHRITTS-QUEST[/] — {c.name} der {c.race} {c.char_class}", 
                     style="magenta"), size=3),
        Layout(name="main"),
        Layout(name="bottom", size=8),
    )
    
    # Main: left=char/equip, center=log, right=quest/stats
    layout["main"].split_row(
        Layout(Panel(char_table, title="[bold]Character[/]"), name="left", size=30),
        Layout(Panel(log_text, title="[bold]Ereignis-Log[/]"), name="center"),
        Layout(name="right", size=30),
    )
    
    layout["right"].split_column(
        Layout(Panel(equip_table), name="equip"),
        Layout(Panel(quest_text, title="[bold]Aktuelle Quest[/]"), name="quest"),
    )
    
    # Bottom: bars + location
    bars = Text()
    bars.append(f"HP [{hp_bar}] {c.hp}/{c.max_hp}\n", style="red")
    bars.append(f"XP [{xp_bar}] {c.xp}/{c.xp_to_next}\n", style="green")
    bars.append(f"{loc_text}  |  Schritte: {c.steps}  |  STR {c.str} DEX {c.dex} INT {c.int} VIT {c.vit} LCK {c.lck}")
    
    layout["bottom"].update(Panel(bars, style="dim"))
    
    return layout


def run_game(engine: GameEngine, save_path: str):
    """Haupt-Game-Loop mit Live-Rendering."""
    auto_save_counter = 0
    
    with Live(render_game(engine), console=console, refresh_per_second=2, screen=True) as live:
        try:
            while True:
                # Game step
                result = engine.step()
                
                # Refill cache occasionally
                if engine.character.steps % 5 == 0:
                    engine.cache.refill_async()
                
                # Sell junk periodically
                if engine.character.steps % 10 == 0:
                    engine._sell_junk()
                
                # Auto-save every 50 steps
                auto_save_counter += 1
                if auto_save_counter >= 50:
                    engine.save(save_path)
                    auto_save_counter = 0
                
                # Render
                live.update(render_game(engine))
                
                # Speed — slower for readability, faster at higher levels
                speed = max(0.3, 1.5 - engine.character.level * 0.02)
                time.sleep(speed)
        
        except KeyboardInterrupt:
            live.update(render_game(engine))
            console.print("\n[bold yellow]Spiel pausiert.[/]")
            engine.save(save_path)
            console.print(f"[green]Spielstand gespeichert: {save_path}[/]")
            console.print("[dim]Drücke Enter zum Beenden...[/]")
            input()


def main():
    console.clear()
    console.print(BANNER)
    
    save_path = os.path.join(SAVE_DIR, "savegame.json")
    
    # Check for existing save
    if os.path.exists(save_path):
        choice = console.input("[cyan]Spielstand gefunden. Fortsetzen? (j/n): [/]").strip().lower()
        if choice in ("j", "ja", "y", "yes", ""):
            console.print("[green]Lade Spielstand...[/]")
            engine = GameEngine.load(save_path)
            console.print(f"[dim]Willkommen zurück, {engine.character.name} (Stufe {engine.character.level})![/]")
            time.sleep(1)
            run_game(engine, save_path)
            return
    
    # New game
    char = create_character()
    engine = GameEngine(char)
    run_game(engine, save_path)


if __name__ == "__main__":
    main()