"""
Arbeitspeicher-Budget: Jam nutzt gezielt bis zu X % RAM (Standard 50 %).

Unter dem Ziel: mehr Hintergrund-Aktionen. Darüber: Jam bremst Playwright & Browser.
"""

from __future__ import annotations

import random
import time

from jam.brain import JamBrain, JamState
from jam.owner import owner_name

DEFAULT_TARGET = 0.5

LINES = (
    "{owner}, ich nutze jetzt **{pct:.0f} % Arbeitspeicher** – mehr Power wenn Platz ist, "
    "Pause wenn der PC voll wird!",
    "RAM-Modus **{pct:.0f} %** AN – Jam arbeitet stärker, solange genug Speicher frei ist.",
)


def hears_memory_budget(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if any(w in h for w in ("arbeitsspeicher", "arbeits speicher", " ram", "speicher")):
        if any(w in h for w in ("50", "prozent", "%", "halb", "nutz", "verwend", "nutzen")):
            return True
    if "50" in h and any(w in h for w in ("prozent", "%", "ram", "speicher", "arbeit")):
        return True
    if h.strip() in ("ja 50", "ja 50%", "ja50"):
        return True
    return False


def parse_memory_pct(text: str, default: float = DEFAULT_TARGET) -> float:
    h = text.lower()
    if "75" in h:
        return 0.75
    if "25" in h:
        return 0.25
    if "100" in h or "alles" in h:
        return 1.0
    if "50" in h or "halb" in h:
        return 0.5
    return default


def target_ram_pct(state: JamState) -> float:
    v = float(getattr(state, "jam_memory_target_pct", 0) or 0)
    if v <= 0:
        return DEFAULT_TARGET if getattr(state, "jam_memory_budget_on", False) else 1.0
    return max(0.1, min(1.0, v))


def system_memory_snapshot() -> tuple[float, float, float]:
    """Returns (used_pct 0-1, available_gb, total_gb)."""
    try:
        import psutil

        v = psutil.virtual_memory()
        return v.percent / 100.0, v.available / (1024**3), v.total / (1024**3)
    except Exception:
        return 0.5, 4.0, 8.0


def ram_work_factor(state: JamState) -> float:
    """
    >1 = Jam darf mehr parallel (noch unter RAM-Ziel).
    <1 = drosseln (System nah am Ziel oder drüber).
    """
    if not getattr(state, "jam_memory_budget_on", False):
        return 1.0
    used, _avail, _total = system_memory_snapshot()
    target = target_ram_pct(state)
    headroom = target - used
    if headroom > 0.12:
        return 1.0 + min(0.45, headroom * 2.5)
    if headroom > 0.02:
        return 1.0
    if used > target + 0.08:
        return 0.45
    return 0.72


def allow_heavy_task(state: JamState) -> bool:
    """Playwright / viele Browser nur wenn RAM-Budget passt."""
    if not getattr(state, "jam_memory_budget_on", False):
        return True
    used, avail, _ = system_memory_snapshot()
    target = target_ram_pct(state)
    if used > target + 0.1 and avail < 1.2:
        return False
    if used > target + 0.18:
        return False
    return random.random() < 0.85


def timer_speed_factor(state: JamState) -> float:
    """Für keep_awake: höher = kürzere Wartezeit zwischen Aktionen."""
    base = float(getattr(state, "jam_night_intensity", 1.0) or 1.0)
    base = max(0.1, min(1.0, base))
    return base * ram_work_factor(state)


def enable_memory_budget(
    brain: JamBrain,
    *,
    pct: float = 0.0,
    heard: str = "",
) -> str:
    state = brain.state
    owner = owner_name(state)
    target = pct if pct > 0 else parse_memory_pct(heard, DEFAULT_TARGET)

    state.jam_memory_budget_on = True
    state.jam_memory_target_pct = target
    state.jam_night_intensity = target
    state.jam_resource_mode = f"ram_{int(target * 100)}"
    state.remember(f"RAM-Modus {target:.0%}")
    state.last_action = "memory_budget"
    brain.add_xp(5)
    brain.save()

    used, avail, total = system_memory_snapshot()
    return (
        random.choice(LINES).format(owner=owner, pct=target * 100)
        + f" System: {used * 100:.0f} % belegt ({avail:.1f} GB frei von {total:.1f} GB). "
        f"Hintergrund & Fokus laufen mit **{target:.0%} Intensität**."
    )[:520]


def status_line(state: JamState) -> str:
    if not getattr(state, "jam_memory_budget_on", False):
        return ""
    used, avail, total = system_memory_snapshot()
    t = target_ram_pct(state) * 100
    return (
        f"RAM-Ziel: {t:.0f} % · System {used * 100:.0f} % · "
        f"{avail:.1f} GB frei · Faktor {ram_work_factor(state):.2f}"
    )


def apply_memory_budget_startup(brain: JamBrain) -> None:
    """Beim Jam-Start: RAM-Ziel aus State oder Standard 50 %."""
    import os

    state = brain.state
    env = os.environ.get("JAM_RAM_PCT", "").strip().replace("%", "")
    if env:
        try:
            enable_memory_budget(brain, pct=float(env) / 100.0)
            return
        except ValueError:
            pass
    if getattr(state, "jam_memory_budget_on", False) and float(
        getattr(state, "jam_memory_target_pct", 0) or 0
    ) > 0:
        return
    enable_memory_budget(brain, pct=DEFAULT_TARGET)


def handle_speech(brain: JamBrain, heard: str) -> str | None:
    if hears_memory_budget(heard):
        return enable_memory_budget(brain, heard=heard)
    return None
