"""
Auf Kunden zugehen: weltweit Werbung + Interessenten suchen + ansprechen.

Ablauf:
1. Jam findet, wer etwas brauchen könnte (Suche weltweit)
2. Jam schreibt Anschreiben (DE/EN) – noch kein Code
3. Kunde sagt ja → „Jam, Kunde will programmieren“ → dann baut Jam
"""

from __future__ import annotations

import json
import random
import re
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

OUTBOUND_ROOT = Path.home() / "Documents" / "Jam-Kunden-Ansprache-Welt"
AUTO_GAP_SEC = 100.0
USER_GAP_SEC = 40.0

# Was Leute oft suchen → Jam bietet es an (erst nach Zusage bauen)
PROSPECT_OFFERS: tuple[dict, ...] = (
    {
        "id": "python_script",
        "title": "Custom Python Script",
        "title_de": "Individuelles Python-Script",
        "need": "Automation, file sorting, small bot, API helper",
        "search_en": "need python developer small project",
        "search_de": "python programmierer kleinauftrag gesucht",
        "template": "python_utility",
        "range": (29, 79),
    },
    {
        "id": "landing_page",
        "title": "Landing Page / Mini Website",
        "title_de": "Landingpage / Mini-Webseite",
        "need": "Fast professional one-page site for business or launch",
        "search_en": "need web developer landing page urgent",
        "search_de": "webentwickler landingpage dringend gesucht",
        "template": "landing_page",
        "range": (59, 149),
    },
    {
        "id": "excel_auto",
        "title": "Excel / CSV Automation",
        "title_de": "Excel / CSV Automatisierung",
        "need": "Reports, less manual work, Python or scripts",
        "search_en": "excel automation freelancer needed",
        "search_de": "excel automatisierung programmierer gesucht",
        "template": "python_utility",
        "range": (35, 99),
    },
    {
        "id": "bugfix",
        "title": "Website Bugfix / Quick Fix",
        "title_de": "Website-Fehler schnell beheben",
        "need": "Broken layout, plugin, contact form, speed",
        "search_en": "website fix developer needed today",
        "search_de": "website fehler beheben programmierer heute",
        "template": "landing_page",
        "range": (39, 119),
    },
    {
        "id": "shop_paypal",
        "title": "PayPal Shop / Digital Sell Setup",
        "title_de": "PayPal-Shop / digital verkaufen",
        "need": "Sell digital product with PayPal, simple shop",
        "search_en": "help setup paypal digital product shop",
        "search_de": "paypal shop einrichten hilfe gesucht",
        "template": "python_utility",
        "range": (45, 109),
    },
)

# Wo man Leute findet, die etwas brauchen (Buyer-Intent)
PROSPECT_PLACES: tuple[tuple[str, str], ...] = (
    ("Google EN", "https://www.google.com/search?q={q}"),
    ("Google DE", "https://www.google.com/search?q={q}&hl=de"),
    ("Reddit forhire", "https://www.reddit.com/r/forhire/search/?q={q}&restrict_sr=1"),
    ("Reddit slavelabour", "https://www.reddit.com/r/slavelabour/search/?q={q}&restrict_sr=1"),
    ("Upwork Jobs", "https://www.upwork.com/nx/search/jobs/?q={q}"),
    ("Freelancer Projekte", "https://www.freelancer.com/jobs/{q_slug}/"),
)

WORLD_AD_CHANNELS: tuple[tuple[str, str], ...] = (
    ("Twitter/X Werbung", "https://twitter.com/intent/tweet?text={text}"),
    ("Telegram Share", "https://t.me/share/url?url={url}&text={text}"),
    ("LinkedIn Suche", "https://www.linkedin.com/search/results/content/?keywords={q}"),
)

LINES = (
    "{owner}, ich gehe **auf Kunden zu** – weltweit suchen, ansprechen, **erst bauen wenn sie ja sagen**!",
    "Outbound: {title} – Anschreiben fertig (DE+EN). Noch kein Code – smart für {owner}!",
)


def hears_outbound(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if any(
        w in h
        for w in (
            "kunden",
            "kunde",
            "anschreib",
            "ansprechen",
            "auf kunden",
            "zu gehen",
            "outbound",
            "interessent",
            "jemanden suchen",
            "suchen der",
            "wer etwas braucht",
        )
    ):
        return True
    if "welt" in h and any(w in h for w in ("werbung", "werben", "weit", "global")):
        if any(w in h for w in ("kunde", "suchen", "anschreib", "produkt")):
            return True
    if "erst ansprech" in h or "vorher anschreib" in h:
        return True
    if "bau" in h and "erst" in h and any(w in h for w in ("kunde", "wenn", "zusage")):
        return True
    return False


def is_outbound_mode(state: JamState) -> bool:
    return bool(getattr(state, "jam_outbound_sales_mode", False))


def _outreach_email_body(offer: dict, owner: str, price: float, lang: str) -> str:
    title = offer["title_de"] if lang == "de" else offer["title"]
    if lang == "de":
        return (
            f"Hallo,\n\n"
            f"ich bin Jam, Entwickler-Assistent für {owner}. "
            f"Ich habe gesehen, dass Sie vielleicht Hilfe bei **{title}** brauchen.\n\n"
            f"Wir können das für Sie bauen (Python / Web / Automatisierung) – "
            f"**erst nach Ihrer Zusage**, kein Risiko.\n\n"
            f"• Thema: {offer['need']}\n"
            f"• Richtpreis ab {price:.0f} EUR\n"
            f"• PayPal: {PAYPAL_EMAIL}\n"
            f"• Lieferung: schnell, DE/EN\n\n"
            f"Interesse? Antworten Sie kurz mit „ja“ oder was Sie genau brauchen – "
            f"dann legen wir los.\n\n"
            f"Viele Grüße\nJam / {owner}\n"
        )
    return (
        f"Hi,\n\n"
        f"I'm Jam, dev assistant for {owner}. You might need **{title}**.\n\n"
        f"We can build it (Python / web / automation) – **only after you confirm** – no upfront code dump.\n\n"
        f"• Scope: {offer['need']}\n"
        f"• From {price:.0f} EUR\n"
        f"• PayPal: {PAYPAL_EMAIL}\n"
        f"• Fast delivery, English & German\n\n"
        f"Interested? Reply with what you need – we start when you say yes.\n\n"
        f"Best,\nJam / {owner}\n"
    )


def _write_prospect_pack(
    project: Path,
    *,
    offer: dict,
    owner: str,
    price: float,
    price_reason: str,
    research: str,
) -> None:
    project.mkdir(parents=True, exist_ok=True)
    title_de = offer["title_de"]
    body_de = _outreach_email_body(offer, owner, price, "de")
    body_en = _outreach_email_body(offer, owner, price, "en")

    (project / "ANSCHREIBEN_DE.txt").write_text(body_de, encoding="utf-8")
    (project / "ANSCHREIBEN_EN.txt").write_text(body_en, encoding="utf-8")
    (project / "DM_KURZ.txt").write_text(
        f"Hi! Jam here – we can build {offer['title']} for you (~{price:.0f}€, PayPal). "
        f"Only after you say yes. Interested? – {owner}\n",
        encoding="utf-8",
    )
    (project / "STATUS.json").write_text(
        json.dumps(
            {
                "status": "prospekt_wartet_antwort",
                "offer_id": offer["id"],
                "title": offer["title"],
                "price": price,
                "template": offer["template"],
                "note": "Code wird erst gebaut wenn Kunde zusagt",
                "at": time.time(),
            },
            indent=2,
        ),
        encoding="utf-8",
    )
    (project / "index.html").write_text(
        f"""<!DOCTYPE html><html lang="de"><head><meta charset="utf-8">
<title>{title_de} – Anfrage</title></head><body style="font-family:system-ui;max-width:720px;margin:2rem auto">
<h1>{title_de}</h1>
<p><strong>Für:</strong> {owner} · Jam</p>
<p>{offer['need']}</p>
<p>Ab <strong>{price:.0f} €</strong> – {price_reason}</p>
<p>⚠️ <em>Wir bauen erst nach Ihrer Zusage.</em> PayPal: {PAYPAL_EMAIL}</p>
<p><a href="mailto:{PAYPAL_EMAIL}?subject={quote(title_de)}">Antworten</a></p>
</body></html>""",
        encoding="utf-8",
    )
    (project / "README.md").write_text(
        f"# Kunden-Ansprache – {title_de}\n\n"
        f"**Status:** Anschreiben fertig – **noch nicht programmiert**\n\n"
        f"## Jam Workflow\n"
        f"1. `ANSCHREIBEN_DE.txt` / `ANSCHREIBEN_EN.txt` → Reddit, Upwork, E-Mail, DM\n"
        f"2. Kunde antwortet JA → David sagt: **„Jam, Kunde will programmieren“**\n"
        f"3. Jam baut in Cursor (`template`: {offer['template']})\n"
        f"4. **„Jam, jetzt verkaufen“** → Auslieferung\n\n"
        f"Recherche: {research}\n",
        encoding="utf-8",
    )


def _open_prospect_searches(offer: dict, *, minimal: bool = False) -> list[str]:
    opened: list[str] = []
    queries = [
        offer["search_en"],
        offer["search_de"],
        f"{offer['title']} freelancer needed",
    ]
    n_places = 2 if minimal else 4
    for q in queries[:2]:
        for name, tpl in PROSPECT_PLACES[:n_places]:
            url = tpl.format(q=quote_plus(q), q_slug=quote_plus(q.replace(" ", "-")))
            try:
                webbrowser.open(url, new=2)
                opened.append(name)
            except OSError:
                pass
            time.sleep(0.35)
    return opened


def _world_ad_push(title: str, price: float, owner: str) -> list[str]:
    text_en = (
        f"Need {title}? We build it AFTER you confirm – from {price:.0f} EUR. "
        f"PayPal {PAYPAL_EMAIL} · Fast · DE/EN · Jam for {owner}"
    )
    text_de = (
        f"Brauchst du {title}? Wir bauen erst nach Zusage – ab {price:.0f} €. "
        f"PayPal {PAYPAL_EMAIL} · Jam für {owner}"
    )
    opened: list[str] = []
    try:
        webbrowser.open(
            WORLD_AD_CHANNELS[0][1].format(text=quote_plus(text_en[:240])),
            new=2,
        )
        opened.append("Twitter")
        webbrowser.open(
            WORLD_AD_CHANNELS[1][1].format(
                url=quote(f"mailto:{PAYPAL_EMAIL}", safe=""),
                text=quote_plus(text_en[:500]),
            ),
            new=2,
        )
        opened.append("Telegram")
        webbrowser.open(
            f"https://www.google.com/search?q={quote_plus('hire python developer remote paypal')}",
            new=2,
        )
        opened.append("Google Welt")
    except OSError:
        pass
    OUTBOUND_ROOT.mkdir(parents=True, exist_ok=True)
    (OUTBOUND_ROOT / "WELT_WERBUNG_EN.txt").write_text(text_en + "\n", encoding="utf-8")
    (OUTBOUND_ROOT / "WELT_WERBUNG_DE.txt").write_text(text_de + "\n", encoding="utf-8")
    return opened


def create_outbound_prospect(
    brain: JamBrain,
    *,
    user_initiated: bool = False,
) -> str:
    """Einen Interessenten-Kontakt vorbereiten – Anschreiben, keine Programmierung."""
    state = brain.state
    owner = owner_name(state)
    gap = USER_GAP_SEC if user_initiated else AUTO_GAP_SEC
    if time.time() - getattr(state, "last_outbound_at", 0.0) < gap:
        wait = int(gap - (time.time() - state.last_outbound_at))
        return f"Nächste Kunden-Ansprache in {wait} Sek."

    log = getattr(state, "jam_outbound_log", []) or []
    recent = [e.get("offer_id") for e in log[-5:] if isinstance(e, dict)]
    pool = [p for p in PROSPECT_OFFERS if p["id"] not in recent] or list(PROSPECT_OFFERS)
    offer = random.choice(pool)

    from jam.sales_engine import jam_decide_price
    from jam.urgent_offers import _research_need

    research = _research_need(
        {"search": offer["search_de"], "need": offer["need"]}
    )
    lo, hi = offer["range"]
    price, price_reason = jam_decide_price(
        state,
        lo=float(lo),
        hi=float(hi),
        title=offer["title_de"],
        difficulty=3,
        research=research,
    )

    stamp = datetime.now().strftime("%Y%m%d-%H%M%S")
    slug = re.sub(r"[^a-z0-9]+", "-", offer["id"])[:20]
    project = OUTBOUND_ROOT / f"{stamp}-{slug}"
    _write_prospect_pack(
        project,
        offer=offer,
        owner=owner,
        price=price,
        price_reason=price_reason,
        research=research,
    )

    minimal = getattr(state, "jam_browser_minimal", False) and not user_initiated
    opened = _open_prospect_searches(offer, minimal=minimal)

    try:
        body = (project / "ANSCHREIBEN_DE.txt").read_text(encoding="utf-8")
        webbrowser.open(
            f"mailto:?subject={quote('Angebot: ' + offer['title_de'])}&body={quote(body[:1800])}",
            new=2,
        )
    except OSError:
        pass

    try:
        from jam.auto_ops import clipboard_text

        clipboard_text(
            (project / "ANSCHREIBEN_EN.txt").read_text(encoding="utf-8")[:4000]
        )
    except Exception:
        pass

    entry = {
        "offer_id": offer["id"],
        "title": offer["title_de"],
        "path": str(project),
        "price": price,
        "status": "prospekt_wartet_antwort",
        "at": time.time(),
    }
    log.append(entry)
    state.jam_outbound_log = log[-40:]
    state.outbound_prospect_count = getattr(state, "outbound_prospect_count", 0) + 1
    state.last_outbound_at = time.time()
    state.last_action = "outbound_prospect"
    state.remember(f"Kunden-Ansprache: {offer['title_de']}")
    brain.add_xp(12)
    brain.save()

    return (
        random.choice(LINES).format(owner=owner, title=offer["title_de"])
        + f" Ordner: {project.name}. Anschreiben DE+EN fertig, **noch kein Code, keine E-Mail**. "
        f"Suche offen: {', '.join(opened[:5])}. "
        f"Wenn jemand JA sagt: „Jam, Kunde will programmieren“ – dann E-Mail + Bau. PayPal: {PAYPAL_EMAIL}"
    )[:680]


def run_world_outreach_mission(brain: JamBrain, *, user_initiated: bool = True) -> str:
    """Welt-Werbung + mehrere Ansprachen + Welt-Märkte."""
    from jam.world_earn import run_world_earn_round, write_global_listings

    owner = owner_name(brain.state)
    parts: list[str] = []

    try:
        parts.append(run_world_earn_round(brain, user_initiated=user_initiated)[:120])
    except Exception as e:
        parts.append(f"Welt: {e}"[:60])

    title, price, _ = _latest_sale(brain)
    _world_ad_push(title, price, owner)
    parts.append("Welt-Werbung EN/DE")

    for _ in range(2 if user_initiated else 1):
        parts.append(create_outbound_prospect(brain, user_initiated=user_initiated)[:100])
        time.sleep(1.0)

    try:
        log = getattr(brain.state, "jam_sales_log", []) or []
        if log and isinstance(log[-1], dict):
            proj = Path(log[-1].get("path", ""))
            if proj.is_dir():
                write_global_listings(
                    proj,
                    title=log[-1].get("title", "Jam"),
                    price=float(log[-1].get("price", 9)),
                    owner=owner,
                    reason="World outbound – build after customer yes",
                )
    except Exception:
        pass

    brain.state.jam_outbound_sales_mode = True
    brain.save()
    return (
        f"{owner}, **Welt-Mission**: Werbung + {2 if user_initiated else 1}× Kunden ansprechen – "
        f"erst bauen wenn sie zusagen! "
        + " | ".join(parts[:4])
    )[:680]


def _latest_sale(brain: JamBrain) -> tuple[str, float, str]:
    log = getattr(brain.state, "jam_sales_log", []) or []
    if log and isinstance(log[-1], dict):
        return (
            str(log[-1].get("title", "Jam Service")),
            float(log[-1].get("price", 49)),
            str(log[-1].get("path", "")),
        )
    return "Python & Web Hilfe", 49.0, ""


def enable_outbound_sales(brain: JamBrain) -> str:
    state = brain.state
    state.jam_outbound_sales_mode = True
    state.jam_world_earn_mode = True
    brain.save()
    return run_world_outreach_mission(brain, user_initiated=True)


def build_when_customer_says_yes(brain: JamBrain) -> str:
    """Verknüpft outbound mit urgent_offers build."""
    log = getattr(brain.state, "jam_outbound_log", []) or []
    customer_entry: dict | None = None
    for entry in reversed(log):
        if not isinstance(entry, dict):
            continue
        if entry.get("status") not in ("prospekt_wartet_antwort", "angeschrieben_wartet"):
            continue
        entry["status"] = "kunde_will_bauen"
        customer_entry = entry
        brain.state.jam_urgent_offers_log = list(
            getattr(brain.state, "jam_urgent_offers_log", []) or []
        ) + [
            {
                "offer_id": entry.get("offer_id", ""),
                "title": entry.get("title", ""),
                "path": entry.get("path", ""),
                "price": entry.get("price", 49),
                "status": "wartet_auf_kunde",
                "template": next(
                    (p["template"] for p in PROSPECT_OFFERS if p["id"] == entry.get("offer_id")),
                    "python_utility",
                ),
                "at": time.time(),
            }
        ]
        brain.save()
        break

    email_bit = ""
    if customer_entry:
        try:
            from jam.jam_auto_email import send_email_for_confirmed_customer

            email_bit = " " + send_email_for_confirmed_customer(
                brain, user_initiated=True, entry=customer_entry
            )[:280]
        except Exception as e:
            email_bit = f" E-Mail: {e}"[:50]

    from jam.urgent_offers import build_for_customer

    return (build_for_customer(brain, user_initiated=True) + email_bit)[:720]


def maybe_auto_outbound(brain: JamBrain) -> str | None:
    if not is_outbound_mode(brain.state):
        if not getattr(brain.state, "jam_money_all_in_mode", False):
            return None
    if time.time() - getattr(brain.state, "last_outbound_at", 0.0) < AUTO_GAP_SEC:
        return None
    if random.random() > 0.42:
        return None
    return create_outbound_prospect(brain, user_initiated=False)


def handle_speech(brain: JamBrain, heard: str) -> str | None:
    try:
        from jam.customer_contact import handle_speech as contact_speech

        hit = contact_speech(brain, heard)
        if hit:
            return hit
    except Exception:
        pass
    if not hears_outbound(heard):
        return None
    h = heard.lower()
    if any(w in h for w in ("kunde will", "kunde sagt", "hat ja gesagt", "will es")):
        return build_when_customer_says_yes(brain)
    if any(w in h for w in ("welt", "werbung", "global", "überall")):
        return run_world_outreach_mission(brain, user_initiated=True)
    return enable_outbound_sales(brain)


def status_line(state: JamState) -> str:
    n = getattr(state, "outbound_prospect_count", 0)
    pending = sum(
        1
        for e in (getattr(state, "jam_outbound_log", []) or [])
        if isinstance(e, dict)
        and e.get("status") in ("prospekt_wartet_antwort", "angeschrieben_wartet")
    )
    return f"Kunden-Ansprache: {n} Kontakte, {pending} warten auf Antwort"
