"""
Telegram-Verkaufskanal: Shop einrichten + Werbung.

Jam erstellt Texte, Katalog und Share-Links. Automatisches Posten nur mit
Bot-Token in data/telegram_config.local.json (optional).
"""

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, paypal_donate_url

ROOT = Path(__file__).resolve().parent.parent
CONFIG_FILE = ROOT / "data" / "telegram_config.json"
CONFIG_LOCAL = ROOT / "data" / "telegram_config.local.json"
TELEGRAM_ROOT = Path.home() / "Documents" / "Jam-Telegram-Verkauf"

WEB_TELEGRAM = "https://web.telegram.org/"
BOT_FATHER = "https://t.me/BotFather"
CREATE_CHANNEL_HELP = "https://telegram.org/tour/channels"

DEFAULT_CHANNEL_NAME = "Jam Shop – David"
DEFAULT_CHANNEL_USER = "david_jam_verkauf"

AUTO_GAP_SEC = 120.0
USER_GAP_SEC = 30.0

SETUP_LINES = (
    "{owner}, ich richte deinen **Telegram-Verkauf** ein – Texte & Werbung sind fertig!",
    "Telegram-Shop vorbereitet! Kanal anlegen, Posts aus dem Ordner kopieren – PayPal {paypal}.",
)

AD_LINES = (
    "{owner}, **Telegram-Werbung** ist raus – Share-Fenster & Posts in der Zwischenablage!",
    "Werbung auf Telegram: {n} Posts fertig für deinen Kanal!",
)


def _telegram_share(text: str, url: str = "") -> str:
    base = "https://t.me/share/url?"
    if url:
        return f"{base}url={quote(url, safe='')}&text={quote_plus(text[:900])}"
    return f"{base}text={quote_plus(text[:1000])}"


def _load_json(path: Path) -> dict:
    if not path.is_file():
        return {}
    try:
        data = json.loads(path.read_text(encoding="utf-8"))
        return data if isinstance(data, dict) else {}
    except (OSError, json.JSONDecodeError):
        return {}


def load_config() -> dict:
    cfg = _load_json(CONFIG_FILE)
    local = _load_json(CONFIG_LOCAL)
    cfg.update({k: v for k, v in local.items() if v})
    return cfg


def save_config(**fields: object) -> None:
    cfg = _load_json(CONFIG_FILE)
    cfg.update({k: v for k, v in fields.items() if v is not None})
    CONFIG_FILE.parent.mkdir(parents=True, exist_ok=True)
    CONFIG_FILE.write_text(json.dumps(cfg, indent=2, ensure_ascii=False), encoding="utf-8")


def channel_link(cfg: dict | None = None) -> str:
    c = cfg or load_config()
    link = str(c.get("channel_link", "") or "").strip()
    if link:
        return link if link.startswith("http") else f"https://t.me/{link.lstrip('@')}"
    user = str(c.get("channel_username", DEFAULT_CHANNEL_USER) or DEFAULT_CHANNEL_USER).lstrip("@")
    return f"https://t.me/{user}"


def hears_telegram_sell(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if "telegram" not in h and "telegr" not in h:
        return False
    return any(
        w in h
        for w in (
            "verkauf",
            "shop",
            "kanal",
            "channel",
            "werbung",
            "werben",
            "einricht",
            "einrich",
            "anlegen",
            "post",
            "setup",
        )
    )


def _latest_products(brain: JamBrain, n: int = 5) -> list[dict]:
    log = list(getattr(brain.state, "jam_sales_log", []) or [])
    out: list[dict] = []
    for entry in reversed(log):
        if isinstance(entry, dict) and entry.get("title"):
            out.append(entry)
        if len(out) >= n:
            break
    return out


def _product_posts(products: list[dict], owner: str) -> list[str]:
    from jam.active_sell import paypal_buy_url

    posts: list[str] = []
    if not products:
        posts.append(
            f"🛒 **Jam Digital Shop** – kleine Tools & Web-Hilfe von {owner}\n"
            f"💳 PayPal: {PAYPAL_EMAIL}\n"
            f"📩 Bestellen: DM oder Mail {PAYPAL_EMAIL}\n"
            f"⚡ Schnell, fair, auf Deutsch & English"
        )
        return posts

    for p in products:
        title = str(p.get("title", "Jam Produkt"))
        price = float(p.get("price", 9))
        reason = str(p.get("reason", ""))[:120]
        link = paypal_buy_url(price, title)
        posts.append(
            f"🆕 **{title}**\n"
            f"💶 Preis: **{price:.2f} EUR**\n"
            f"✨ {reason or 'Digital von Jam – sofort lieferbar'}\n"
            f"💳 Kaufen (PayPal): {link}\n"
            f"📧 {PAYPAL_EMAIL}\n"
            f"— Jam für {owner}"
        )
    return posts


def _write_shop_pack(
    brain: JamBrain,
    posts: list[str],
    *,
    owner: str,
) -> Path:
    TELEGRAM_ROOT.mkdir(parents=True, exist_ok=True)
    cfg = load_config()
    ch_name = str(cfg.get("channel_name", DEFAULT_CHANNEL_NAME))
    ch_url = channel_link(cfg)
    products = _latest_products(brain, 8)

    catalog_lines = []
    for p in products:
        title = p.get("title", "?")
        price = float(p.get("price", 0))
        catalog_lines.append(f"- **{title}** – {price:.2f} €")

    einrichtung = f"""TELEGRAM VERKAUFS-KANAL – {owner}
=====================================
Stand: {datetime.now().strftime('%d.%m.%Y %H:%M')}

SCHRITT 1 – Kanal anlegen (einmalig)
------------------------------------
1. Öffne Telegram: {WEB_TELEGRAM} oder App
2. Menue -> **Neuer Kanal** -> Name: {ch_name}
3. Kanal **oeffentlich** machen -> Link: @{cfg.get('channel_username', DEFAULT_CHANNEL_USER)}
   (oder eigenen Namen wählen und in data/telegram_config.json eintragen)
4. Beschreibung:
   Digital-Produkte & Programmier-Hilfe von {owner}.
   PayPal: {PAYPAL_EMAIL}

SCHRITT 2 – Ersten Post
-----------------------
1. Kanal oeffnen -> Nachricht schreiben
2. Text aus TELEGRAM_POST_1.txt kopieren (Ordner Jam-Telegram-Verkauf)
3. Pin-Nachricht: Kanal-Info oben anheften

SCHRITT 3 – Werbung
-------------------
- Jam öffnet t.me/share – dort Kanal wählen & senden
- Oder Posts aus TELEGRAM_POST_*.txt manuell einfügen
- In anderen Gruppen nur mit Erlaubnis der Admins posten!

OPTIONAL – Auto-Post (fortgeschritten)
--------------------------------------
1. @BotFather -> /newbot -> Token kopieren
2. Bot als **Admin** in deinen Kanal
3. Datei: data/telegram_config.local.json
   {{
     "bot_token": "DEIN_TOKEN",
     "channel_id": "@dein_kanal oder -100..."
   }}
4. Dann: Jam -> Telegram Werbung posten (automatisch)

PayPal für alle Käufe: {PAYPAL_EMAIL}
Kanal-Link (Ziel): {ch_url}
"""
    (TELEGRAM_ROOT / "EINRICHTUNG.txt").write_text(einrichtung, encoding="utf-8")

    for i, post in enumerate(posts, 1):
        (TELEGRAM_ROOT / f"TELEGRAM_POST_{i}.txt").write_text(post, encoding="utf-8")

    pin = (
        f"📢 **{ch_name}**\n\n"
        f"Willkommen! Hier verkauft Jam digitale Produkte für **{owner}**.\n\n"
        f"💳 PayPal: `{PAYPAL_EMAIL}`\n"
        f"📦 Aktuelle Angebote:\n"
        + ("\n".join(catalog_lines) if catalog_lines else "- Gleich mehr News!\n")
        + f"\n🔗 Spende/Tip: {paypal_donate_url()}\n"
        f"Fragen → DM oder Mail."
    )
    (TELEGRAM_ROOT / "TELEGRAM_KANAL_PIN.txt").write_text(pin, encoding="utf-8")

    html_items = "".join(
        f'<li><strong>{p.get("title")}</strong> – {float(p.get("price",0)):.2f} €</li>'
        for p in products
    )
    (TELEGRAM_ROOT / "katalog.html").write_text(
        f"""<!DOCTYPE html><html lang="de"><head><meta charset="utf-8">
<title>{ch_name}</title></head><body>
<h1>{ch_name}</h1><p>PayPal: {PAYPAL_EMAIL}</p>
<ul>{html_items or '<li>Jam baut gleich neue Produkte…</li>'}</ul>
<p><a href="{paypal_donate_url()}">PayPal</a> · <a href="{ch_url}">Telegram</a></p>
</body></html>""",
        encoding="utf-8",
    )

    return TELEGRAM_ROOT


def _clipboard(text: str) -> bool:
    try:
        from jam.auto_ops import clipboard_text

        return clipboard_text(text[:6000])
    except Exception:
        return False


def _try_api_post(text: str) -> bool:
    cfg = load_config()
    token = str(cfg.get("bot_token", "") or "").strip()
    chat = str(cfg.get("channel_id", "") or cfg.get("channel_username", "") or "").strip()
    if not token or not chat:
        return False
    try:
        import urllib.request

        payload = json.dumps(
            {
                "chat_id": chat if chat.startswith("@") or chat.startswith("-") else f"@{chat}",
                "text": text[:4090],
                "parse_mode": "Markdown",
                "disable_web_page_preview": False,
            },
            ensure_ascii=False,
        ).encode("utf-8")
        req = urllib.request.Request(
            f"https://api.telegram.org/bot{token}/sendMessage",
            data=payload,
            headers={"Content-Type": "application/json"},
            method="POST",
        )
        with urllib.request.urlopen(req, timeout=25) as resp:
            return resp.status == 200
    except Exception:
        return False


def setup_telegram_shop(brain: JamBrain, *, user_initiated: bool = True) -> str:
    """Kanal-Anleitung + Posts + Browser öffnen."""
    state = brain.state
    owner = owner_name(state)
    products = _latest_products(brain, 5)
    if not products and user_initiated:
        try:
            from jam.sales_engine import run_sale_project

            run_sale_project(brain, user_initiated=True)
            products = _latest_products(brain, 5)
        except Exception:
            pass

    posts = _product_posts(products, owner)
    welcome = (
        f"👋 **{DEFAULT_CHANNEL_NAME}** ist online!\n"
        f"Digitale Mini-Tools & Python/Web von Jam für {owner}.\n"
        f"💳 {PAYPAL_EMAIL}"
    )
    posts = [welcome] + posts[:6]

    folder = _write_shop_pack(brain, posts, owner=owner)
    save_config(
        channel_name=DEFAULT_CHANNEL_NAME,
        channel_username=DEFAULT_CHANNEL_USER,
        owner=owner,
    )

    opened: list[str] = []
    try:
        webbrowser.open(WEB_TELEGRAM, new=2)
        opened.append("Telegram Web")
        webbrowser.open(BOT_FATHER, new=2)
        opened.append("BotFather")
        webbrowser.open(CREATE_CHANNEL_HELP, new=2)
        webbrowser.open(channel_link(), new=2)
        webbrowser.open((folder / "katalog.html").as_uri(), new=2)
    except OSError:
        pass

    try:
        import os
        import subprocess

        if os.name == "nt":
            subprocess.run(["explorer", str(folder)], check=False, timeout=5)
    except Exception:
        pass

    clip = _clipboard(posts[0])
    state.telegram_shop_ready = True
    state.telegram_setup_at = time.time()
    state.telegram_channel_link = channel_link()
    state.last_action = "telegram_setup"
    state.remember("Telegram-Verkaufskanal vorbereitet")
    brain.add_xp(8)
    brain.save()

    clip_bit = "Erster Post in Zwischenablage!" if clip else "Posts im Ordner Jam-Telegram-Verkauf."
    return (
        random.choice(SETUP_LINES).format(owner=owner, paypal=PAYPAL_EMAIL)
        + f" Ordner: {folder.name}. {clip_bit} "
        f"Geöffnet: {', '.join(opened)}. "
        f"Kanal anlegen - TELEGRAM_KANAL_PIN.txt als erste Nachricht - Werbung: "
        f"Jam, Telegram Werbung."
    )[:620]


def run_telegram_ads(brain: JamBrain, *, user_initiated: bool = True) -> str:
    """Werbung: Share-Links, optional API-Post."""
    state = brain.state
    gap = USER_GAP_SEC if user_initiated else AUTO_GAP_SEC
    if time.time() - getattr(state, "last_telegram_ad_at", 0.0) < gap:
        wait = int(gap - (time.time() - state.last_telegram_ad_at))
        return f"Nächste Telegram-Werbung in {wait} Sek."

    owner = owner_name(state)
    products = _latest_products(brain, 3)
    posts = _product_posts(products, owner)
    if not posts:
        return setup_telegram_shop(brain, user_initiated=user_initiated)

    folder = _write_shop_pack(brain, posts, owner=owner)
    posted_api = 0
    shared = 0

    for i, post in enumerate(posts[:3], 1):
        url = ""
        if products and i - 1 < len(products):
            from jam.active_sell import paypal_buy_url

            url = paypal_buy_url(
                float(products[i - 1].get("price", 9)),
                str(products[i - 1].get("title", "Produkt")),
            )
        if _try_api_post(post):
            posted_api += 1
        try:
            webbrowser.open(_telegram_share(post, url), new=2)
            shared += 1
            time.sleep(0.5)
        except OSError:
            pass

    try:
        webbrowser.open(channel_link(), new=2)
    except OSError:
        pass

    _clipboard("\n\n---\n\n".join(posts[:3]))
    state.last_telegram_ad_at = time.time()
    state.telegram_ad_count = getattr(state, "telegram_ad_count", 0) + 1
    state.last_action = "telegram_ads"
    state.remember(f"Telegram-Werbung #{state.telegram_ad_count}")
    brain.add_xp(5)
    brain.save()

    api_bit = f" {posted_api}× auto-gepostet." if posted_api else ""
    return (
        random.choice(AD_LINES).format(owner=owner, n=len(posts))
        + f" Share-Fenster: {shared}×.{api_bit}"
        f" Texte: {folder.name}. Kanal: {channel_link()}. "
        f"Im Share-Dialog deinen **Kanal** wählen und Senden!"
    )[:620]


def maybe_auto_telegram_ad(brain: JamBrain) -> str | None:
    state = brain.state
    if not getattr(state, "telegram_shop_ready", False):
        if random.random() > 0.25:
            return None
        return setup_telegram_shop(brain, user_initiated=False)[:220]
    if time.time() - getattr(state, "last_telegram_ad_at", 0.0) < 300.0:
        return None
    if random.random() > 0.38:
        return None
    return run_telegram_ads(brain, user_initiated=False)


def push_telegram_for_product(
    title: str,
    price: float,
    owner: str,
    paypal_link: str,
) -> str:
    """Kurzer Telegram-Post für ein Produkt (active_sell)."""
    post = (
        f"🆕 {title} – {price:.2f} EUR\n"
        f"PayPal: {paypal_link}\n"
        f"{PAYPAL_EMAIL} · Jam für {owner}"
    )
    try:
        webbrowser.open(_telegram_share(post, paypal_link), new=2)
    except OSError:
        pass
    return post


def handle_speech(brain: JamBrain, heard: str) -> str | None:
    if not hears_telegram_sell(heard):
        return None
    h = heard.lower()
    if any(w in h for w in ("werbung", "werben", "post", "push", "bewerb")):
        return run_telegram_ads(brain, user_initiated=True)
    return setup_telegram_shop(brain, user_initiated=True)
