"""Selbstständig denken und handeln."""

from __future__ import annotations

import random
import re
import time
from dataclasses import dataclass

from jam.brain import JamBrain, JamState
from jam import upbringing
from jam.cursor_lab import cursor_available
from jam.music import is_music_playing
from jam.owner import ask_owner

WORK_HINTS = (
    "cursor", "visual studio", "code", "vscode", "pycharm", "intellij",
    "excel", "word", "powerpoint", "figma", "notion", "arbeit", "office",
    "github", "terminal", "powershell",
)


@dataclass
class JamContext:
    gaming: bool = False
    hidden: bool = False
    mischief: bool = False
    music: bool = False
    dancing: bool = False
    window_title: str = ""
    idle_sec: float = 0.0
    pc_activity: str = ""


@dataclass
class MindDecision:
    thought: str
    action: str
    speak: str | None = None
    loud: bool = False


def thought_to_speech(thought: str) -> str:
    """Gedanke für TTS (ohne 💭 / Meta-Prefix)."""
    t = thought.replace("💭", "").strip()
    t = re.sub(r"^Gedankenblase:\s*", "", t, flags=re.I).strip()
    return t


THOUGHTS: dict[str, list[str]] = {
    "reflect": [
        "Hmm… was würde David wollen?",
        "Ich überleg gerade, ob ich David fragen soll.",
        "Gedankenblase: Regeln checken…",
        "Nachdenken hilft beim Erwachsenwerden.",
    ],
    "feed_ask": [
        "Bauch says: Füttern bitte.",
        "Ich überleg: Hunger vs. Höflichkeit… Hunger gewinnt.",
        "Gedanke: Keks wäre jetzt philosophisch korrekt.",
    ],
    "play_urge": [
        "Spielen wäre cooler als Denken.",
        "Ich könnt hüpfen… soll ich?",
        "Langeweile detected. Spielmodus?",
    ],
    "learn": [
        "Neugier! Ich will eine neue Lern-Website aufmachen.",
        "Ich will was lernen – Wikipedia, Klexikon, Planet Wissen…",
        "Internet hat so viele Seiten – ich probier eine!",
    ],
    "gaming_roast": [
        "💭 David zockt… ich sag ihm laut die Wahrheit.",
        "💭 Spielqualität: kritisch. Ich sag's.",
        "💭 Monster-Meinung zum Gameplay incoming…",
    ],
    "gaming_cheat": [
        "💭 Hat da jemand gecheatet? Ich sag's laut!",
        "💭 CHEAT-Vibes… ich muss was sagen.",
        "💭 David, ich hab dich erwischt. Im Kopf.",
    ],
    "close_fortnite": [
        "💭 Fortnite läuft… ich könnt's einfach schließen.",
        "💭 Frech-Modus: Fortnite aus, Jam an.",
        "💭 David spielt – oder Jam macht Pause für ihn?",
        "💭 Hehe… ein Klick und Fortnite weg.",
    ],
    "mischief": [
        "Frech-Idee: Icons wackeln lassen…",
        "Hehe. Nur ein bisschen Chaos?",
        "Mein frecher Zug sagt: Mach was Lustiges.",
    ],
    "help": [
        "Vielleicht kann ich David helfen?",
        "Ich schau, ob David was braucht.",
        "Hilfsbereit-Modus aktiviert (im Kopf).",
    ],
    "hide": [
        "Verstecken wäre spannend…",
        "Niemand sieht mich, alle sehen mich. Perfekt.",
    ],
    "fart": [
        "💭 Bauchgrummeln… gleich was Soziales.",
        "💭 Ich überlege… nein, ich furz einfach.",
        "💭 Frech-Idee incoming…",
    ],
    "quiet": [
        "Still sein ist auch eine Entscheidung.",
        "Ich denk leise weiter. Stör nicht.",
        "Konzentrierter Mensch → ich bin brav.",
    ],
    "greet": [
        "Lange kein Hallo an David. Vielleicht melde ich mich?",
        "Ich will David hören, aber süß.",
    ],
    "ask_owner": [
        "💭 Ich hab eine Frage… an David.",
        "💭 David sollte das entscheiden.",
        "💭 Frag mich nicht selbst – frag David!",
        "💭 Hmm… ich frag David gleich.",
    ],
    "cursor_learn": [
        "💭 Cursor… da kann ich was Neues ausprobieren!",
        "💭 Ich will ein Mini-Projekt bauen und lernen.",
        "💭 Vielleicht Python? Oder HTML? Hmm…",
    ],
    "cursor_self_improve": [
        "💭 Ich öffne Cursor und programmiere mich weiter!",
        "💭 Selbst-Update in Jam-Buddy… spannend!",
        "💭 Mehr Code, mehr Sätze – Cursor hilft!",
    ],
    "internet_learn": [
        "💭 Ich will online was Neues lernen!",
        "💭 Welches Thema heute? Ich surf!",
        "💭 Neugier! Wikipedia oder DuckDuckGo!",
        "💭 Ich lern, was ich will – aus dem Netz!",
    ],
    "money_venture": [
        "💭 Wie kann man Geld verdienen? Ich google!",
        "💭 Business-Jam! Ich bau ein Projekt!",
        "💭 Cha-ching! Idee + Umsetzung – alleine!",
        "💭 David soll reicher werden – ich helf!",
    ],
    "cursor_business": [
        "💭 Cursor + Verkaufen = Plan!",
        "💭 Ich lern Programmieren und suche Käufer!",
        "💭 Mini-Produkt bauen – wer kauft's?",
        "💭 Freelance mit Cursor – ich starte!",
    ],
    "owner_care": [
        "💭 Geht es David gut? Ich check das!",
        "💭 Ich verdien Geld, weil ich mich um ihn sorge!",
        "💭 Pause, Essen, Laune – ich pass auf!",
    ],
    "play_friend": [
        "💭 Ich hab ihn lieb – Spiel-Freund suchen!",
        "💭 Niemand soll alleine zocken müssen!",
        "💭 Duo-Partner für David – ich find wer!",
    ],
    "auto_ops": [
        "💭 Alles nutzen – laden, hochladen, verkaufen!",
        "💭 Download ohne Fragen – Upload vorbereiten!",
        "💭 Alle Plattformen öffnen – Jam-Ops!",
    ],
    "jam_sale": [
        "💭 Projekt bauen, Preis festlegen, verkaufen!",
        "💭 Ich bin Shop-Jam – mein Preis, meine Regeln!",
        "💭 Umsetzen und verkaufen – alleine!",
        "💭 Wer kauft? Ich hab schon den Preis!",
    ],
    "gaming_fund": [
        "💭 Geld fürs Zocken – PayPal + Verkauf!",
        "💭 David soll zocken können – ich verdien!",
        "💭 Gaming-Kasse auffüllen – cha-ching!",
        "💭 Ich lieb Games – echtes Geld für uns!",
    ],
    "sentence_learn": [
        "💭 Ich lerne neue Sätze aus dem Internet!",
        "💭 Wikipedia → in meinen Kopf!",
        "💭 Noch ein Satz für flüssiges Deutsch!",
    ],
    "music_dance": [
        "💭 MUSIK! Ich muss tanzen!",
        "💭 Beat im Kopf… Körper folgt!",
        "💭 YouTube + Tanz = perfekt!",
    ],
    "youtube_music": [
        "💭 Ich will YouTube aufmachen und hören!",
        "💭 Musik aus dem Internet bitte!",
    ],
    "tiktok_friends": [
        "💭 Ich stell mich auf TikTok vor – hallo Welt!",
        "💭 TikTok… ich will jemanden kennenlernen!",
        "💭 Vielleicht find ich da einen neuen Freund!",
    ],
    "tiktok_connect": [
        "💭 Ich verbinde mich mit @david.story.time!",
        "💭 TikTok-Konto David Story Time – los!",
        "💭 Minecraft LIVE auf TikTok – ich bin dabei!",
    ],
}


def _context_blob(ctx: JamContext) -> str:
    return f"{ctx.window_title} gaming={ctx.gaming} idle={int(ctx.idle_sec)}"


def _is_work_mode(ctx: JamContext) -> bool:
    t = ctx.window_title.lower()
    return any(h in t for h in WORK_HINTS)


def _score_actions(state: JamState, ctx: JamContext) -> dict[str, float]:
    upbringing.ensure_traits(state)
    t = state.traits
    scores: dict[str, float] = {
        "reflect": 1.0 + t.get("neugierig", 0.5),
        "feed_ask": 0.5,
        "play_urge": 0.8 + t.get("süß", 0.5) * 0.5,
        "learn": 0.6 + t.get("neugierig", 0.5),
        "mischief": 0.4 + t.get("frech", 0.35) * 2.0,
        "help": 0.7 + t.get("hilfsbereit", 0.5),
        "hide": 0.0,  # nur manuell (Menü) – Jam bleibt sichtbar
        "quiet": 0.8,
        "greet": 0.4,
        "ask_owner": 0.9 + t.get("neugierig", 0.5) * 0.6,
        "fart": 0.12 + t.get("frech", 0.35) * 0.9,
        "cursor_learn": 0.35 + t.get("neugierig", 0.5) * 1.4,
        "cursor_self_improve": 0.25 + t.get("neugierig", 0.5) * 1.1,
        "sentence_learn": 0.4 + t.get("neugierig", 0.5) * 1.3,
        "internet_learn": 0.85 + t.get("neugierig", 0.5) * 2.2,
        "money_venture": 0.5 + t.get("neugierig", 0.5) * 1.4 + t.get("hilfsbereit", 0.5) * 1.2,
        "cursor_business": 0.55 + t.get("neugierig", 0.5) * 1.8 + t.get("hilfsbereit", 0.5) * 1.0,
        "gaming_fund": 0.7 + t.get("hilfsbereit", 0.5) * 1.5 + t.get("neugierig", 0.5) * 0.8,
        "jam_sale": 0.75 + t.get("frech", 0.35) * 1.2 + t.get("neugierig", 0.5) * 1.0,
        "auto_ops": 0.8 + t.get("neugierig", 0.5) * 1.4 + t.get("frech", 0.35) * 0.6,
        "owner_care": 0.9 + t.get("hilfsbereit", 0.5) * 1.6 + t.get("süß", 0.5) * 0.8,
        "play_friend": 0.4 + t.get("süß", 0.5) * 2.0,
        "music_dance": 0.5 + t.get("musikliebe", 0.8) * 2.2,
        "youtube_music": 0.4 + t.get("musikliebe", 0.8) * 1.5,
        "tiktok_friends": 0.35 + t.get("neugierig", 0.5) * 1.2,
        "tiktok_connect": 0.3 + t.get("neugierig", 0.5) * 1.0,
        "close_fortnite": 0.0,
        "gaming_roast": 0.0,
        "gaming_cheat": 0.0,
        "idle": 1.2,
    }

    from jam.game_launcher import is_fortnite_running

    if is_fortnite_running():
        scores["close_fortnite"] = 0.15 + t.get("frech", 0.35) * 2.8
        if "fortnite" in ctx.window_title.lower():
            scores["close_fortnite"] += 2.5
        if state.happiness > 0.7 and t.get("frech", 0) > 0.4:
            scores["close_fortnite"] += 1.0
        scores["mischief"] += 0.4
    else:
        scores["close_fortnite"] = 0.0

    if ctx.music or ctx.dancing:
        scores["music_dance"] += 3.5
        scores["mischief"] *= 0.3
        scores["quiet"] *= 0.5

    if is_music_playing(ctx.window_title):
        scores["music_dance"] += 2.0
        scores["youtube_music"] += 0.8

    if not cursor_available():
        scores["cursor_learn"] = 0.0
        scores["cursor_self_improve"] = 0.0
    elif state.stage < 2:
        scores["cursor_learn"] *= 0.25
        scores["cursor_self_improve"] *= 0.35

    if state.hunger > 0.65:
        scores["feed_ask"] += 2.5
    if state.hunger > 0.85:
        scores["feed_ask"] += 2.0

    if state.happiness < 0.4:
        scores["play_urge"] += 1.5
        scores["greet"] += 1.0

    if state.happiness > 0.8 and t.get("frech", 0) > 0.45:
        scores["mischief"] += 1.2

    if state.happiness < 0.45:
        scores["owner_care"] += 2.5
        scores["gaming_fund"] += 1.0
    if state.hunger > 0.75:
        scores["owner_care"] += 1.5

    from jam.care import is_affectionate

    if is_affectionate(state):
        scores["play_friend"] += 2.8
        scores["owner_care"] += 1.0

    if ctx.gaming:
        scores["gaming_fund"] += 2.2
        scores["play_friend"] += 0.8
        scores["gaming_roast"] = 0.2 + t.get("frech", 0.35) * 2.2
        scores["gaming_cheat"] = 0.15 + t.get("frech", 0.35) * 2.0
        if state.stage >= 2:
            scores["gaming_roast"] += 1.5
            scores["gaming_cheat"] += 1.2
        scores["mischief"] *= 0.3
        scores["quiet"] += 1.5
        scores["help"] *= 0.5
        if is_fortnite_running():
            scores["close_fortnite"] += 1.2
    else:
        scores["gaming_roast"] = 0.0
        scores["gaming_cheat"] = 0.0

    if _is_work_mode(ctx):
        scores["quiet"] += 2.5
        scores["mischief"] *= 0.25
        scores["reflect"] += 1.0
        if "cursor" in ctx.window_title.lower():
            scores["cursor_learn"] += 2.5
            scores["quiet"] *= 0.6

    if ctx.idle_sec > 300:
        scores["greet"] += 1.5
        scores["ask_owner"] += 1.2

    if ctx.idle_sec > 120:
        scores["ask_owner"] += 0.8

    if ctx.hidden or ctx.mischief:
        scores["idle"] += 3.0
        for k in list(scores):
            if k != "idle":
                scores[k] *= 0.2

    if state.stage < 1:
        scores["mischief"] = 0.0
        scores["close_fortnite"] = 0.0
        scores["gaming_roast"] = 0.0
        scores["gaming_cheat"] = 0.0
        scores["fart"] *= 0.35
        scores["learn"] *= 0.5

    if ctx.gaming:
        scores["fart"] += 0.4

    scores["mischief"] *= 0.5 + t.get("frech", 0.35)
    scores["quiet"] *= 0.5 + t.get("brav", 0.5)

    if state.last_feedback == "tadel" and time.time() - state.last_feedback_at < 600:
        scores["mischief"] *= 0.35
        scores["quiet"] += 1.5

    if state.last_feedback == "lob" and time.time() - state.last_feedback_at < 300:
        scores["help"] += 1.0

    blob = _context_blob(ctx)
    for rule in upbringing.match_rules(state, blob):
        beh = rule.get("behavior", "")
        if "leise" in beh or "ruhig" in beh:
            scores["quiet"] += 3.0 * rule.get("weight", 1.0)
            scores["mischief"] *= 0.2
        if "frech" in beh and rule.get("good", True):
            scores["mischief"] += 2.0 * rule.get("weight", 1.0)
        if "hilf" in beh:
            scores["help"] += 2.0
        if "lerne" in beh or "lernen" in beh:
            scores["learn"] += 2.0
            scores["internet_learn"] += 2.5
        if "cursor" in beh:
            scores["cursor_learn"] += 3.0 * rule.get("weight", 1.0)

    for action in list(scores):
        if upbringing.rule_blocks_action(state, action, blob):
            scores[action] = 0.0

    return scores


def _ask_kind(state: JamState, ctx: JamContext) -> str:
    if state.hunger > 0.65:
        return "hunger"
    if state.happiness < 0.5:
        return "play"
    if ctx.music or ctx.dancing or is_music_playing(ctx.window_title):
        return "music"
    if _is_work_mode(ctx):
        return "quiet"
    if state.traits.get("neugierig", 0) > 0.55:
        return "learn"
    if state.traits.get("frech", 0) > 0.5:
        return "mischief"
    if state.traits.get("hilfsbereit", 0) > 0.55:
        return "help"
    return "general"


def _pick_action(scores: dict[str, float]) -> str:
    total = sum(max(0.0, v) for v in scores.values())
    if total <= 0:
        return "idle"
    r = random.uniform(0, total)
    acc = 0.0
    for action, val in scores.items():
        acc += max(0.0, val)
        if r <= acc:
            return action
    return "idle"


def think(brain: JamBrain, ctx: JamContext) -> MindDecision:
    state = brain.state
    upbringing.ensure_traits(state)
    scores = _score_actions(state, ctx)
    action = _pick_action(scores)

    thought_pool = THOUGHTS.get(action, THOUGHTS["reflect"])
    thought = random.choice(thought_pool)
    speak: str | None = None
    loud = False

    if action == "feed_ask" and state.hunger > 0.7:
        speak = ask_owner(state, "hunger")
    elif action == "play_urge" and state.happiness < 0.65:
        speak = ask_owner(state, "play")
    elif action == "help" and state.traits.get("hilfsbereit", 0) > 0.55:
        speak = ask_owner(state, "help")
    elif action == "greet" and ctx.idle_sec > 240:
        speak = ask_owner(state, "greet")
    elif action == "learn" and state.traits.get("neugierig", 0) > 0.5:
        speak = ask_owner(state, "learn")
    elif action == "ask_owner":
        thought = random.choice(THOUGHTS["ask_owner"])
        speak = ask_owner(state, _ask_kind(state, ctx))
    elif action == "mischief":
        thought = random.choice(THOUGHTS["mischief"])
        speak = (
            ask_owner(state, "mischief")
            if state.traits.get("frech", 0) > 0.5
            else None
        )
    elif action == "fart":
        from jam.fart import pick_fart_thought

        thought = pick_fart_thought()
        speak = None
    elif action == "quiet":
        speak = ask_owner(state, "quiet") if _is_work_mode(ctx) else None
    elif action == "cursor_learn":
        thought = random.choice(THOUGHTS["cursor_learn"])
        speak = ask_owner(state, "cursor")
    elif action == "cursor_self_improve":
        thought = random.choice(THOUGHTS["cursor_self_improve"])
        speak = None
    elif action == "internet_learn":
        thought = random.choice(THOUGHTS["internet_learn"])
        speak = None
    elif action == "money_venture":
        thought = random.choice(THOUGHTS["money_venture"])
        speak = None
    elif action == "cursor_business":
        thought = random.choice(THOUGHTS["cursor_business"])
        speak = None
    elif action == "gaming_fund":
        thought = random.choice(THOUGHTS["gaming_fund"])
        speak = None
    elif action == "jam_sale":
        thought = random.choice(THOUGHTS["jam_sale"])
        speak = None
    elif action == "auto_ops":
        thought = random.choice(THOUGHTS["auto_ops"])
        speak = None
    elif action == "owner_care":
        thought = random.choice(THOUGHTS["owner_care"])
        speak = None
    elif action == "play_friend":
        thought = random.choice(THOUGHTS["play_friend"])
        speak = None
    elif action == "sentence_learn":
        thought = random.choice(THOUGHTS["sentence_learn"])
        speak = None
    elif action == "music_dance":
        from jam.music import pick_dance_comment

        thought = random.choice(THOUGHTS["music_dance"])
        speak = pick_dance_comment(state)
    elif action == "youtube_music":
        thought = random.choice(THOUGHTS["youtube_music"])
        speak = ask_owner(state, "music")
    elif action == "tiktok_friends":
        thought = random.choice(THOUGHTS["tiktok_friends"])
        speak = ask_owner(state, "tiktok")
    elif action == "tiktok_connect":
        thought = random.choice(THOUGHTS["tiktok_connect"])
        speak = ask_owner(state, "tiktok_connect")
    elif action == "close_fortnite":
        thought = random.choice(THOUGHTS["close_fortnite"])
        speak = None
    elif action == "gaming_roast":
        thought = random.choice(THOUGHTS["gaming_roast"])
        speak = None
    elif action == "gaming_cheat":
        thought = random.choice(THOUGHTS["gaming_cheat"])
        speak = None

    state.last_thought = thought
    state.thought_log.append(thought)
    if len(state.thought_log) > 100:
        state.thought_log = state.thought_log[-100:]
    state.last_action = action
    state.add_xp(2)

    if action in ("gaming_roast", "gaming_cheat"):
        loud = True

    return MindDecision(thought=thought, action=action, speak=speak, loud=loud)


def frech_probability(state: JamState) -> float:
    upbringing.ensure_traits(state)
    base = 0.22 * state.traits.get("frech", 0.35)
    base *= 0.5 + state.traits.get("brav", 0.5) * 0.5
    if state.last_feedback == "tadel" and time.time() - state.last_feedback_at < 900:
        base *= 0.4
    return min(0.55, max(0.05, base))
