"""VidPuls – Stripe Checkout (Einzelvideo + Abo)."""

from __future__ import annotations

import json
import os
import urllib.error
import urllib.parse
import urllib.request
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
SECRETS = ROOT / "data" / "jami-secrets.local.json"
CONFIG_NAMES = ("vidpuls-config.json", "clipwelle-config.json", "jampulse-config.json")
SITE_URL = "http://127.0.0.1:8791"


def _config_path() -> Path:
    for name in CONFIG_NAMES:
        p = ROOT / "data" / name
        if p.is_file():
            return p
    return ROOT / "data" / CONFIG_NAMES[0]


def _stripe_key() -> str:
    key = os.environ.get("STRIPE_SECRET_KEY", "").strip()
    if key:
        return key
    if SECRETS.is_file():
        try:
            data = json.loads(SECRETS.read_text(encoding="utf-8"))
            return str(
                data.get("stripe_live_secret_key")
                or data.get("stripe_secret_key")
                or data.get("STRIPE_SECRET_KEY")
                or ""
            ).strip()
        except (json.JSONDecodeError, OSError):
            pass
    return ""


def _site_url() -> str:
    cfg_path = _config_path()
    if cfg_path.is_file():
        try:
            cfg = json.loads(cfg_path.read_text(encoding="utf-8"))
            return str(cfg.get("site_url") or SITE_URL).rstrip("/")
        except (json.JSONDecodeError, OSError):
            pass
    from jam.jampulse_brand import PRODUCT_SITE_URL

    return PRODUCT_SITE_URL.rstrip("/")


def product_catalog() -> dict[str, dict]:
    from jam.jampulse_brand import SINGLE_VIDEO_OFFER, SUBSCRIPTION_OFFER

    sub = SUBSCRIPTION_OFFER
    single = SINGLE_VIDEO_OFFER
    cat = {
        "video_1": {
            "name": single["title"],
            "price_eur": float(single["price_eur"]),
            "mode": "payment",
            "videos": 1,
        },
        "pro_monthly": {
            "name": sub["title"] + " · Monat",
            "price_eur": float(sub["monthly_eur"]),
            "mode": "subscription",
            "interval": "month",
        },
        "pro_yearly": {
            "name": sub["title"] + " · Jahr (-30 %)",
            "price_eur": float(sub["yearly_eur"]),
            "mode": "subscription",
            "interval": "year",
        },
    }
    try:
        from jam.dialog_shop import dialog_product_catalog

        cat.update(dialog_product_catalog())
    except ImportError:
        pass
    return cat


def create_dialog_checkout(
    product_id: str,
    *,
    email: str = "",
    pay_with: str = "all",
) -> dict:
    """Checkout für Dialog-Studio (Erfolg zurück zum lokalen Studio)."""
    ip = _lan_ip()
    success_base = f"http://{ip}:8793"
    return create_checkout_session(
        product_id,
        email=email,
        pay_with=pay_with,
        success_base=success_base,
        cancel_path="/",
    )


def _lan_ip() -> str:
    try:
        from jam.wan2gp_local import local_ip

        return local_ip()
    except ImportError:
        return "127.0.0.1"


def _stripe_post(path: str, fields: dict) -> dict:
    key = _stripe_key()
    if not key:
        return {"error": "Stripe-Key fehlt (STRIPE_SECRET_KEY oder jami-secrets.local.json)"}
    body = urllib.parse.urlencode(fields).encode("utf-8")
    req = urllib.request.Request(
        f"https://api.stripe.com/v1/{path.lstrip('/')}",
        data=body,
        headers={"Authorization": f"Bearer {key}"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=45) as resp:
            return json.loads(resp.read().decode())
    except urllib.error.HTTPError as e:
        try:
            err = json.loads(e.read().decode())
            return {"error": err.get("error", {}).get("message") or str(e)}
        except (json.JSONDecodeError, OSError):
            return {"error": str(e)}


def _stripe_get(path: str) -> dict:
    key = _stripe_key()
    if not key:
        return {"error": "Stripe-Key fehlt"}
    req = urllib.request.Request(
        f"https://api.stripe.com/v1/{path.lstrip('/')}",
        headers={"Authorization": f"Bearer {key}"},
        method="GET",
    )
    try:
        with urllib.request.urlopen(req, timeout=45) as resp:
            return json.loads(resp.read().decode())
    except urllib.error.HTTPError as e:
        try:
            err = json.loads(e.read().decode())
            return {"error": err.get("error", {}).get("message") or str(e)}
        except (json.JSONDecodeError, OSError):
            return {"error": str(e)}


def create_checkout_session(
    product_id: str,
    *,
    email: str = "",
    pay_with: str = "all",
    success_base: str | None = None,
    cancel_path: str = "/?view=create",
) -> dict:
    cat = product_catalog()
    product = cat.get(product_id)
    if not product:
        return {"ok": False, "error": f"Unbekanntes Produkt: {product_id}"}

    base = (success_base or _site_url()).rstrip("/")
    cents = int(round(float(product["price_eur"]) * 100))
    fields: dict = {
        "mode": product["mode"],
        "locale": "de",
        "success_url": f"{base}/?paid=stripe&session_id={{CHECKOUT_SESSION_ID}}&product={product_id}",
        "cancel_url": f"{base}{cancel_path}",
        "metadata[type]": "vidpuls",
        "metadata[product_id]": product_id,
        "line_items[0][quantity]": "1",
        "line_items[0][price_data][currency]": "eur",
        "line_items[0][price_data][product_data][name]": product["name"],
    }
    if email and "@" in email:
        fields["customer_email"] = email

    if product["mode"] == "subscription":
        fields["line_items[0][price_data][recurring][interval]"] = product["interval"]
        fields["line_items[0][price_data][unit_amount]"] = str(cents)
    else:
        fields["line_items[0][price_data][unit_amount]"] = str(cents)

    from jam.jampulse_payments import STRIPE_CHECKOUT_PRESETS

    pay = (pay_with or "all").strip().lower()
    if pay == "paypal":
        presets = [["paypal"], ["paypal", "card"], ["card", "link", "paypal"]]
    elif pay in ("bank", "ueberweisung", "transfer"):
        presets = [
            ["customer_balance"],
            ["sepa_debit"],
            ["card", "link", "paypal", "sepa_debit"],
            ["card", "link", "paypal"],
            ["card"],
        ]
    else:
        presets = STRIPE_CHECKOUT_PRESETS + [["sepa_debit"], ["customer_balance"]]
    key = _stripe_key()
    if not key:
        from jam.jampulse_payments import paypal_product_url

        ip = _lan_ip()
        return_url = f"http://{ip}:8793/?paid=paypal&product={urllib.parse.quote(product_id)}"
        return {
            "ok": True,
            "fallback": "paypal",
            "url": paypal_product_url(
                product_id=product_id,
                price_eur=float(product["price_eur"]),
                title=str(product["name"]),
                return_url=return_url,
            ),
            "message": "Stripe nicht konfiguriert – PayPal-Direktlink",
        }

    last_err = "Checkout fehlgeschlagen"
    methods_used: list[str] = []
    for preset in presets:
        payload: list[tuple[str, str]] = [(k, v) for k, v in fields.items()]
        for m in preset:
            payload.append(("payment_method_types[]", m))
        body = urllib.parse.urlencode(payload).encode("utf-8")
        req = urllib.request.Request(
            "https://api.stripe.com/v1/checkout/sessions",
            data=body,
            headers={"Authorization": f"Bearer {key}"},
            method="POST",
        )
        try:
            with urllib.request.urlopen(req, timeout=45) as resp:
                session = json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            try:
                err = json.loads(e.read().decode())
                last_err = err.get("error", {}).get("message") or str(e)
            except (json.JSONDecodeError, OSError):
                last_err = str(e)
            msg = last_err.lower()
            if "payment_method" in msg or "payment method" in msg:
                continue
            return {"ok": False, "error": last_err}
        else:
            methods_used = preset
            if session.get("url"):
                return {
                    "ok": True,
                    "url": session["url"],
                    "sessionId": session.get("id"),
                    "productId": product_id,
                    "paymentMethods": methods_used,
                }
            last_err = session.get("error") or "Keine Checkout-URL"
            break

    return {"ok": False, "error": last_err}


def verify_session(session_id: str) -> dict:
    sid = (session_id or "").strip()
    if not sid.startswith("cs_"):
        return {"ok": False, "error": "Ungültige Session-ID"}
    session = _stripe_get(f"checkout/sessions/{sid}")
    if session.get("error"):
        return {"ok": False, "error": session["error"]}
    if session.get("payment_status") != "paid" and session.get("status") != "complete":
        return {"ok": False, "error": "Zahlung noch nicht abgeschlossen", "status": session.get("payment_status")}

    meta = session.get("metadata") or {}
    product_id = str(meta.get("product_id") or "pro_monthly")
    from jam.jampulse_license import apply_purchase

    try:
        lic = apply_purchase(product_id, session_id=sid)
    except ValueError as e:
        return {"ok": False, "error": str(e)}
    return {"ok": True, "productId": product_id, "license": lic}
