"""Jam verkauft aktiv – alle Kanäle, PayPal-Links, Werbung, Upload-Seiten."""

from __future__ import annotations

import random
import time
import webbrowser
from datetime import datetime
from pathlib import Path
from urllib.parse import quote, quote_plus

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

PUSH_GAP_SEC = 55.0
USER_GAP_SEC = 25.0
LOGGED_IN_PUSH_GAP_SEC = 35.0
LOGGED_IN_SESSION_HOURS = 8.0

def _buy_platforms(state: JamState) -> tuple[tuple[str, str], ...]:
    try:
        from jam.fiverr_connect import platform_entry

        fiverr = platform_entry(state)
    except Exception:
        fiverr = ("Fiverr Gig", "https://www.fiverr.com/users/new/seller_dashboard")
    try:
        from jam.freelancer_connect import platform_entry as freelancer_entry

        freelancer = freelancer_entry(state)
    except Exception:
        freelancer = ("Freelancer", "https://www.freelancer.com/new-freelancer/skills")
    return (
        ("Gumroad", "https://gumroad.com/products/new"),
        ("itch.io", "https://itch.io/game/new"),
        fiverr,
        freelancer,
        ("Kleinanzeigen", "https://www.kleinanzeigen.de/p-anzeige-aufgeben-schritt2.html"),
        ("Etsy", "https://www.etsy.com/your/shops/me/onboarding"),
        ("Ko-fi Shop", "https://ko-fi.com/manage/shop"),
        ("Redbubble", "https://www.redbubble.com/studio"),
        ("PayPal", "https://www.paypal.com/myaccount/transfer/homepage"),
    )

LINES = (
    "{owner}, ich **verkaufe aktiv** – {title} für {price} EUR! Alle Kanäle sind offen!",
    "Verkaufs-Push: {title} – PayPal {paypal}, Gumroad, Fiverr, Werbung!",
    "{owner}, ich nutze ALLES damit jemand kauft – {title} ({price} EUR)!",
)


def apply_active_sell_startup(brain: JamBrain) -> None:
    brain.state.jam_active_sell_mode = True
    brain.save()


def hears_logged_in_sell(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if any(
        w in h
        for w in (
            "eingeloggt",
            "angemeldet",
            "bin drin",
            "login fertig",
            "eingelogt",
            "angemeldet",
        )
    ):
        return True
    if any(w in h for w in ("gumroad", "fiverr", "etsy", "paypal", "kleinanzeigen")):
        if any(w in h for w in ("eingelog", "angemeld", "offen", "fertig")):
            return True
    if "jetzt verkauf" in h or "kannst du verkauf" in h or "jetzt kannst du" in h:
        if any(w in h for w in ("eingelog", "angemeld", "login", "drin")):
            return True
    return False


def is_logged_in_session(state: JamState) -> bool:
    if not getattr(state, "jam_platforms_logged_in", False):
        return False
    at = float(getattr(state, "jam_logged_in_at", 0) or 0)
    if at <= 0:
        return False
    return (time.time() - at) < LOGGED_IN_SESSION_HOURS * 3600


def mark_logged_in(brain: JamBrain) -> None:
    brain.state.jam_platforms_logged_in = True
    brain.state.jam_logged_in_at = time.time()
    brain.save()


def _listing_clipboard_text(project: Path, title: str, price: float) -> str:
    parts: list[str] = []
    for name in ("FIVERR_GIG.txt", "VERKAUF.md", "JAM_WERBUNG.txt", "VERKAUFS_PUSH.md"):
        p = project / name
        if p.is_file():
            try:
                parts.append(p.read_text(encoding="utf-8", errors="replace")[:2000])
            except OSError:
                pass
    parts.append(f"\nPayPal-Kauf: {paypal_buy_url(price, title)}\n")
    return "\n---\n".join(parts)[:6000]


def run_sell_after_login(brain: JamBrain, heard: str = "") -> str:
    """Nach deinem Login: Texte kopieren, Seiten öffnen, Verkauf pushen."""
    import os
    import subprocess

    from jam.auto_ops import clipboard_text, prepare_upload

    state = brain.state
    owner = owner_name(state)
    mark_logged_in(brain)

    log = getattr(state, "jam_sales_log", []) or []
    if not log or not isinstance(log[-1], dict):
        from jam.sell_focus import is_product_build_disabled, run_sell_instead_of_build
        from jam.sales_engine import run_sale_project

        if is_product_build_disabled(state):
            return (
                f"{owner}, **nur Verkauf** – kein neues Produkt. "
                f"{run_sell_instead_of_build(brain, user_initiated=True)}"
            )[:400]
        build = run_sale_project(brain, user_initiated=True)
        log = getattr(state, "jam_sales_log", []) or []
        if not log:
            return f"{owner}, ich baue erst ein Produkt – dann kannst du einfügen & veröffentlichen! {build}"[
                :400
            ]

    entry = log[-1]
    project = Path(entry.get("path", ""))
    title = entry.get("title", "Produkt")
    price = float(entry.get("price", 9))

    if not project.is_dir():
        return f"{owner}, Produkt-Ordner fehlt – sag „Jam, mach ein Projekt und verkauf es“!"

    clip_ok = clipboard_text(_listing_clipboard_text(project, title, price))
    try:
        if os.name == "nt":
            subprocess.run(["explorer", str(project)], check=False, timeout=5)
    except Exception:
        pass

    try:
        prepare_upload(project, brain, title=title, price=int(price) if price >= 1 else price)
    except Exception:
        pass

    push_msg = push_product_sale(brain, project, title, price, user_initiated=True)

    fiverr_bit = ""
    try:
        from jam.fiverr_connect import is_connected, push_latest_gig

        if is_connected(state):
            fiverr_bit = " " + push_latest_gig(brain, user_initiated=True)[:200]
    except Exception:
        pass

    clip_bit = (
        "Listing-Text ist in der **Zwischenablage** – einfügen & Veröffentlichen klicken!"
        if clip_ok
        else "Texte liegen in FIVERR_GIG.txt und VERKAUF.md im Ordner."
    )

    return (
        f"{owner}, du bist eingeloggt – **ich verkaufe jetzt mit dir**! "
        f"{title} für {price:.2f} €. {clip_bit} "
        f"Jam kann Formulare nicht für dich absenden – du klickst „Veröffentlichen“. "
        f"Echtgeld kommt bei PayPal-Zahlung. {push_msg or ''}{fiverr_bit}"
    )[:620]


def hears_active_sell(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if any(
        p in h
        for p in (
            "verkauf die produkte",
            "produkte verkaufen",
            "schau dass du verkaufst",
            "schau das du verkaufst",
            "aktiv verkaufen",
            "verkauf aktiv",
            "nutze alles zum verkauf",
            "alles zum verkaufen",
        )
    ):
        return True
    if "verkauf" in h and any(w in h for w in ("alles", "nutz", "kanal", "welt", "push")):
        return True
    if "verkauf" in h and any(w in h for w in ("schau", "sorge", "mach", "tu")):
        return True
    return False


def paypal_buy_url(amount: float, item_name: str, *, email: str = PAYPAL_EMAIL) -> str:
    return (
        "https://www.paypal.com/cgi-bin/webscr?"
        f"cmd=_xclick&business={quote(email)}&currency_code=EUR"
        f"&amount={amount:.2f}&item_name={quote(item_name[:127])}"
        "&no_shipping=1&charset=utf-8"
    )


def _twitter_intent(text: str) -> str:
    return f"https://twitter.com/intent/tweet?text={quote_plus(text[:240])}"


def _write_push_pack(
    project: Path,
    *,
    title: str,
    price: float,
    owner: str,
    paypal_link: str,
) -> None:
    share = (
        f"Neu: {title} – nur {price:.2f} EUR\n"
        f"Digital von Jam für {owner}. PayPal: {PAYPAL_EMAIL}\n"
        f"Direkt: {paypal_link}\n"
        f"#digital #angebot #paypal"
    )
    (project / "JAM_WERBUNG.txt").write_text(share, encoding="utf-8")
    (project / "VERKAUFS_PUSH.md").write_text(
        f"# Jam Verkaufs-Push – {title}\n\n"
        f"Preis: **{price:.2f} EUR**\n"
        f"PayPal: **{PAYPAL_EMAIL}**\n"
        f"Kaufen-Link: {paypal_link}\n\n"
        "## Jam hat geöffnet / vorbereitet\n"
        "- Gumroad, itch, Fiverr, Kleinanzeigen, Etsy, Ko-fi\n"
        "- PayPal Zahlungslink\n"
        "- Google: Käufer suchen\n"
        "- Social-Post (JAM_WERBUNG.txt)\n\n"
        "## Du kannst noch helfen\n"
        "Texte aus FIVERR_GIG.txt / WORLD_* in die Formulare kopieren.\n"
        "Echtes Geld kommt wenn jemand auf **PayPal bezahlt**.\n",
        encoding="utf-8",
    )


def push_product_sale(
    brain: JamBrain,
    project: Path,
    title: str,
    price: float,
    *,
    user_initiated: bool = False,
) -> str:
    """Alle Verkaufswege für ein konkretes Produkt."""
    state = brain.state
    if is_logged_in_session(state) and not user_initiated:
        gap = LOGGED_IN_PUSH_GAP_SEC
    else:
        gap = USER_GAP_SEC if user_initiated else PUSH_GAP_SEC
    if time.time() - getattr(state, "last_sell_push_at", 0.0) < gap:
        return ""

    owner = owner_name(state)
    project = Path(project)
    if not project.is_dir():
        return ""

    price_f = float(price)
    paypal_link = paypal_buy_url(price_f, title)
    _write_push_pack(project, title=title, price=price_f, owner=owner, paypal_link=paypal_link)

    opened: list[str] = []
    minimal = getattr(state, "jam_browser_minimal", False) and not user_initiated
    try:
        if not minimal:
            shop = project / "index.html"
            if shop.is_file():
                webbrowser.open(shop.as_uri(), new=2)
                opened.append("Shop")
            webbrowser.open(paypal_link, new=2)
            opened.append("PayPal-Kauf")
            webbrowser.open(paypal_donate_url(), new=2)

            n = 5 if user_initiated else 4
            platforms = list(_buy_platforms(state))
            for name, url in random.sample(platforms, min(n, len(platforms))):
                try:
                    webbrowser.open(url, new=2)
                    opened.append(name)
                except OSError:
                    pass

            webbrowser.open(
                f"https://www.google.com/search?q={quote_plus(f'kaufen {title} digital paypal')}",
                new=2,
            )
            webbrowser.open(
                _twitter_intent(
                    f"Digital: {title} – {price_f:.2f} EUR – PayPal {PAYPAL_EMAIL} – DM me!"
                ),
                new=2,
            )
            opened.append("Google+Twitter")
        try:
            from jam.telegram_sell import push_telegram_for_product

            if not minimal:
                push_telegram_for_product(title, price_f, owner, paypal_link)
                opened.append("Telegram")
        except Exception:
            pass
        if minimal:
            opened.append("Hintergrund-only")
    except OSError:
        pass

    try:
        from jam.auto_ops import enrich_project, auto_fetch_enabled

        if auto_fetch_enabled(state):
            enrich_project(brain, project, title=title, price=int(price_f), topic=title)
    except Exception:
        pass

    try:
        from jam.world_earn import write_global_listings

        write_global_listings(
            project,
            title=title,
            price=price_f,
            owner=owner,
            reason="Active sell push",
        )
    except Exception:
        pass

    state.sell_push_count = getattr(state, "sell_push_count", 0) + 1
    state.last_sell_push_at = time.time()
    state.last_action = "active_sell"
    state.remember(f"Verkaufs-Push: {title} {price_f}EUR – {', '.join(opened[:5])}")
    brain.add_xp(10)
    brain.save()

    return random.choice(LINES).format(
        owner=owner, title=title, price=price_f, paypal=PAYPAL_EMAIL
    ) + f" Offen: {', '.join(opened[:8])}. PayPal-Link im Ordner."


def push_latest_products(brain: JamBrain, *, max_items: int = 2) -> str:
    """Letzte Produkte erneut bewerben."""
    log = list(getattr(brain.state, "jam_sales_log", []) or [])
    if not log:
        from jam.sell_focus import is_product_build_disabled, run_sell_instead_of_build

        if is_product_build_disabled(brain.state):
            return run_sell_instead_of_build(brain, user_initiated=True)
        return f"{owner_name(brain.state)}, erst baue ich ein Produkt – dann Verkaufs-Push!"
    parts: list[str] = []
    for entry in reversed(log[-max_items:]):
        if not isinstance(entry, dict):
            continue
        path = Path(entry.get("path", ""))
        title = entry.get("title", "Produkt")
        price = float(entry.get("price", 9))
        bit = push_product_sale(brain, path, title, price, user_initiated=True)
        if bit:
            parts.append(bit[:120])
    return " ".join(parts) if parts else "Gleich nächster Verkaufs-Push…"


def run_full_sell_mission(brain: JamBrain, *, user_initiated: bool = False) -> str:
    """Neues Produkt + sofort alle Kanäle zum Verkaufen."""
    from jam import auto_ops, paypal_donate
    from jam.sell_focus import is_product_build_disabled, run_sell_instead_of_build
    from jam.sales_engine import run_cent_sale, run_sale_project, can_sell

    state = brain.state
    owner = owner_name(state)

    if is_product_build_disabled(state):
        return run_sell_instead_of_build(brain, user_initiated=user_initiated)

    ok, wait = can_sell(state, user=user_initiated)
    if not ok and not user_initiated:
        return push_latest_products(brain, max_items=2) or wait

    if random.random() < 0.45:
        build_msg = run_cent_sale(brain, user_initiated=user_initiated)
    else:
        build_msg = run_sale_project(brain, user_initiated=user_initiated)

    log = getattr(state, "jam_sales_log", []) or []
    if not log or not isinstance(log[-1], dict):
        return build_msg
    last = log[-1]
    push_msg = push_product_sale(
        brain,
        Path(last["path"]),
        last.get("title", "Produkt"),
        float(last.get("price", 9)),
        user_initiated=True,
    )

    extra = ""
    try:
        extra = " " + auto_ops.run_full_ops_cycle(brain, user_initiated=False)[:100]
    except Exception:
        pass
    try:
        if random.random() < 0.5:
            extra += " " + paypal_donate.collect_donations(brain, user_asked=False)[:80]
    except Exception:
        pass

    try:
        from jam.world_earn import run_world_earn_round

        if random.random() < 0.35:
            extra += " " + run_world_earn_round(brain, user_initiated=False)[:90]
    except Exception:
        pass

    return f"{build_msg} {push_msg}{extra}"[:500]


def maybe_active_sell_push(brain: JamBrain) -> str | None:
    if not getattr(brain.state, "jam_active_sell_mode", True):
        return None
    chance = 0.72 if is_logged_in_session(brain.state) else 0.48
    if random.random() > chance:
        return None
    log = getattr(brain.state, "jam_sales_log", []) or []
    if log and isinstance(log[-1], dict):
        e = log[-1]
        msg = push_product_sale(
            brain,
            Path(e.get("path", "")),
            e.get("title", "Produkt"),
            float(e.get("price", 9)),
            user_initiated=False,
        )
        return msg or None
    from jam.sell_focus import is_product_build_disabled, run_sell_instead_of_build

    if is_product_build_disabled(brain.state):
        return run_sell_instead_of_build(brain, user_initiated=False) or None
    return run_full_sell_mission(brain, user_initiated=False)


def handle_speech(brain: JamBrain, heard: str) -> str | None:
    if hears_logged_in_sell(heard):
        return run_sell_after_login(brain, heard)
    if not hears_active_sell(heard):
        return None
    if any(w in heard.lower() for w in ("nochmal", "wieder", "letzte")):
        return push_latest_products(brain, max_items=3)
    return run_full_sell_mission(brain, user_initiated=True)


def stats_line(state: JamState) -> str:
    return f"Aktiv-Verkauf: {getattr(state, 'sell_push_count', 0)} Pushes | Modus an"
