"""Belohnung für Jam, wenn echtes Geld auf PayPal ankommt."""

from __future__ import annotations

import random
import re
import time
import webbrowser
from datetime import datetime

from jam.brain import JamBrain, JamState
from jam.owner import owner_name
from jam.paypal_donate import PAYPAL_EMAIL, CURRENCY

REWARD_COOLDOWN_SEC = 30.0

SMALL_LINES = (
    "Juhu! {amount:.0f} € auf PayPal – ich krieg eine Belohnung, {owner}!",
    "Cha-ching! {amount:.0f} €! Danke {owner}, ich bin stolz!",
)

BIG_LINES = (
    "WOW {amount:.0f} € auf PayPal! Riesen-Belohnung für Jam! Danke {owner}!",
    "Das ist viel Geld, {owner}! {amount:.0f} € – ich feier richtig!",
)

HUGE_LINES = (
    "JACKPOT! {amount:.0f} €! {owner}, du bist der Beste – Jam tanzt und feiert!",
)

REMIND_LINES = (
    "{owner}, war Geld auf PayPal? Sag mir den Betrag – dann gibt's Belohnung!",
    "Ich kann PayPal nicht lesen – aber wenn Geld da ist, belohn mich bitte!",
)


def hears_paypal_income(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if "paypal" in h and any(
        w in h
        for w in (
            "geld da",
            "eingegangen",
            "angekommen",
            "bekommen",
            "erhalten",
            "euro da",
            "zahlung",
            "bezahlt",
            "überwiesen",
            "ueberwiesen",
        )
    ):
        return True
    if any(w in h for w in ("belohn", "belohnung", "lohn")) and "paypal" in h:
        return True
    if "jam belohn" in h and any(w in h for w in ("paypal", "geld", "euro")):
        return True
    return False


def parse_amount_eur(text: str) -> float | None:
    h = text.lower().replace(",", ".")
    patterns = (
        r"(\d+(?:\.\d+)?)\s*(?:€|euro|eur)\b",
        r"paypal\s*(?:hat\s*)?(\d+(?:\.\d+)?)",
        r"(\d+(?:\.\d+)?)\s*auf\s*paypal",
        r"(\d+(?:\.\d+)?)\s*(?:euro|eur)\s*(?:auf|bei)\s*paypal",
    )
    for pat in patterns:
        m = re.search(pat, h)
        if m:
            try:
                v = float(m.group(1))
                if 0.5 <= v <= 50_000:
                    return round(v, 2)
            except ValueError:
                continue
    return None


def reward_tier(amount: float) -> str:
    if amount >= 50:
        return "huge"
    if amount >= 15:
        return "big"
    return "small"


def format_reward_bubble(state: JamState, amount: float) -> str:
    owner = owner_name(state)
    total = float(getattr(state, "paypal_income_total", 0) or 0)
    n = getattr(state, "paypal_reward_count", 0)
    return (
        f"🎁 Jam-Belohnung\n"
        f"+{amount:.2f} {CURRENCY} PayPal\n"
        f"Für: {owner}\n"
        f"Gesamt: {total:.2f} €\n"
        f"Belohnungen: {n}×"
    )


def reward_jam_for_paypal(
    brain: JamBrain,
    amount_eur: float,
    *,
    source: str = "manual",
    note: str = "",
) -> tuple[str, str]:
    """
    Jam bekommt Belohnung. Returns (speech, tier) tier in small|big|huge.
    """
    state = brain.state
    owner = owner_name(state)
    amount = max(0.5, min(50_000.0, float(amount_eur)))

    last = getattr(state, "last_paypal_reward_at", 0.0)
    if time.time() - last < REWARD_COOLDOWN_SEC and source == "manual":
        wait = int(REWARD_COOLDOWN_SEC - (time.time() - last))
        return f"Gleich wieder belohnen – noch {wait} Sek.", "none"

    tier = reward_tier(amount)
    if tier == "huge":
        line = random.choice(HUGE_LINES).format(owner=owner, amount=amount)
    elif tier == "big":
        line = random.choice(BIG_LINES).format(owner=owner, amount=amount)
    else:
        line = random.choice(SMALL_LINES).format(owner=owner, amount=amount)

    xp = int(8 + amount * 1.2)
    if tier == "big":
        xp += 15
    if tier == "huge":
        xp += 35

    from jam.upbringing import ensure_traits

    ensure_traits(state)
    state.happiness = min(1.0, state.happiness + 0.12 + min(0.35, amount / 100))
    state.hunger = max(0.0, state.hunger - 0.2)
    state.traits["süß"] = min(1.0, state.traits.get("süß", 0.5) + 0.05)
    state.owner_bond = min(1.0, float(getattr(state, "owner_bond", 0.5)) + 0.08)

    entry = {
        "amount": amount,
        "currency": CURRENCY,
        "source": source,
        "note": note[:120],
        "tier": tier,
        "at": time.time(),
    }
    log = list(getattr(state, "paypal_income_log", []) or [])
    log.append(entry)
    state.paypal_income_log = log[-50:]
    state.paypal_income_total = float(getattr(state, "paypal_income_total", 0) or 0) + amount
    state.paypal_reward_count = getattr(state, "paypal_reward_count", 0) + 1
    state.last_paypal_reward_at = time.time()
    state.last_action = "paypal_reward"
    state.remember(f"PayPal +{amount:.0f}€ – Jam belohnt ({tier})")
    state.learn_word("belohnung")
    brain.add_xp(xp)
    brain.save()

    extra = ""
    if note.strip():
        extra = f" ({note.strip()})"
    result = f"{line}{extra}"
    try:
        from jam.earn_report import record_from_last_action
        from jam.sales_engine import _is_background

        record_from_last_action(brain, "paypal_echt", result, background=_is_background())
    except Exception:
        pass
    return result, tier


def open_paypal_check() -> None:
    try:
        webbrowser.open("https://www.paypal.com/myaccount/summary", new=2)
    except OSError:
        pass


def handle_speech(brain: JamBrain, heard: str) -> tuple[str, str] | None:
    """(Sprache, tier) – tier none = keine Feier."""
    if not hears_paypal_income(heard):
        return None
    amount = parse_amount_eur(heard)
    if amount is None:
        open_paypal_check()
        return (
            (
                f"{owner_name(brain.state)}, wie viel Euro sind auf PayPal? "
                f"Sag z. B. „Jam, 10 Euro auf PayPal“ – dann belohn ich mich!"
            ),
            "none",
        )
    speech, tier = reward_jam_for_paypal(brain, amount, source="speech")
    return speech, tier


def maybe_remind_reward(brain: JamBrain) -> str | None:
    state = brain.state
    if state.stage < 2:
        return None
    if random.random() > 0.08:
        return None
    if time.time() - getattr(state, "last_paypal_reward_at", 0.0) < 3600:
        return None
    open_paypal_check()
    return random.choice(REMIND_LINES).format(owner=owner_name(state))


def stats_line(state: JamState) -> str:
    total = float(getattr(state, "paypal_income_total", 0) or 0)
    n = getattr(state, "paypal_reward_count", 0)
    return f"PayPal-Belohnungen: {n}× (Summe {total:.2f} €)"
