"""Fiverr-Verkäufer verbinden – Konto merken, Seller-Dashboard + Gig-Texte (kein API-Login)."""

from __future__ import annotations

import json
import random
import re
import time
import webbrowser
from pathlib import Path

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

CONFIG_PATH = Path(__file__).resolve().parent.parent / "data" / "fiverr_config.json"
DEFAULT_USERNAME = "davidhutson2000"

SELLER_DASHBOARD = "https://www.fiverr.com/seller_dashboard"
START_SELLING = "https://www.fiverr.com/start_selling"
NEW_SELLER = "https://www.fiverr.com/users/new/seller_dashboard"
INBOX_URL = "https://www.fiverr.com/inbox"
PAYPAL_ACCOUNT_URL = "https://www.paypal.com/myaccount/summary"

CONNECT_SPEECH: tuple[str, ...] = (
    "{owner}, Fiverr ist verbunden! Seller-Dashboard ist offen – Gig-Texte kopierst du aus FIVERR_GIG.txt.",
    "Fiverr-Link aktiv! @{user} – sag „Jam, Fiverr Gig“ und ich öffne den neuen Gig-Editor mit Text in der Zwischenablage.",
    "Ja! Fiverr hängt dran – ich pushe deine Jam-Produkte als Gigs für {owner}!",
)

ALREADY_CONNECTED: tuple[str, ...] = (
    "Fiverr ist schon verbunden (@{user}) – Dashboard ist wieder offen.",
    "Link steht: Fiverr @{user} – Gig-Ordner und Zwischenablage nutzen wie eben.",
)


def _load_file_config() -> dict:
    try:
        if CONFIG_PATH.is_file():
            return json.loads(CONFIG_PATH.read_text(encoding="utf-8"))
    except (OSError, json.JSONDecodeError, TypeError):
        pass
    return {}


def _save_file_config(username: str) -> None:
    CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
    CONFIG_PATH.write_text(
        json.dumps({"username": username, "updated_at": time.time()}, indent=2),
        encoding="utf-8",
    )


def normalize_username(raw: str) -> str:
    u = (raw or "").strip().lstrip("@").lower()
    u = re.sub(r"[^a-z0-9_-]", "", u)
    return u[:32]


def get_username(state: JamState) -> str:
    if getattr(state, "fiverr_username", ""):
        return normalize_username(state.fiverr_username)
    cfg = _load_file_config()
    return normalize_username(cfg.get("username", "") or DEFAULT_USERNAME)


def is_connected(state: JamState) -> bool:
    return bool(getattr(state, "fiverr_connected", False))


def profile_url(username: str | None = None) -> str:
    u = normalize_username(username or "")
    if u:
        return f"https://www.fiverr.com/{u}"
    return START_SELLING


def manage_gigs_url(username: str | None = None) -> str:
    u = normalize_username(username or "")
    if u:
        return f"https://www.fiverr.com/users/{u}/manage_gigs"
    return NEW_SELLER


def new_gig_url(username: str | None = None) -> str:
    u = normalize_username(username or "")
    if u:
        return f"https://www.fiverr.com/users/{u}/manage_gigs/new"
    return NEW_SELLER


def seller_urls(username: str | None = None) -> list[tuple[str, str]]:
    u = normalize_username(username or "")
    if u:
        return [
            ("Profil", profile_url(u)),
            ("Gigs verwalten", manage_gigs_url(u)),
            ("Neuer Gig", new_gig_url(u)),
            ("Seller Dashboard", SELLER_DASHBOARD),
            ("Inbox", INBOX_URL),
        ]
    return [
        ("Fiverr Verkaufen starten", START_SELLING),
        ("Seller Dashboard", SELLER_DASHBOARD),
        ("Neuer Verkäufer", NEW_SELLER),
    ]


def platform_entry(state: JamState) -> tuple[str, str]:
    """URL-Tuple für active_sell / auto_ops."""
    u = get_username(state)
    if is_connected(state) and u:
        return ("Fiverr Gig", new_gig_url(u))
    return ("Fiverr", manage_gigs_url(u) if u else NEW_SELLER)


def _offering_for_title(title: str):
    try:
        from jam.service_catalog import SERVICE_OFFERINGS

        t = title.lower()
        for o in SERVICE_OFFERINGS:
            if o["id"].startswith("minecraft") and "minecraft" in t:
                if o["id"] == "minecraft_full" and "komplett" in t:
                    return o
                if o["id"] == "minecraft_java" and ("java" in t or "plugin" in t):
                    return o
                if o["id"] == "minecraft_scripts" and (
                    "skript" in t or "datenpack" in t or "script" in t
                ):
                    return o
                if o["id"] == "minecraft_server" and (
                    "server" in t or "leitung" in t or "setup" in t
                ):
                    return o
        if "minecraft" in t:
            return SERVICE_OFFERINGS[0]
        if "webseite" in t or "website" in t or "landing" in t or "portfolio" in t:
            if "business" in t or "firma" in t:
                for o in SERVICE_OFFERINGS:
                    if o["id"] == "web_business":
                        return o
            if "portfolio" in t or "creator" in t:
                for o in SERVICE_OFFERINGS:
                    if o["id"] == "web_portfolio":
                        return o
            if "landing" in t or "link" in t:
                for o in SERVICE_OFFERINGS:
                    if o["id"] == "web_landing":
                        return o
            for o in SERVICE_OFFERINGS:
                if o["id"] == "web_modern":
                    return o
        if "discord" in t:
            if "skript" in t or "script" in t or "custom" in t:
                for o in SERVICE_OFFERINGS:
                    if o["id"] == "discord_scripts":
                        return o
            for o in SERVICE_OFFERINGS:
                if o["id"] == "discord_setup":
                    return o
        for o in SERVICE_OFFERINGS:
            if o["title"].lower()[:20] in t or t[:15] in o["title"].lower():
                return o
    except Exception:
        pass
    return None


def write_gig_listing(
    project: Path,
    *,
    title: str,
    owner: str,
    price: int,
    reason: str,
) -> None:
    """FIVERR_GIG.txt – copy-paste für Fiverr-Formular."""
    offering = _offering_for_title(title)
    if offering:
        try:
            from jam.service_catalog import fiverr_gig_text

            body = fiverr_gig_text(
                offering,
                owner=owner,
                standard_price=price,
                project_name=project.name,
            )
            body += f"\nJam-Preis-Begründung: {reason}\n"
            (project / "FIVERR_GIG.txt").write_text(body, encoding="utf-8")
            return
        except Exception:
            pass
    tags = ", ".join(
        w
        for w in (
            "digital",
            "delivery",
            "german",
            "python",
            "design",
            "jam",
            "freelance",
        )
        if w not in title.lower()
    )[:120]
    body = (
        f"=== FIVERR GIG (Jam) ===\n\n"
        f"TITEL (max 80 Zeichen):\n{title[:80]}\n\n"
        f"KATEGORIE-VORSCHLAG:\n"
        f"Programming & Tech > Website Development\n"
        f"oder Graphics & Design > Digital Art\n\n"
        f"BESCHREIBUNG:\n"
        f"I deliver **{title}** – built by Jam/Cursor for **{owner}**.\n\n"
        f"✅ What you get:\n"
        f"- Complete files from project folder\n"
        f"- Clear README / VERKAUF.md\n"
        f"- Fast communication in English or German\n\n"
        f"💳 Auszahlung an David: PayPal **{PAYPAL_EMAIL}** (Fiverr-Auszahlung dort einrichten)\n"
        f"   Direktkauf / Spende ebenfalls: {PAYPAL_EMAIL}\n\n"
        f"Jam price rationale: {reason}\n\n"
        f"PAKETE (Vorschlag):\n"
        f"- Basic: {max(5, int(price * 0.6))} EUR – core delivery\n"
        f"- Standard: {price} EUR – full package (recommended)\n"
        f"- Premium: {int(price * 1.4)} EUR – extras + priority\n\n"
        f"LIEFERZEIT: 2–3 Tage\n\n"
        f"TAGS: {tags}\n\n"
        f"FAQ:\n"
        f"Q: Is this custom?\nA: Yes – project folder: {project.name}\n"
    )
    (project / "FIVERR_GIG.txt").write_text(body, encoding="utf-8")


def format_connect_bubble(username: str) -> str:
    u = normalize_username(username)
    lines = ["💼 Fiverr verbunden", SELLER_DASHBOARD]
    if u:
        lines.insert(1, f"@{u}")
    return "\n".join(lines)


def hears_connect(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if "fiverr" not in h and "fiver" not in h:
        return False
    return any(
        w in h
        for w in (
            "verbind",
            "connect",
            "link",
            "konto",
            "account",
            "anmelden",
            "einlog",
            "login",
            "koppel",
            "seller",
            "verkäufer",
            "verkaeufer",
        )
    )


def hears_start_selling(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if "fiverr" not in h and "fiver" not in h:
        return False
    return any(
        w in h
        for w in (
            "verkauf",
            "verkaufen",
            "verdiene",
            "verdienen",
            "geld",
            "paypal",
            "anfang",
            "starte",
            "start",
            "loslegen",
            "business",
        )
    ) or ("verbind" in h and any(w in h for w in ("verkauf", "geld", "paypal")))


def billing_url(username: str | None = None) -> str:
    u = normalize_username(username or DEFAULT_USERNAME)
    if u:
        return f"https://www.fiverr.com/users/{u}/billing?source=header_nav"
    return SELLER_DASHBOARD


def hears_gig_push(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if "fiverr" not in h and "fiver" not in h:
        return False
    return any(
        w in h
        for w in (
            "gig",
            "listing",
            "angebot",
            "verkauf",
            "einstellen",
            "veröffentlich",
            "publish",
        )
    )


def parse_username_from_speech(text: str) -> str | None:
    h = text.lower()
    m = re.search(
        r"(?:als|user(?:name)?|profil|konto)\s+([a-z0-9_-]{3,32})",
        h.replace("jam", " "),
    )
    if m:
        return normalize_username(m.group(1))
    m = re.search(r"fiverr\.com/([a-z0-9_-]{3,32})", h)
    if m:
        return normalize_username(m.group(1))
    m = re.search(r"@([a-z0-9_-]{3,32})", h)
    if m and "fiverr" in h:
        return normalize_username(m.group(1))
    return None


def connect_fiverr(
    brain: JamBrain,
    *,
    username: str | None = None,
    heard: str = "",
    user_asked: bool = True,
) -> str:
    """Fiverr-Verknüpfung: Username speichern + Seller-Seiten öffnen."""
    state = brain.state
    owner = owner_name(state)
    u = normalize_username(
        username
        or parse_username_from_speech(heard)
        or get_username(state)
        or DEFAULT_USERNAME
    )

    was = is_connected(state) and (not u or get_username(state) == u)

    if u:
        state.fiverr_username = u
        _save_file_config(u)

    state.fiverr_connected = True
    state.fiverr_connected_at = time.time()
    state.fiverr_connect_count = getattr(state, "fiverr_connect_count", 0) + (0 if was else 1)
    state.last_action = "fiverr_connect"
    state.remember(f"Fiverr verbunden{f' @{u}' if u else ''}")
    state.learn_word("fiverr")
    brain.add_xp(10)
    brain.save()

    opened: list[str] = []
    try:
        for name, url in seller_urls(u)[:4 if user_asked else 2]:
            webbrowser.open(url, new=2)
            opened.append(name)
    except OSError as e:
        return f"Fiverr-Verbindung klappt nicht: {e}"

    display_user = u or "dein Seller-Konto"
    if was:
        line = random.choice(ALREADY_CONNECTED).format(user=display_user, owner=owner)
    else:
        line = random.choice(CONNECT_SPEECH).format(user=display_user, owner=owner)
    if not u:
        line += (
            " Sag deinen Fiverr-Nutzernamen, z. B. „Jam, Fiverr verbinden als meinname“ – "
            "dann öffne ich direkt deine Gigs."
        )
    line += f" Offen: {', '.join(opened)}."
    return line


def _latest_sale_project(brain: JamBrain) -> tuple[Path, str, float] | None:
    log = getattr(brain.state, "jam_sales_log", []) or []
    if not log or not isinstance(log[-1], dict):
        return None
    entry = log[-1]
    project = Path(entry.get("path", ""))
    if not project.is_dir():
        return None
    return project, str(entry.get("title", "Produkt")), float(entry.get("price", 9))


def push_latest_gig(brain: JamBrain, *, user_initiated: bool = True) -> str:
    """Gig-Text in Zwischenablage + Fiverr Gig-Editor."""
    from jam.auto_ops import clipboard_text

    if not is_connected(brain.state):
        return connect_fiverr(brain, user_asked=user_initiated)

    sale = _latest_sale_project(brain)
    if not sale:
        from jam.sales_engine import run_sale_project

        build = run_sale_project(brain, user_initiated=user_initiated)
        sale = _latest_sale_project(brain)
        if not sale:
            return f"Ich baue erst ein Produkt – dann Fiverr-Gig! {build}"[:400]

    project, title, price = sale
    clip_text = ""
    gig_file = project / "FIVERR_GIG.txt"
    if gig_file.is_file():
        try:
            clip_text = gig_file.read_text(encoding="utf-8", errors="replace")[:6000]
        except OSError:
            pass
    if not clip_text:
        write_gig_listing(
            project,
            title=title,
            owner=owner_name(brain.state),
            price=int(price) if price >= 1 else 5,
            reason="Jam Gig push",
        )
        clip_text = gig_file.read_text(encoding="utf-8", errors="replace")[:6000]

    clip_ok = clipboard_text(clip_text)
    u = get_username(brain.state)
    try:
        webbrowser.open(new_gig_url(u), new=2)
        shop = project / "index.html"
        if shop.is_file():
            webbrowser.open(shop.as_uri(), new=2)
    except OSError:
        pass

    brain.state.fiverr_gig_push_count = getattr(brain.state, "fiverr_gig_push_count", 0) + 1
    brain.state.last_fiverr_gig_push_at = time.time()
    brain.state.last_action = "fiverr_gig"
    brain.save()

    owner = owner_name(brain.state)
    clip_bit = (
        "Gig-Text ist in der **Zwischenablage** – in Fiverr einfügen & Veröffentlichen!"
        if clip_ok
        else f"Text liegt in {gig_file.name} im Ordner."
    )
    return (
        f"{owner}, Fiverr-Gig für **{title}** ({price:.2f} €)! "
        f"{clip_bit} Jam klickt nicht „Publish“ – du bestätigst im Browser."
    )[:480]


def run_fiverr_sell_mission(brain: JamBrain, *, heard: str = "", user_initiated: bool = True) -> str:
    """
    Fiverr verbinden + Produkt bauen + Gig/PayPal pushen.
    Echtes Geld: Fiverr-Auszahlung oder PayPal-Zahlung an PAYPAL_EMAIL.
    """
    from jam.active_sell import apply_active_sell_startup, mark_logged_in, push_product_sale
    from jam.sales_engine import run_sale_project

    owner = owner_name(brain.state)
    u = DEFAULT_USERNAME

    connect_msg = connect_fiverr(
        brain, username=u, heard=heard, user_asked=user_initiated
    )
    apply_active_sell_startup(brain)
    mark_logged_in(brain)
    brain.state.jam_active_sell_mode = True
    brain.state.remember(f"Fiverr-Verkauf für {owner}, PayPal {PAYPAL_EMAIL}")
    brain.save()

    build_msg = run_sale_project(brain, user_initiated=user_initiated)
    gig_msg = push_latest_gig(brain, user_initiated=user_initiated)

    push_msg = ""
    sale = _latest_sale_project(brain)
    if sale:
        project, title, price = sale
        push_msg = push_product_sale(
            brain, project, title, price, user_initiated=user_initiated
        )

    try:
        webbrowser.open(billing_url(u), new=2)
        webbrowser.open(PAYPAL_ACCOUNT_URL, new=2)
    except OSError:
        pass

    return (
        f"{owner}, Fiverr @{u} ist verbunden – ich verkaufe für dich! "
        f"Geld soll auf PayPal **{PAYPAL_EMAIL}**: "
        f"In Fiverr unter Abrechnung PayPal verknüpfen (hab ich geöffnet). "
        f"{build_msg[:120]}… {gig_msg[:140]}… "
        f"Gig-Text in Zwischenablage – du klickst „Veröffentlichen“. "
        f"{push_msg[:80] if push_msg else ''}"
    )[:620]


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

        msg = assist_speech(brain, heard)
        if msg:
            return msg
    except Exception:
        pass
    if hears_start_selling(heard):
        return run_fiverr_sell_mission(brain, heard=heard, user_initiated=True)
    if hears_connect(heard):
        return connect_fiverr(
            brain,
            username=parse_username_from_speech(heard),
            heard=heard,
            user_asked=True,
        )
    if hears_gig_push(heard):
        return push_latest_gig(brain, user_initiated=True)
    if "fiverr" in heard.lower() and any(
        w in heard.lower() for w in ("eingelog", "angemeld", "login fertig", "bin drin")
    ):
        from jam.active_sell import mark_logged_in

        connect_fiverr(brain, heard=heard, user_asked=True)
        mark_logged_in(brain)
        return push_latest_gig(brain, user_initiated=True)
    return None


def stats_line(state: JamState) -> str:
    u = get_username(state)
    flag = "verbunden" if is_connected(state) else "nicht verbunden"
    pushes = getattr(state, "fiverr_gig_push_count", 0)
    user_bit = f" @{u}" if u else ""
    return f"Fiverr{user_bit}: {flag}, Gig-Pushes: {pushes}×"
