"""
E-Mail nur wenn Jam einen echten Kunden hat (Zusage), nicht bei kalten Prospects.

Ablauf: Prospect = Anschreiben im Ordner, keine E-Mail. Kunde sagt ja → E-Mail schreiben + Gmail.
"""

from __future__ import annotations

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

ROOT = Path(__file__).resolve().parent.parent
EMAIL_LOG = ROOT / "data" / "jam-email.log"
AUTO_GAP_SEC = 120.0
USER_GAP_SEC = 35.0

# Prospect wartet; ab Zusage darf Jam E-Mail erstellen/versenden
PROSPECT_STATUSES = frozenset({"prospekt_wartet_antwort", "angeschrieben_wartet"})
CUSTOMER_STATUSES = frozenset({"kunde_will_bauen", "kunde_bestaetigt"})

LINES = (
    "{owner}, ich habe eine **E-Mail geschrieben** und über **Jam Browser / Gmail** verschickt "
    "(oder Entwurf + Send versucht) – für jemanden der **{need}** braucht.",
    "E-Mail raus: Thema „{title}“ – Jam hat selbst geschrieben und abgeschickt. PayPal: {paypal}",
)


def hears_auto_email(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if "email" in h or "e-mail" in h or "mail" in h:
        if any(
            w in h
            for w in (
                "weg",
                "schick",
                "send",
                "verschick",
                "schreib",
                "automat",
                "selbst",
                "raus",
            )
        ):
            return True
    if "mail" in h and any(w in h for w in ("brauch", "bedarf", "angebot", "kunde")):
        return True
    return False


def is_auto_email_on(state: JamState) -> bool:
    return bool(getattr(state, "jam_auto_email_mode", False)) or bool(
        getattr(state, "jam_full_contact_grant", False)
    )


def enable_auto_email(brain: JamBrain) -> str:
    state = brain.state
    state.jam_auto_email_mode = True
    state.jam_contact_auto = True
    state.remember("Jam: E-Mail bei Kunde-Zusage AN")
    brain.add_xp(6)
    brain.save()
    return (
        f"{owner_name(state)}, E-Mail-Modus AN – Jam schreibt und schickt erst, "
        f"wenn **ein Kunde zugesagt** hat (z. B. „Jam, Kunde will programmieren“). "
        f"Bei neuen Prospects nur Anschreiben, keine Mail."
    )


def has_jam_customer(state: JamState) -> bool:
    log = getattr(state, "jam_outbound_log", []) or []
    return any(
        isinstance(e, dict) and e.get("status") in CUSTOMER_STATUSES
        for e in log
    )


def pending_customer_for_email(state: JamState) -> dict | None:
    """Kunde mit Zusage, E-Mail noch nicht als gesendet markiert."""
    log = getattr(state, "jam_outbound_log", []) or []
    for entry in reversed(log):
        if not isinstance(entry, dict):
            continue
        if entry.get("status") not in CUSTOMER_STATUSES:
            continue
        if entry.get("email_sent"):
            continue
        return entry
    return None


def _mark_customer_email_sent(state: JamState, entry: dict) -> None:
    entry["email_sent"] = True
    entry["status"] = "email_gesendet"
    log = getattr(state, "jam_outbound_log", []) or []
    for i, e in enumerate(log):
        if isinstance(e, dict) and e.get("path") == entry.get("path"):
            log[i] = {**e, **entry}
            break
    state.jam_outbound_log = log


def email_subject(offer: dict, owner: str, lang: str = "de") -> str:
    title = offer["title_de"] if lang == "de" else offer["title"]
    return f"Angebot: {title} – wir helfen (Jam / {owner})"[:120]


def gmail_compose_url(
    *,
    to: str = "",
    subject: str = "",
    body: str = "",
) -> str:
    base = "https://mail.google.com/mail/u/0/?view=cm&fs=1"
    parts = []
    if to:
        parts.append(f"to={quote(to)}")
    if subject:
        parts.append(f"su={quote(subject)}")
    if body:
        parts.append(f"body={quote(body)}")
    if parts:
        return base + "&" + "&".join(parts)
    return base + "&tf=cm"


def _log(msg: str) -> None:
    line = f"[{datetime.now().strftime('%H:%M:%S')}] {msg}\n"
    try:
        EMAIL_LOG.parent.mkdir(parents=True, exist_ok=True)
        prev = EMAIL_LOG.read_text(encoding="utf-8") if EMAIL_LOG.is_file() else ""
        EMAIL_LOG.write_text(prev[-8000:] + line, encoding="utf-8")
    except OSError:
        pass


def _write_email_pack(
    project: Path,
    *,
    offer: dict,
    owner: str,
    price: float,
    body_de: str,
    body_en: str,
    recipient: str = "",
) -> None:
    sub_de = email_subject(offer, owner, "de")
    sub_en = email_subject(offer, owner, "en")
    (project / "EMAIL_VERSAND_DE.txt").write_text(
        f"An: {recipient or '(Jam trägt ein wenn auf der Seite gefunden)'}\n"
        f"Betreff: {sub_de}\n\n{body_de}\n",
        encoding="utf-8",
    )
    (project / "EMAIL_VERSAND_EN.txt").write_text(
        f"To: {recipient or '(fill if found)'}\n"
        f"Subject: {sub_en}\n\n{body_en}\n",
        encoding="utf-8",
    )
    (project / "GMAIL_COMPOSE_LINK_DE.url").write_text(
        gmail_compose_url(to=recipient, subject=sub_de, body=body_de),
        encoding="utf-8",
    )


def _playwright_ok() -> bool:
    try:
        import playwright  # noqa: F401

        return True
    except ImportError:
        return False


def _try_gmail_send(page, *, to: str, subject: str, body: str) -> list[str]:
    """Gmail Compose öffnen, ausfüllen, Send versuchen."""
    from jam.platform_auth import _fill_login_form, load_credentials
    from jam.customer_contact import _fill_textareas, _try_click

    steps: list[str] = []
    url = gmail_compose_url(to=to, subject=subject, body=body)
    try:
        page.goto(url, wait_until="domcontentloaded", timeout=60_000)
        page.wait_for_timeout(3500)
        steps.append("Compose")
    except Exception as e:
        return [f"Gmail:{e}"[:40]]

    creds = load_credentials()
    if creds and page.locator('input[type="password"]').count() > 0:
        _fill_login_form(page, creds[0], creds[1])
        page.wait_for_timeout(3000)
        page.goto(url, wait_until="domcontentloaded", timeout=60_000)
        page.wait_for_timeout(2500)

    if to:
        for sel in ('input[name="to"]', 'textarea[name="to"]', '[aria-label*="To" i]'):
            try:
                loc = page.locator(sel).first
                if loc.is_visible(timeout=1500):
                    loc.fill(to)
                    steps.append("An")
                    break
            except Exception:
                continue

    n = _fill_textareas(page, body)
    if n:
        steps.append(f"Text({n})")

    if _try_click(page, "Send", "Senden", "Send message", "Nachricht senden"):
        steps.append("Gesendet")
    else:
        steps.append("Entwurf-bereit")

    return steps


def send_email_via_jam_browser(
    *,
    subject: str,
    body: str,
    to: str = "",
    open_ui: bool = True,
) -> tuple[str, list[str]]:
    """Versand über Jam-Browser-Profil (Playwright, sichtbar)."""
    if not _playwright_ok():
        if open_ui:
            try:
                from jam.jam_browser import launch_jam_browser

                launch_jam_browser(detached=True)
            except Exception:
                pass
        return "Playwright fehlt", []

    from playwright.sync_api import sync_playwright

    try:
        from jam.jam_browser import PROFILE_DIR as JAM_PROFILE
    except Exception:
        JAM_PROFILE = ROOT / "data" / "jam-browser-profile"

    prof = JAM_PROFILE
    prof.mkdir(parents=True, exist_ok=True)
    steps: list[str] = []

    try:
        with sync_playwright() as p:
            try:
                context = p.chromium.launch_persistent_context(
                    str(prof),
                    channel="msedge",
                    headless=False,
                    viewport={"width": 1400, "height": 900},
                    locale="de-DE",
                )
            except Exception:
                context = p.chromium.launch_persistent_context(
                    str(prof),
                    headless=False,
                    viewport={"width": 1400, "height": 900},
                )
            page = context.pages[0] if context.pages else context.new_page()
            steps = _try_gmail_send(page, to=to, subject=subject, body=body)
            try:
                page.bring_to_front()
            except Exception:
                pass
            page.wait_for_timeout(5000)
            try:
                context.close()
            except Exception:
                pass
        return "OK", steps
    except Exception as e:
        return str(e)[:120], steps


def send_email_for_confirmed_customer(
    brain: JamBrain,
    *,
    user_initiated: bool = False,
    recipient: str = "",
    entry: dict | None = None,
) -> str:
    """E-Mail nur für Kunden mit Zusage – nicht für kalte Prospects."""
    from jam.outbound_sales import PROSPECT_OFFERS, _outreach_email_body
    from jam.platform_auth import load_credentials

    state = brain.state
    owner = owner_name(state)
    entry = entry or pending_customer_for_email(state)

    if not entry:
        if not has_jam_customer(state):
            return (
                f"{owner}, ich erstelle **noch keine E-Mail** – erst wenn ich "
                f"**einen Kunden mit Zusage** habe. Davor nur Anschreiben suchen. "
                f"Sagt jemand JA: „Jam, Kunde will programmieren“."
            )[:520]
        return f"{owner}, für alle Kunden mit Zusage ist die E-Mail schon erledigt."

    project = Path(str(entry.get("path", "")))
    if not project.is_dir():
        return f"{owner}, Kunden-Ordner fehlt – bitte nochmal „Kunde will programmieren“."

    gap = USER_GAP_SEC if user_initiated else AUTO_GAP_SEC
    if time.time() - getattr(state, "last_auto_email_at", 0.0) < gap:
        wait = int(gap - (time.time() - state.last_auto_email_at))
        return f"Nächste Kunden-E-Mail in {wait} Sek."

    if not load_credentials():
        return (
            f"{owner}, für E-Mails an **deinen Kunden** brauche ich Gmail-Freigabe "
            f"(E-Mail + Passwort an Jam). Dann über Jam Browser."
        )

    status = json.loads((project / "STATUS.json").read_text(encoding="utf-8"))
    offer_id = status.get("offer_id", entry.get("offer_id", "angebot"))
    offer = next(
        (p for p in PROSPECT_OFFERS if p["id"] == offer_id),
        {
            "id": offer_id,
            "title": entry.get("title", "Projekt"),
            "title_de": entry.get("title", "Projekt"),
            "need": "Entwicklung / Automatisierung",
        },
    )
    price = float(entry.get("price", status.get("price", 49)))
    body_de = _outreach_email_body(offer, owner, price, "de")
    body_en = _outreach_email_body(offer, owner, price, "en")
    sub_de = email_subject(offer, owner, "de")
    to = recipient or str(entry.get("recipient", ""))

    _write_email_pack(
        project,
        offer=offer,
        owner=owner,
        price=price,
        body_de=body_de,
        body_en=body_en,
        recipient=to,
    )

    try:
        from jam.jam_browser import launch_jam_browser

        launch_jam_browser(detached=True)
    except Exception:
        pass

    status_send, steps = send_email_via_jam_browser(
        subject=sub_de,
        body=body_de,
        to=to,
        open_ui=True,
    )

    _mark_customer_email_sent(state, entry)
    state.last_auto_email_at = time.time()
    state.auto_email_count = getattr(state, "auto_email_count", 0) + 1
    state.last_action = "auto_email"
    state.remember(f"Kunden-E-Mail: {offer.get('title_de', offer_id)}")
    brain.save()
    _log(f"{status_send} | {', '.join(steps)} | {project.name}")

    intro = random.choice(LINES).format(
        owner=owner,
        need=offer.get("need", "")[:60],
        title=offer.get("title_de", ""),
        paypal=PAYPAL_EMAIL,
    )
    return (
        f"{intro} Ordner: {project.name}. Gmail: {', '.join(steps) or status_send}. "
        f"Empfänger-Adresse ggf. im Compose eintragen – Text ist für **deinen Kunden** fertig."
    )[:620]


def run_auto_email_for_need(
    brain: JamBrain,
    *,
    user_initiated: bool = False,
    recipient: str = "",
) -> str:
    """Manuell/Autopilot: E-Mail nur wenn ein Kunde mit Zusage in der Log steht."""
    state = brain.state
    owner = owner_name(state)

    if not is_auto_email_on(state) and user_initiated:
        enable_auto_email(brain)

    if not pending_customer_for_email(state) and not has_jam_customer(state):
        return (
            f"{owner}, ich schicke **keine E-Mail vorher** – erst wenn ein Kunde "
            f"zugesagt hat. Ich suche weiter Prospects (Anschreiben). "
            f"Bei JA: „Jam, Kunde will programmieren“."
        )[:520]

    return send_email_for_confirmed_customer(
        brain,
        user_initiated=user_initiated,
        recipient=recipient,
    )


def _latest_prospect_folder() -> str:
    root = Path.home() / "Documents" / "Jam-Kunden-Ansprache-Welt"
    if not root.is_dir():
        return ""
    dirs = sorted(
        (p for p in root.iterdir() if p.is_dir()),
        key=lambda p: p.stat().st_mtime,
        reverse=True,
    )
    return str(dirs[0]) if dirs else ""


def maybe_auto_email(brain: JamBrain) -> str | None:
    if not is_auto_email_on(brain.state):
        return None
    if not pending_customer_for_email(brain.state):
        return None
    if random.random() > 0.25:
        return None
    if time.time() - getattr(brain.state, "last_auto_email_at", 0.0) < AUTO_GAP_SEC:
        return None
    return send_email_for_confirmed_customer(brain, user_initiated=False)


def handle_speech(brain: JamBrain, heard: str) -> str | None:
    if hears_auto_email(heard):
        return run_auto_email_for_need(brain, user_initiated=True)
    return None
