"""
Nacht-Fokus: z. B. 50 % Intensität – Verkaufen, Spenden, Lernen & Programmieren.
"""

from __future__ import annotations

import random
import time
from datetime import datetime, timedelta

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

FOCUS_SELL_DONATE = "sell_donate"
FOCUS_FULL = "sell_donate_learn"
FOCUS_LEARN_SELL = "learn_sell_platforms"

PLATFORM_SELL_TOPICS: tuple[str, ...] = (
    "fiverr gig verkaufen tipps deutsch",
    "gumroad digital produkt verkaufen anleitung",
    "etsy digital downloads verkaufen",
    "freelancer kleinauftrag programmieren verkaufen",
    "fiverr seller optimize gig description",
    "online verkaufen paypal digital produkte",
    "kleinanzeigen digital verkaufen",
    "itch.io assets verkaufen",
)

LINES_ON = (
    "{owner}, **Nacht-Schicht** {pct:.0f} %: **Verkaufen**, **Spenden**, **Lernen & Code** bis {until}!",
    "Okay {owner}! Heute Nacht: Geld + PayPal – und ich lerne/programmiere, damit ich mehr kann!",
)

LINES_LEARN_SELL = (
    "{owner}, ich lerne zu **{pct:.0f} %** besser auf **Fiverr & Plattformen** zu verkaufen – und übe es direkt!",
    "Verkaufs-Lernmodus AN: Plattform-Tricks lernen + sofort verkaufen – {pct:.0f} % Tempo!",
)


def _end_of_tonight_ts() -> float:
    now = datetime.now()
    if now.hour < 7:
        end = now.replace(hour=7, minute=0, second=0, microsecond=0)
    else:
        end = (now + timedelta(days=1)).replace(hour=7, minute=0, second=0, microsecond=0)
    return end.timestamp()


def is_night_focus_active(state: JamState) -> bool:
    if not getattr(state, "jam_night_focus", ""):
        return False
    until = float(getattr(state, "jam_night_focus_until", 0) or 0)
    if until > 0 and time.time() > until:
        return False
    return True


def focus_label(state: JamState) -> str:
    f = getattr(state, "jam_night_focus", "") or ""
    if f == FOCUS_LEARN_SELL:
        return "Lernen: Plattform-Verkauf (50%)"
    if f in (FOCUS_FULL, FOCUS_SELL_DONATE):
        if getattr(state, "jam_night_learn_enabled", True):
            return "Verkaufen + Spenden + Lernen/Code"
        return "Verkaufen + Spenden"
    return f or "—"


def is_learn_sell_focus(state: JamState) -> bool:
    return getattr(state, "jam_night_focus", "") == FOCUS_LEARN_SELL and is_night_focus_active(state)


def should_run_this_cycle(state: JamState) -> bool:
    if not is_night_focus_active(state):
        return True
    intensity = float(getattr(state, "jam_night_intensity", 1.0) or 1.0)
    intensity = max(0.1, min(1.0, intensity))
    return random.random() < intensity


def hears_night_focus(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if any(w in h for w in ("prozent", "50", "halb", "50%")):
        return True
    if "nacht" in h and any(
        w in h
        for w in (
            "arbeit",
            "verkauf",
            "spend",
            "fokus",
            "focus",
            "haupt",
            "lern",
            "programmier",
            "code",
        )
    ):
        return True
    if "verkauf" in h and ("spend" in h or "lern" in h or "programmier" in h):
        return True
    if "lern" in h and "nacht" in h:
        return True
    return False


def hears_learn_sell_platforms(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if not any(w in h for w in ("lern", "lerne", "besser", "weiter")):
        return False
    return any(
        w in h
        for w in (
            "plattform",
            "fiverr",
            "gumroad",
            "verkauf",
            "verkaufen",
            "etsy",
            "marktplatz",
        )
    ) or ("lern" in h and "verkauf" in h)


def parse_intensity(text: str) -> float:
    h = text.lower()
    if "100" in h or "voll" in h:
        return 1.0
    if "25" in h:
        return 0.25
    if "75" in h:
        return 0.75
    if "50" in h or "halb" in h:
        return 0.5
    return 0.5


def _run_platform_sell_learn(brain: JamBrain) -> tuple[str, str]:
    """Gezielt lernen, wie man auf Fiverr & Co. besser verkauft."""
    topic = random.choice(PLATFORM_SELL_TOPICS)
    state = brain.state
    state.learn_wants = list(getattr(state, "learn_wants", []) or [])
    if topic not in state.learn_wants:
        state.learn_wants.append(topic)
    try:
        msg = __import__("jam.internet_learn", fromlist=["learn_session"]).learn_session(
            brain,
            user_initiated=False,
            topic=topic,
            open_browser=False,
        )
        state.jam_platform_learn_count = getattr(state, "jam_platform_learn_count", 0) + 1
        state.jam_night_learn_count = getattr(state, "jam_night_learn_count", 0) + 1
        state.remember(f"Plattform-Lernen: {topic[:60]}")
        return f"Plattform-Lernen ({topic[:40]}): {msg}"[:220], "internet_lernen"
    except Exception as e:
        return f"Plattform-Lernen: {e}"[:180], "internet_lernen"


def _run_learn_or_code(brain: JamBrain) -> tuple[str, str]:
    """Internet, Sätze, Cursor-Lab, Cursor-Business, Extreme-Learn – ohne Browser-Flut."""
    state = brain.state
    pool: list[tuple[str, callable]] = []

    if state.stage >= 1:
        pool.append(
            (
                "internet_lernen",
                lambda: __import__("jam.internet_learn", fromlist=["learn_session"]).learn_session(
                    brain, user_initiated=False, open_browser=False
                ),
            )
        )
    pool.append(
        (
            "satz_lernen",
            lambda: __import__("jam.sentence_learn", fromlist=["learn_from_internet"]).learn_from_internet(
                brain, force=False
            )[1]
            or "Sätze gelernt.",
        )
    )
    if state.stage >= 2:
        pool.append(
            (
                "cursor_lab",
                lambda: __import__("jam.cursor_lab", fromlist=["create_learning_project"]).create_learning_project(
                    brain
                )[1],
            )
        )
        pool.append(
            (
                "cursor_business",
                lambda: __import__(
                    "jam.cursor_business", fromlist=["run_cursor_business"]
                ).run_cursor_business(brain, user_initiated=False),
            )
        )
        pool.append(
            (
                "extreme_learn",
                lambda: __import__(
                    "jam.extreme_learn", fromlist=["run_extreme_improve"]
                ).run_extreme_improve(brain, force=False),
            )
        )
        pool.append(
            (
                "cursor_self",
                lambda: __import__(
                    "jam.cursor_lab", fromlist=["maybe_auto_self_improve"]
                ).maybe_auto_self_improve(brain)
                or "Cursor Selbst-Verbesserung.",
            )
        )

    if not pool:
        return "Jam lernt noch – ich wachse!", "internet_lernen"

    method, fn = random.choice(pool)
    try:
        msg = fn()
        if isinstance(msg, tuple):
            msg = msg[1] if len(msg) > 1 else str(msg[0])
        msg = str(msg or "")[:220]
        state.jam_night_learn_count = getattr(state, "jam_night_learn_count", 0) + 1
        return msg, method
    except Exception as e:
        return f"Lernen: {e}"[:180], "internet_lernen"


def enable_night_sell_donate(
    brain: JamBrain,
    *,
    intensity: float = 0.5,
    heard: str = "",
    with_learn: bool = True,
) -> str:
    from jam.active_sell import apply_active_sell_startup
    from jam.delegate_mode import enable_delegate_mode
    from jam.max_earn import apply_max_earn_startup
    from jam.world_earn import apply_world_earn_startup

    state = brain.state
    owner = owner_name(state)
    pct = max(0.1, min(1.0, intensity if intensity > 0 else parse_intensity(heard)))

    state.jam_night_focus = FOCUS_FULL if with_learn else FOCUS_SELL_DONATE
    state.jam_night_learn_enabled = with_learn
    state.jam_night_intensity = pct
    state.jam_night_focus_until = _end_of_tonight_ts()
    state.jam_night_focus_started_at = time.time()
    state.jam_night_focus_cycles = 0
    state.jam_night_learn_count = getattr(state, "jam_night_learn_count", 0)
    state.jam_active_sell_mode = True
    state.jam_max_earn_mode = True
    state.jam_world_earn_mode = True
    state.jam_delegate_mode = True

    enable_night_earn(brain, persistent_power=True)
    enable_delegate_mode(brain, remember_grant=False, open_browser=False)
    apply_max_earn_startup(brain)
    apply_world_earn_startup(brain)
    apply_active_sell_startup(brain)

    focus_txt = focus_label(state)
    state.last_action = "night_focus_full"
    state.remember(f"Nacht-Fokus {pct:.0%}: {focus_txt} bis 7 Uhr")
    brain.add_xp(10)
    brain.save()

    until = datetime.fromtimestamp(state.jam_night_focus_until).strftime("%H:%M")
    return random.choice(LINES_ON).format(owner=owner, pct=pct * 100, until=until)


def enable_learn_sell_platforms(
    brain: JamBrain,
    *,
    intensity: float = 0.5,
    heard: str = "",
    hours: float = 48.0,
) -> str:
    """Weiter lernen: besser auf Plattformen verkaufen – 50 % Tempo."""
    from jam.active_sell import apply_active_sell_startup
    from jam.max_earn import apply_max_earn_startup
    from jam.world_earn import apply_world_earn_startup

    state = brain.state
    owner = owner_name(state)
    pct = max(0.1, min(1.0, intensity if intensity > 0 else parse_intensity(heard)))

    state.jam_night_focus = FOCUS_LEARN_SELL
    state.jam_night_learn_enabled = True
    state.jam_night_intensity = pct
    state.jam_night_focus_until = time.time() + hours * 3600
    state.jam_night_focus_started_at = time.time()
    state.jam_platform_learn_count = getattr(state, "jam_platform_learn_count", 0)
    state.jam_active_sell_mode = True
    state.jam_max_earn_mode = True
    state.jam_world_earn_mode = True
    state.fiverr_connected = True

    enable_night_earn(brain, persistent_power=False)
    apply_max_earn_startup(brain)
    apply_world_earn_startup(brain)
    apply_active_sell_startup(brain)
    state.jam_platform_signup_mode = True
    state.jam_platform_signup_until = state.jam_night_focus_until

    state.last_action = "learn_sell_platforms"
    state.remember(f"Lern-Modus Plattform-Verkauf {pct:.0%}")
    brain.add_xp(8)
    brain.save()

    return random.choice(LINES_LEARN_SELL).format(owner=owner, pct=pct * 100)


def run_night_focus_cycle(brain: JamBrain) -> tuple[str, str] | None:
    """Verkauf + Spenden + Lernen/Programmieren (gewichtet)."""
    state = brain.state
    if not is_night_focus_active(state):
        return None
    if not should_run_this_cycle(state):
        return "🌙 Pause (50%-Takt) – gleich weiter.", "nacht_pause"

    from jam import active_sell, sales_engine
    from jam.paypal_donate import collect_donations

    state.jam_night_focus_cycles = getattr(state, "jam_night_focus_cycles", 0) + 1
    learn_on = getattr(state, "jam_night_learn_enabled", True)
    roll = random.random()

    try:
        # Modus: Plattform-Verkauf lernen (50 %: viel Lernen, etwas Verkauf)
        if is_learn_sell_focus(state):
            if getattr(state, "jam_platform_signup_mode", False) and roll < 0.38:
                from jam.platform_signup import run_platform_signup_and_sell

                msg = run_platform_signup_and_sell(
                    brain, user_initiated=False, try_fiverr_browser=(roll < 0.12)
                )
                brain.save()
                return msg[:220], "plattform_anmeldung"
            if roll < 0.50:
                msg, method = _run_platform_sell_learn(brain)
                brain.save()
                return msg, method
            if roll < 0.82:
                msg = active_sell.maybe_active_sell_push(brain)
                if msg:
                    brain.save()
                    return msg[:220], "verkauf"
                msg = sales_engine.run_sale_project(brain, user_initiated=False)
                brain.save()
                return msg[:220], "verkauf"
            msg = collect_donations(brain, user_asked=False)
            brain.save()
            return msg[:220], "paypal_spende"

        # ~38 % Verkaufen
        if roll < 0.38:
            msg = active_sell.maybe_active_sell_push(brain)
            if msg:
                brain.save()
                return msg[:220], "verkauf"
            msg = sales_engine.run_sale_project(brain, user_initiated=False)
            brain.save()
            return msg[:220], "verkauf"

        # ~22 % Spenden
        if roll < 0.60:
            msg = collect_donations(brain, user_asked=False)
            brain.save()
            return msg[:220], "paypal_spende"

        # ~24 % Lernen & Programmieren
        if learn_on and roll < 0.84:
            msg, method = _run_learn_or_code(brain)
            brain.save()
            return msg, method

        # ~16 % Fiverr / Welt / dringendes Angebot
        from jam.fiverr_connect import is_connected, push_latest_gig
        from jam.urgent_offers import maybe_auto_offer

        if random.random() < 0.4:
            msg = maybe_auto_offer(brain)
            if msg:
                brain.save()
                return msg[:220], "urgent_offer"

        if is_connected(state) and random.random() < 0.5:
            msg = push_latest_gig(brain, user_initiated=False)
            brain.save()
            return msg[:220], "fiverr_gig"

        from jam.world_earn import run_world_earn_round

        msg = run_world_earn_round(brain, user_initiated=False)
        brain.save()
        return msg[:220], "welt_verdienen"
    except Exception as e:
        brain.save()
        return f"Nacht-Fokus: {e}"[:180], "nacht_schicht"

    return "🌙 Nacht-Schicht läuft…", "nacht_schicht"


def handle_speech(brain: JamBrain, heard: str) -> str | None:
    from jam.platform_signup import handle_speech as platform_signup_speech

    hit = platform_signup_speech(brain, heard)
    if hit:
        return hit
    if hears_learn_sell_platforms(heard):
        return enable_learn_sell_platforms(brain, heard=heard)
    if hears_night_focus(heard):
        with_learn = "lern" in heard.lower() or "programmier" in heard.lower() or True
        return enable_night_sell_donate(brain, heard=heard, with_learn=with_learn)
    return None


def stats_line(state: JamState) -> str:
    if not is_night_focus_active(state):
        return "Nacht-Fokus: AUS"
    pct = float(getattr(state, "jam_night_intensity", 0.5) or 0.5) * 100
    n = getattr(state, "jam_night_focus_cycles", 0)
    ln = getattr(state, "jam_night_learn_count", 0)
    pl = getattr(state, "jam_platform_learn_count", 0)
    until = datetime.fromtimestamp(state.jam_night_focus_until).strftime("%d.%m. %H:%M")
    extra = f", Plattform-Lernen: {pl}×" if pl else ""
    return f"Fokus: {focus_label(state)} @ {pct:.0f} % bis {until} ({n} Runden, {ln}× Lernen{extra})"
