"""PC-Befehle ausführen und merken."""

from __future__ import annotations

import os
import subprocess
import webbrowser
from typing import Callable

from jam.brain import JamBrain
from jam import game_launcher

GAME_ACTION_PREFIX = "__game__:"
CLOSE_GAME_PREFIX = "__close_game__:"

BUILTIN: dict[str, str] = {
    "notepad": "notepad",
    "rechner": "calc",
    "taschenrechner": "calc",
    "explorer": "explorer",
    "cmd": "cmd",
    "pause": "pause",
}


def run_shell(command: str) -> tuple[bool, str]:
    try:
        from jam.pc_control import DENY_PATTERNS

        if DENY_PATTERNS.search(command):
            return False, "Zu gefährlich – Jam macht das nicht."
        if command.startswith("http"):
            webbrowser.open(command)
            return True, "Browser geöffnet."
        proc = subprocess.Popen(
            command,
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            creationflags=subprocess.CREATE_NO_WINDOW if os.name == "nt" else 0,
        )
        out, err = proc.communicate(timeout=30)
        msg = (out or err or "Fertig.").strip()[:300]
        return proc.returncode == 0, msg
    except subprocess.TimeoutExpired:
        return False, "Befehl hat zu lange gedauert."
    except OSError as e:
        return False, str(e)


def resolve_action(brain: JamBrain, phrase: str) -> str | None:
    key = phrase.strip().lower().replace("jam", "").strip()
    close_id = game_launcher.parse_close_phrase(key)
    if close_id:
        return f"{CLOSE_GAME_PREFIX}{close_id}"

    game_id = game_launcher.parse_game_name(key)
    if game_id:
        return f"{GAME_ACTION_PREFIX}{game_id}"

    if key in brain.state.learned_commands:
        return brain.state.learned_commands[key]
    for trigger, action in brain.state.learned_commands.items():
        if trigger in key:
            return action
    for word, cmd in BUILTIN.items():
        if word in key:
            return cmd

    for prefix in (
        "starte ",
        "start ",
        "öffne ",
        "oeffne ",
        "spiel ",
        "spiele ",
        "launch ",
    ):
        if key.startswith(prefix):
            target = key[len(prefix) :].strip()
            game_id = game_launcher.parse_game_name(target)
            if game_id:
                return f"{GAME_ACTION_PREFIX}{game_id}"
            if target in BUILTIN:
                return BUILTIN[target]
            return f"start {target}" if target else None

    if key.startswith("suche "):
        q = key[6:].strip()
        return f'start https://www.google.com/search?q={q.replace(" ", "+")}'
    return None


def execute_phrase(brain: JamBrain, phrase: str) -> str:
    action = resolve_action(brain, phrase)
    if not action:
        return "Das kenn ich noch nicht. Sag: Jam merke [phrase] als [befehl]"
    if action.startswith(CLOSE_GAME_PREFIX):
        return game_launcher.close_game(
            brain, action[len(CLOSE_GAME_PREFIX) :], user_asked=True
        )
    if action.startswith(GAME_ACTION_PREFIX):
        return game_launcher.launch_game(brain, action[len(GAME_ACTION_PREFIX) :])
    if action == "pause":
        return "Okay, ich pausiere kurz."
    ok, msg = run_shell(action)
    brain.state.add_xp(6 if ok else 1)
    brain.save()
    return f"{'Erledigt' if ok else 'Hmm'}: {msg}"
