"""Jam lernt aus dem Internet immer mehr ganze Sätze und nutzt sie beim Sprechen."""

from __future__ import annotations

import random
import re
import time

import requests

from jam.brain import JamBrain, JamState

WIKI_RANDOM = "https://de.wikipedia.org/api/rest_v1/page/random/summary"
TIMEOUT = 10
MIN_LEARN_GAP_SEC = 40.0
MAX_STORED_SENTENCES = 500

# Einfache Satz-Schablonen aus gelernten Wörtern
COMPOSE_TEMPLATES = (
    "Ich habe im Internet gelesen: {snippet}",
    "Neu für mich: {snippet}",
    "Aus dem Netz gelernt – {snippet}",
    "Boah, {word} – das steht in meinem Kopf!",
    "Jam lernt Deutsch: {snippet}",
    "Wusstest du? {snippet}",
    "{owner}, ich kann jetzt sagen: {snippet}",
)

GERMAN_WORD = re.compile(r"\b(der|die|das|und|ist|ein|eine|nicht|auch|mit|für|auf|als|wird|sich)\b", re.I)


def _looks_german(text: str) -> bool:
    if not text or len(text) < 12:
        return False
    if "http" in text.lower() or "www." in text.lower():
        return False
    if sum(1 for c in text if c.isalpha()) < 8:
        return False
    return bool(GERMAN_WORD.search(text)) or any(c in text for c in "äöüÄÖÜß")


def split_sentences(text: str, *, max_count: int = 6) -> list[str]:
    text = re.sub(r"<[^>]+>", "", text)
    text = re.sub(r"\s+", " ", text).strip()
    if not text:
        return []
    parts = re.split(r"(?<=[.!?])\s+", text)
    out: list[str] = []
    for p in parts:
        p = p.strip()
        if 18 <= len(p) <= 220 and _looks_german(p):
            if not p.endswith((".", "!", "?")):
                p += "."
            out.append(p)
        if len(out) >= max_count:
            break
    return out


def fetch_sentences_from_web(topic: str | None = None) -> list[str]:
    from jam.internet_learn import fetch_from_internet

    _label, sentences, _url = fetch_from_internet(topic)
    return sentences


def get_learned_sentences(state: JamState) -> list[str]:
    return list(getattr(state, "learned_sentences", None) or [])


def remember_sentences(state: JamState, sentences: list[str]) -> int:
    pool = get_learned_sentences(state)
    added = 0
    for s in sentences:
        key = s.strip()
        if not key or key in pool:
            continue
        pool.append(key)
        added += 1
        for word in re.findall(r"[A-Za-zÄÖÜäöüß]{5,}", key)[:4]:
            state.learn_word(word.lower())
    if added:
        state.learned_sentences = pool[-MAX_STORED_SENTENCES:]
        state.sentence_learn_count = getattr(state, "sentence_learn_count", 0) + added
        state.last_sentence_learn = time.time()
    return added


def can_learn_sentences(state: JamState) -> bool:
    last = getattr(state, "last_sentence_learn", 0.0)
    return time.time() - last >= MIN_LEARN_GAP_SEC


def learn_from_internet(brain: JamBrain, *, force: bool = False) -> tuple[int, str | None]:
    """
    Holt Sätze aus dem Netz und speichert sie.
    Returns (Anzahl neu, optional Kurz-Meldung).
    """
    if not force and not can_learn_sentences(brain.state):
        return 0, None
    sentences = fetch_sentences_from_web()
    if not sentences:
        return 0, None
    n = remember_sentences(brain.state, sentences)
    if n:
        brain.state.remember(f"Neue Sätze ({n}): {sentences[0][:80]}")
        brain.add_xp(4 + n)
        brain.save()
        return n, sentences[0]
    return 0, None


def compose_from_learned(state: JamState) -> str | None:
    """Eigenen Satz aus Gelerntem zusammensetzen."""
    pool = get_learned_sentences(state)
    if not pool:
        return None
    snippet = random.choice(pool)
    if len(snippet) > 160:
        snippet = snippet[:157].rsplit(" ", 1)[0] + "…"
    words = getattr(state, "learned_words", None) or []
    word = random.choice(words) if words else "Wissen"
    from jam.owner import owner_name

    tpl = random.choice(COMPOSE_TEMPLATES)
    return tpl.format(snippet=snippet, word=word, owner=owner_name(state))


def pick_line_for_speech(state: JamState) -> str:
    """Zufallszeile – bevorzugt gelernte Internet-Sätze."""
    pool = get_learned_sentences(state)
    if pool:
        weight = min(0.72, 0.2 + len(pool) * 0.004)
        if random.random() < weight:
            if random.random() < 0.35:
                composed = compose_from_learned(state)
                if composed:
                    return composed
            line = random.choice(pool)
            if len(line) > 200:
                line = line[:197].rsplit(" ", 1)[0] + "…"
            return line
    from jam.speech import random_line

    return random_line(state)


def maybe_auto_learn(brain: JamBrain) -> str | None:
    from jam.internet_learn import maybe_auto_learn as curiosity_learn

    return curiosity_learn(brain)


def stats_line(state: JamState) -> str:
    n = len(get_learned_sentences(state))
    c = getattr(state, "sentence_learn_count", 0)
    return f"Gelernte Sätze: {n} (insgesamt {c} aus dem Netz)"
