"""SEO-Landingpages für organischen Google-Traffic → Jami-Registrierungen & Coin-Umsatz."""

from __future__ import annotations

import hashlib
import json
from pathlib import Path

# Top-Städte + Long-Tail (passiv indexierbar)
SEO_CITIES: list[dict[str, str]] = [
    {"slug": "berlin", "name": "Berlin", "region": "Berlin"},
    {"slug": "hamburg", "name": "Hamburg", "region": "Hamburg"},
    {"slug": "muenchen", "name": "München", "region": "Bayern"},
    {"slug": "koeln", "name": "Köln", "region": "NRW"},
    {"slug": "frankfurt", "name": "Frankfurt", "region": "Hessen"},
    {"slug": "stuttgart", "name": "Stuttgart", "region": "Baden-Württemberg"},
    {"slug": "duesseldorf", "name": "Düsseldorf", "region": "NRW"},
    {"slug": "leipzig", "name": "Leipzig", "region": "Sachsen"},
    {"slug": "dortmund", "name": "Dortmund", "region": "NRW"},
    {"slug": "essen", "name": "Essen", "region": "NRW"},
    {"slug": "bremen", "name": "Bremen", "region": "Bremen"},
    {"slug": "dresden", "name": "Dresden", "region": "Sachsen"},
    {"slug": "hannover", "name": "Hannover", "region": "Niedersachsen"},
    {"slug": "nuernberg", "name": "Nürnberg", "region": "Bayern"},
    {"slug": "duisburg", "name": "Duisburg", "region": "NRW"},
    {"slug": "bochum", "name": "Bochum", "region": "NRW"},
    {"slug": "wuppertal", "name": "Wuppertal", "region": "NRW"},
    {"slug": "bielefeld", "name": "Bielefeld", "region": "NRW"},
    {"slug": "bonn", "name": "Bonn", "region": "NRW"},
    {"slug": "muenster", "name": "Münster", "region": "NRW"},
    {"slug": "karlsruhe", "name": "Karlsruhe", "region": "Baden-Württemberg"},
    {"slug": "mannheim", "name": "Mannheim", "region": "Baden-Württemberg"},
    {"slug": "augsburg", "name": "Augsburg", "region": "Bayern"},
    {"slug": "wiesbaden", "name": "Wiesbaden", "region": "Hessen"},
    {"slug": "aachen", "name": "Aachen", "region": "NRW"},
    {"slug": "moenchengladbach", "name": "Mönchengladbach", "region": "NRW"},
    {"slug": "braunschweig", "name": "Braunschweig", "region": "Niedersachsen"},
    {"slug": "kiel", "name": "Kiel", "region": "Schleswig-Holstein"},
    {"slug": "chemnitz", "name": "Chemnitz", "region": "Sachsen"},
    {"slug": "freiburg", "name": "Freiburg", "region": "Baden-Württemberg"},
    {"slug": "rostock", "name": "Rostock", "region": "Mecklenburg-Vorpommern"},
    {"slug": "mainz", "name": "Mainz", "region": "Rheinland-Pfalz"},
    {"slug": "lueneburg", "name": "Lüneburg", "region": "Niedersachsen"},
    {"slug": "erfurt", "name": "Erfurt", "region": "Thüringen"},
    {"slug": "halle", "name": "Halle", "region": "Sachsen-Anhalt"},
    {"slug": "kassel", "name": "Kassel", "region": "Hessen"},
    {"slug": "magdeburg", "name": "Magdeburg", "region": "Sachsen-Anhalt"},
    {"slug": "saarbruecken", "name": "Saarbrücken", "region": "Saarland"},
    {"slug": "luebeck", "name": "Lübeck", "region": "Schleswig-Holstein"},
    {"slug": "potsdam", "name": "Potsdam", "region": "Brandenburg", "country": "DE"},
    {"slug": "oldenburg", "name": "Oldenburg", "region": "Niedersachsen"},
    {"slug": "osnabrueck", "name": "Osnabrück", "region": "Niedersachsen"},
    {"slug": "heidelberg", "name": "Heidelberg", "region": "Baden-Württemberg"},
    {"slug": "darmstadt", "name": "Darmstadt", "region": "Hessen"},
    {"slug": "regensburg", "name": "Regensburg", "region": "Bayern"},
    {"slug": "ingolstadt", "name": "Ingolstadt", "region": "Bayern"},
    {"slug": "wuerzburg", "name": "Würzburg", "region": "Bayern"},
    {"slug": "fuerth", "name": "Fürth", "region": "Bayern"},
    {"slug": "ulm", "name": "Ulm", "region": "Baden-Württemberg"},
    {"slug": "heilbronn", "name": "Heilbronn", "region": "Baden-Württemberg"},
    {"slug": "pforzheim", "name": "Pforzheim", "region": "Baden-Württemberg"},
    {"slug": "offenbach", "name": "Offenbach", "region": "Hessen"},
    {"slug": "goettingen", "name": "Göttingen", "region": "Niedersachsen"},
    {"slug": "bottrop", "name": "Bottrop", "region": "NRW"},
    {"slug": "reutlingen", "name": "Reutlingen", "region": "Baden-Württemberg"},
    {"slug": "koblenz", "name": "Koblenz", "region": "Rheinland-Pfalz"},
    {"slug": "bremerhaven", "name": "Bremerhaven", "region": "Bremen"},
    {"slug": "remscheid", "name": "Remscheid", "region": "NRW"},
    {"slug": "bergisch-gladbach", "name": "Bergisch Gladbach", "region": "NRW"},
    {"slug": "jena", "name": "Jena", "region": "Thüringen"},
    {"slug": "erlangen", "name": "Erlangen", "region": "Bayern"},
    {"slug": "trier", "name": "Trier", "region": "Rheinland-Pfalz"},
    {"slug": "moers", "name": "Moers", "region": "NRW"},
    {"slug": "siegen", "name": "Siegen", "region": "NRW"},
    {"slug": "hildesheim", "name": "Hildesheim", "region": "Niedersachsen"},
    {"slug": "salzgitter", "name": "Salzgitter", "region": "Niedersachsen"},
    {"slug": "cottbus", "name": "Cottbus", "region": "Brandenburg"},
    {"slug": "guetersloh", "name": "Gütersloh", "region": "NRW"},
    {"slug": "witten", "name": "Witten", "region": "NRW"},
    {"slug": "schwerin", "name": "Schwerin", "region": "Mecklenburg-Vorpommern"},
    {"slug": "gera", "name": "Gera", "region": "Thüringen"},
    {"slug": "iserlohn", "name": "Iserlohn", "region": "NRW"},
    {"slug": "ludwigshafen", "name": "Ludwigshafen", "region": "Rheinland-Pfalz"},
    {"slug": "hanau", "name": "Hanau", "region": "Hessen"},
    {"slug": "flensburg", "name": "Flensburg", "region": "Schleswig-Holstein"},
    {"slug": "esslingen", "name": "Esslingen", "region": "Baden-Württemberg"},
    {"slug": "tuebingen", "name": "Tübingen", "region": "Baden-Württemberg"},
    {"slug": "bayreuth", "name": "Bayreuth", "region": "Bayern"},
    {"slug": "delmenhorst", "name": "Delmenhorst", "region": "Niedersachsen"},
    {"slug": "neuss", "name": "Neuss", "region": "NRW"},
    {"slug": "aschaffenburg", "name": "Aschaffenburg", "region": "Bayern"},
    {"slug": "plauen", "name": "Plauen", "region": "Sachsen"},
    {"slug": "bocholt", "name": "Bocholt", "region": "NRW"},
    {"slug": "zwickau", "name": "Zwickau", "region": "Sachsen"},
    {"slug": "neuwied", "name": "Neuwied", "region": "Rheinland-Pfalz"},
    {"slug": "unna", "name": "Unna", "region": "NRW"},
    {"slug": "neubrandenburg", "name": "Neubrandenburg", "region": "Mecklenburg-Vorpommern"},
    {"slug": "fulda", "name": "Fulda", "region": "Hessen"},
    {"slug": "konstanz", "name": "Konstanz", "region": "Baden-Württemberg"},
    {"slug": "marburg", "name": "Marburg", "region": "Hessen"},
    {"slug": "rheine", "name": "Rheine", "region": "NRW"},
    {"slug": "viersen", "name": "Viersen", "region": "NRW"},
    {"slug": "castrop-rauxel", "name": "Castrop-Rauxel", "region": "NRW"},
    {"slug": "ratingen", "name": "Ratingen", "region": "NRW"},
    {"slug": "luedenscheid", "name": "Lüdenscheid", "region": "NRW"},
    {"slug": "arnsberg", "name": "Arnsberg", "region": "NRW"},
    {"slug": "gladbeck", "name": "Gladbeck", "region": "NRW"},
    {"slug": "dorsten", "name": "Dorsten", "region": "NRW"},
    {"slug": "sindelfingen", "name": "Sindelfingen", "region": "Baden-Württemberg"},
    {"slug": "wesel", "name": "Wesel", "region": "NRW"},
    {"slug": "detmold", "name": "Detmold", "region": "NRW"},
    {"slug": "landshut", "name": "Landshut", "region": "Bayern"},
    {"slug": "bamberg", "name": "Bamberg", "region": "Bayern"},
    {"slug": "passau", "name": "Passau", "region": "Bayern"},
    {"slug": "kempten", "name": "Kempten", "region": "Bayern"},
    {"slug": "rosenheim", "name": "Rosenheim", "region": "Bayern"},
    {"slug": "schweinfurt", "name": "Schweinfurt", "region": "Bayern"},
    {"slug": "stralsund", "name": "Stralsund", "region": "Mecklenburg-Vorpommern"},
    {"slug": "brandenburg-havel", "name": "Brandenburg an der Havel", "region": "Brandenburg"},
    {"slug": "weimar", "name": "Weimar", "region": "Thüringen"},
    {"slug": "suhl", "name": "Suhl", "region": "Thüringen"},
    {"slug": "nordhausen", "name": "Nordhausen", "region": "Thüringen"},
    {"slug": "dessau", "name": "Dessau-Roßlau", "region": "Sachsen-Anhalt"},
    {"slug": "wolfenbuettel", "name": "Wolfenbüttel", "region": "Niedersachsen"},
    {"slug": "celle", "name": "Celle", "region": "Niedersachsen"},
    {"slug": "wilhelmshaven", "name": "Wilhelmshaven", "region": "Niedersachsen"},
    {"slug": "emden", "name": "Emden", "region": "Niedersachsen"},
    {"slug": "speyer", "name": "Speyer", "region": "Rheinland-Pfalz"},
    {"slug": "ludwigsburg", "name": "Ludwigsburg", "region": "Baden-Württemberg"},
    {"slug": "ravensburg", "name": "Ravensburg", "region": "Baden-Württemberg"},
    {"slug": "villingen-schwenningen", "name": "Villingen-Schwenningen", "region": "Baden-Württemberg"},
]

SEO_CITIES_AT: list[dict[str, str]] = [
    {"slug": "wien", "name": "Wien", "region": "Wien", "country": "AT"},
    {"slug": "graz", "name": "Graz", "region": "Steiermark", "country": "AT"},
    {"slug": "linz", "name": "Linz", "region": "Oberösterreich", "country": "AT"},
    {"slug": "salzburg", "name": "Salzburg", "region": "Salzburg", "country": "AT"},
    {"slug": "innsbruck", "name": "Innsbruck", "region": "Tirol", "country": "AT"},
    {"slug": "klagenfurt", "name": "Klagenfurt", "region": "Kärnten", "country": "AT"},
    {"slug": "villach", "name": "Villach", "region": "Kärnten", "country": "AT"},
    {"slug": "wels", "name": "Wels", "region": "Oberösterreich", "country": "AT"},
    {"slug": "st-poelten", "name": "St. Pölten", "region": "Niederösterreich", "country": "AT"},
    {"slug": "dornbirn", "name": "Dornbirn", "region": "Vorarlberg", "country": "AT"},
]

SEO_CITIES_CH: list[dict[str, str]] = [
    {"slug": "zuerich", "name": "Zürich", "region": "Zürich", "country": "CH"},
    {"slug": "bern", "name": "Bern", "region": "Bern", "country": "CH"},
    {"slug": "basel", "name": "Basel", "region": "Basel-Stadt", "country": "CH"},
    {"slug": "genf", "name": "Genf", "region": "Genf", "country": "CH"},
    {"slug": "lausanne", "name": "Lausanne", "region": "Waadt", "country": "CH"},
    {"slug": "luzern", "name": "Luzern", "region": "Luzern", "country": "CH"},
    {"slug": "st-gallen", "name": "St. Gallen", "region": "St. Gallen", "country": "CH"},
    {"slug": "winterthur", "name": "Winterthur", "region": "Zürich", "country": "CH"},
    {"slug": "lugano", "name": "Lugano", "region": "Tessin", "country": "CH"},
    {"slug": "biel", "name": "Biel", "region": "Bern", "country": "CH"},
]

def all_seo_cities() -> list[dict[str, str]]:
    de = [{**c, "country": c.get("country", "DE")} for c in SEO_CITIES]
    return de + SEO_CITIES_AT + SEO_CITIES_CH

# Long-Tail SEO (Google-Suchen ohne Stadt)
SEO_TOPICS: list[dict[str, str]] = [
    {
        "slug": "ohne-fake-moderatoren",
        "title": "Dating ohne Fake-Moderatoren",
        "desc": "Echte Singles statt Chat-Agenten: Jami-Dating ohne Animatoren und Fake-Profile.",
        "h1": "Dating ohne Fake-Moderatoren",
    },
    {
        "slug": "partnersuche-deutschland",
        "title": "Partnersuche Deutschland – echte Singles",
        "desc": "Partnersuche in ganz Deutschland. Swipen, matchen, chatten – 100 Gratis-Coins.",
        "h1": "Partnersuche in Deutschland",
    },
    {
        "slug": "singleboerse-kostenlos",
        "title": "Singlebörse kostenlos testen",
        "desc": "Singlebörse kostenlos registrieren, 100 Coins geschenkt. Fair chatten ohne Abo.",
        "h1": "Singlebörse kostenlos testen",
    },
    {
        "slug": "flirt-app-deutsch",
        "title": "Flirt-App auf Deutsch",
        "desc": "Deutsche Flirt-App mit Entfernung in km und Herkunft auf dem Profil.",
        "h1": "Flirt-App auf Deutsch",
    },
    {
        "slug": "kennenlernen-ab-18",
        "title": "Kennenlernen ab 18 – sicher & ehrlich",
        "desc": "Ab 18 registrieren, echte Personen, Melden & Blockieren eingebaut.",
        "h1": "Kennenlernen ab 18",
    },
    {
        "slug": "dating-mit-entfernung",
        "title": "Dating mit km-Entfernung",
        "desc": "Sieh sofort wie weit dein Match entfernt ist – Stadt, Land, Kilometer.",
        "h1": "Dating mit Entfernung in km",
    },
    {
        "slug": "chat-dating-echt",
        "title": "Echter Chat-Dating – keine Bots",
        "desc": "Nur registrierte Nutzer im Chat. Keine vorgegebenen Moderatoren-Antworten.",
        "h1": "Echter Chat beim Dating",
    },
    {
        "slug": "coins-statt-abo",
        "title": "Dating mit Coins statt Abo-Falle",
        "desc": "Transparent: 10 Coins pro Nachricht. Pakete ab 2,99 € – kein monatliches Abo.",
        "h1": "Coins statt Abo-Falle",
    },
    {
        "slug": "schwaebisch-gmuend",
        "title": "Singles in Schwäbisch Gmünd",
        "desc": "Lokale Partnersuche in Schwäbisch Gmünd und Umgebung.",
        "h1": "Singles in Schwäbisch Gmünd",
    },
    {
        "slug": "tapfheim",
        "title": "Singles in Tapfheim & Donau-Ries",
        "desc": "Dating in Tapfheim, Donauwörth, Dillingen – echte Menschen aus der Region.",
        "h1": "Singles in Tapfheim & Umgebung",
    },
    {
        "slug": "oesterreich",
        "title": "Dating Österreich – echte Singles",
        "desc": "Partnersuche in Österreich: Wien, Graz, Salzburg und mehr. 100 Gratis-Coins.",
        "h1": "Dating in Österreich",
    },
    {
        "slug": "schweiz",
        "title": "Dating Schweiz – Singles CH",
        "desc": "Partnersuche in der Schweiz: Zürich, Bern, Basel, Genf. Keine Fake-Moderatoren.",
        "h1": "Dating in der Schweiz",
    },
    {
        "slug": "dach-region",
        "title": "Dating D-A-CH – Deutschland Österreich Schweiz",
        "desc": "Jami-Dating für die DACH-Region. Echte Nutzer, km-Entfernung, fairer Coin-Preis.",
        "h1": "Dating in D-A-CH",
    },
    {
        "slug": "ue40-singles",
        "title": "Dating ab 40 – seriöse Singles",
        "desc": "Partnersuche ab 40: echte Profile, keine Fake-Moderatoren, fair chatten mit Coins.",
        "h1": "Dating ab 40 – Ü40 Singles",
    },
    {
        "slug": "single-mama",
        "title": "Single Mama Dating",
        "desc": "Single mit Kind? Echte Singles kennenlernen – transparent, ohne Abo-Falle.",
        "h1": "Single Mama – Partnersuche",
    },
    {
        "slug": "single-papa",
        "title": "Single Papa Dating",
        "desc": "Allein erziehender Vater? Finde echte Matches in deiner Nähe.",
        "h1": "Single Papa – Partnersuche",
    },
    {
        "slug": "partnersuche-50-plus",
        "title": "Partnersuche 50 Plus",
        "desc": "Liebe kennt kein Alter – Jami für Singles 50+ in Deutschland.",
        "h1": "Partnersuche 50 Plus",
    },
    {
        "slug": "alleinerziehend-dating",
        "title": "Alleinerziehend Dating",
        "desc": "Dating für Alleinerziehende – ehrlich, ohne Chat-Agenten.",
        "h1": "Alleinerziehend – Dating",
    },
    {
        "slug": "serioese-partnersuche",
        "title": "Seriöse Partnersuche",
        "desc": "Keine Fake-Profile, keine Moderatoren – nur echte registrierte Nutzer.",
        "h1": "Seriöse Partnersuche",
    },
    {
        "slug": "neu-single",
        "title": "Neu Single – wieder kennenlernen",
        "desc": "Frisch getrennt? Starte locker mit 100 Gratis-Coins bei Jami.",
        "h1": "Neu Single – wieder starten",
    },
    {
        "slug": "dating-app-vergleich",
        "title": "Dating-App Vergleich – ehrlich & ohne Abo",
        "desc": "Coins statt Abo-Falle: Jami im Vergleich zu klassischen Singlebörsen.",
        "h1": "Dating-App Vergleich",
    },
    {
        "slug": "online-dating-tipps",
        "title": "Online-Dating Tipps für echte Dates",
        "desc": "Profil, erste Nachricht, Sicherheit – plus 100 Gratis-Coins bei Jami.",
        "h1": "Online-Dating Tipps",
    },
    {
        "slug": "partnersuche-bayern",
        "title": "Partnersuche Bayern",
        "desc": "Singles in München, Nürnberg, Augsburg und ganz Bayern – Jami-Dating.",
        "h1": "Partnersuche in Bayern",
    },
    {
        "slug": "partnersuche-nrw",
        "title": "Partnersuche NRW",
        "desc": "Dating in Köln, Düsseldorf, Dortmund, Essen – echte Profile, km-Entfernung.",
        "h1": "Partnersuche in NRW",
    },
]

MICRO_TOOLS = [
    {"path": "bewerbung", "title": "Bewerbungs-Pro", "price": "4,99", "desc": "Lebenslauf + Anschreiben PDF"},
    {"path": "rechnung", "title": "Rechnung-Pro", "price": "2,99", "desc": "Rechnung erstellen & PDF"},
    {"path": "angebot", "title": "Angebot-Pro", "price": "3,49", "desc": "Kostenvoranschlag & Angebot PDF"},
    {"path": "briefe", "title": "Briefe-Pro", "price": "3,99", "desc": "Mahnung & Kündigung PDF"},
]

BUNDLE_PRICE = "9,99"
PAYPAL_EMAIL = "david.prechtel1986@gmail.com"


def indexnow_key(site_url: str) -> str:
    h = hashlib.sha256(f"jami-indexnow-{site_url}".encode()).hexdigest()
    return h[:32]


def _city_page_html(city: dict[str, str], site_url: str) -> str:
    name = city["name"]
    region = city["region"]
    slug = city["slug"]
    country = city.get("country", "DE")
    country_label = {"DE": "Deutschland", "AT": "Österreich", "CH": "Schweiz"}.get(country, country)
    base = site_url.rstrip("/")
    reg_url = f"{base}/?utm_source=seo&utm_medium=landing&utm_campaign={slug}"
    title = f"Singles in {name} kennenlernen – Jami Dating {region}"
    desc = (
        f"Echte Singles in {name} ({region}, {country_label}): Swipen, Matchen, Chatten. "
        f"100 Gratis-Coins, keine Fake-Moderatoren. Kostenlos registrieren – 18+."
    )
    return f"""<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <title>{title}</title>
  <meta name="description" content="{desc}"/>
  <link rel="canonical" href="{base}/dating-{slug}.html"/>
  <meta property="og:title" content="{title}"/>
  <meta property="og:description" content="{desc}"/>
  <meta property="og:url" content="{base}/dating-{slug}.html"/>
  <meta property="og:type" content="website"/>
  <style>
    :root {{ --bg:#1a0a24; --card:#2a1538; --pink:#ff6b9d; --text:#f5f0f8; --muted:#b8a8c8; }}
    * {{ box-sizing:border-box; }}
    body {{ margin:0; font-family:Segoe UI,system-ui,sans-serif; background:var(--bg); color:var(--text);
      background-image:radial-gradient(ellipse 70% 50% at 50% -10%, rgba(255,107,157,0.2), transparent); }}
    .wrap {{ max-width:720px; margin:0 auto; padding:2rem 1.25rem 3rem; }}
    h1 {{ font-size:clamp(1.5rem,4vw,2rem); margin:0 0 0.75rem; line-height:1.25; }}
    h1 em {{ color:var(--pink); font-style:normal; }}
    p {{ line-height:1.6; color:var(--muted); }}
    ul {{ line-height:1.7; color:var(--muted); padding-left:1.2rem; }}
    .cta {{
      display:inline-block; margin-top:1.25rem; padding:1rem 1.5rem;
      background:linear-gradient(135deg,#ff4d8d,#b84dff); color:#fff; text-decoration:none;
      font-weight:700; border-radius:14px; font-size:1.05rem;
    }}
    .card {{ background:var(--card); border:1px solid rgba(255,107,157,0.25); border-radius:16px; padding:1.5rem; margin-top:1.5rem; }}
    footer {{ margin-top:2rem; font-size:0.8rem; color:#7a6a8a; }}
    footer a {{ color:var(--pink); }}
  </style>
  <script type="application/ld+json">
  {json.dumps({
      "@context": "https://schema.org",
      "@type": "WebPage",
      "name": title,
      "description": desc,
      "url": f"{base}/dating-{slug}.html",
      "isPartOf": {"@type": "WebSite", "name": "Jami-Dating", "url": base},
  }, ensure_ascii=False)}
  </script>
</head>
<body>
  <div class="wrap">
    <h1>Singles in <em>{name}</em> – echte Dates ohne Fake-Profile</h1>
    <p>{desc}</p>
    <div class="card">
      <p><strong>Warum Jami in {name}?</strong></p>
      <ul>
        <li>Nur registrierte echte Nutzer – keine Chat-Moderatoren</li>
        <li>Herkunft &amp; Entfernung in km auf dem Profil</li>
        <li>100 Gratis-Coins beim Start – fair chatten (10 Coins/Nachricht)</li>
        <li>Swipe, Match, Chat – kostenlos testen</li>
      </ul>
      <a class="cta" href="{reg_url}">Jetzt kostenlos in {name} registrieren →</a>
    </div>
    <footer>
      18+ · <a href="{base}/impressum.html">Impressum</a> ·
      <a href="{base}/datenschutz.html">Datenschutz</a> ·
      <a href="{base}/">Jami Startseite</a>
    </footer>
  </div>
</body>
</html>"""


def _topic_page_html(topic: dict[str, str], site_url: str) -> str:
    slug = topic["slug"]
    base = site_url.rstrip("/")
    reg_url = f"{base}/?utm_source=seo&utm_medium=topic&utm_campaign={slug}"
    title = topic["title"]
    desc = topic["desc"]
    h1 = topic["h1"]
    return f"""<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <title>{title} – Jami-Dating</title>
  <meta name="description" content="{desc}"/>
  <link rel="canonical" href="{base}/guide-{slug}.html"/>
  <style>
    body {{ margin:0; font-family:Segoe UI,sans-serif; background:#1a0a24; color:#f5f0f8; line-height:1.6; }}
    .wrap {{ max-width:720px; margin:0 auto; padding:2rem 1.25rem; }}
    h1 {{ color:#ff6b9d; }}
    a.cta {{ display:inline-block; margin-top:1rem; padding:1rem 1.4rem; background:linear-gradient(135deg,#ff4d8d,#b84dff);
      color:#fff; text-decoration:none; font-weight:700; border-radius:12px; }}
    p {{ color:#d8cce8; }}
  </style>
</head>
<body>
  <div class="wrap">
    <h1>{h1}</h1>
    <p>{desc}</p>
    <p>100 Gratis-Coins · Keine Fake-Moderatoren · Herkunft &amp; km sichtbar · 18+</p>
    <a class="cta" href="{reg_url}">Jetzt kostenlos bei Jami starten</a>
    <p style="margin-top:2rem;font-size:0.85rem;"><a href="{base}/" style="color:#ff6b9d;">Jami-Dating Startseite</a></p>
  </div>
</body>
</html>"""


def _single_page_html(city: dict[str, str], site_url: str) -> str:
    name = city["name"]
    region = city["region"]
    slug = city["slug"]
    country = city.get("country", "DE")
    base = site_url.rstrip("/")
    reg_url = f"{base}/?utm_source=seo&utm_medium=single&utm_campaign={slug}"
    title = f"Single in {name} – Partnersuche & Kennenlernen"
    desc = (
        f"Single in {name} ({region})? Partnersuche ohne Fake-Moderatoren. "
        f"100 Gratis-Coins, echte Nutzer, km-Entfernung. Kostenlos bei Jami – 18+."
    )
    return f"""<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <title>{title}</title>
  <meta name="description" content="{desc}"/>
  <link rel="canonical" href="{base}/single-{slug}.html"/>
  <style>
    body {{ margin:0; font-family:Segoe UI,sans-serif; background:#1a0a24; color:#f5f0f8; line-height:1.6; }}
    .wrap {{ max-width:720px; margin:0 auto; padding:2rem 1.25rem; }}
    h1 {{ color:#ff6b9d; font-size:clamp(1.4rem,4vw,1.9rem); }}
    p {{ color:#d8cce8; }}
    a.cta {{ display:inline-block; margin-top:1rem; padding:1rem 1.4rem; background:linear-gradient(135deg,#ff4d8d,#b84dff);
      color:#fff; text-decoration:none; font-weight:700; border-radius:12px; }}
    footer {{ margin-top:2rem; font-size:0.8rem; color:#7a6a8a; }}
    footer a {{ color:#ff6b9d; }}
  </style>
</head>
<body>
  <div class="wrap">
    <h1>Single in {name} – jetzt kennenlernen</h1>
    <p>{desc}</p>
    <p>Swipe, Match, Chat – fair mit Coins, kein monatliches Abo. Herkunft &amp; Entfernung sichtbar.</p>
    <a class="cta" href="{reg_url}">Kostenlos registrieren in {name} →</a>
    <footer>
      18+ · <a href="{base}/dating-{slug}.html">Mehr zu Singles in {name}</a> ·
      <a href="{base}/">Jami Startseite</a>
    </footer>
  </div>
</body>
</html>"""


def _tools_hub_html(site_url: str) -> str:
    base = site_url.rstrip("/")
    items = "\n".join(
        f'<li><a href="{base}/{t["path"]}/">{t["title"]}</a> – {t["desc"]} ({t["price"]} EUR)</li>'
        for t in MICRO_TOOLS
    )
    return f"""<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <title>Gratis-Tools &amp; PDF-Downloads – Jami</title>
  <meta name="description" content="Bewerbung, Rechnung und mehr – digitale Tools mit PayPal."/>
  <style>
    body {{ font-family:Segoe UI,sans-serif; background:#0c1220; color:#eef3fb; max-width:640px; margin:2rem auto; padding:1rem; }}
    h1 {{ font-size:1.4rem; }}
    li {{ margin:0.6rem 0; }}
    a {{ color:#4f8cff; }}
  </style>
</head>
<body>
  <h1>Digitale Tools (PayPal &amp; Stripe)</h1>
  <p>Vorschau gratis – PDF-Export per PayPal oder Stripe (Karte, PayPal, Klarna)</p>
  <ul>{items}</ul>
  <p><a href="{base}/bundle.html"><strong>Alle 4 Tools im Bundle für {BUNDLE_PRICE} EUR</strong></a></p>
  <p><a href="{base}/">Zurück zu Jami-Dating</a></p>
  <script src="/js/tools-funnel.js" defer></script>
</body>
</html>"""


def _bundle_page_html(site_url: str) -> str:
    base = site_url.rstrip("/")
    items = "".join(f"<li>{t['title']} ({t['price']} EUR einzeln)</li>" for t in MICRO_TOOLS)
    return f"""<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <title>Tool-Bundle – alle PDF-Tools für {BUNDLE_PRICE} EUR</title>
  <meta name="description" content="Bewerbung, Rechnung, Angebot, Briefe – alle Tools im Paket. {BUNDLE_PRICE} EUR per PayPal oder Stripe."/>
  <style>
    body {{ font-family:Segoe UI,sans-serif; background:#0c1220; color:#eef3fb; max-width:640px; margin:2rem auto; padding:1rem; }}
    h1 {{ color:#ffd166; }}
    .price {{ font-size:2rem; font-weight:700; color:#34d399; }}
    a.cta {{ display:inline-block; margin-top:1rem; padding:1rem 1.4rem; background:linear-gradient(135deg,#ffd166,#ff6b9d);
      color:#1a0a24; text-decoration:none; font-weight:700; border-radius:12px; }}
    li {{ margin:0.4rem 0; }}
  </style>
</head>
<body>
  <h1>Alle Tools – Bundle</h1>
  <p class="price">{BUNDLE_PRICE} EUR</p>
  <p>Statt einzeln kaufen – alle 4 PDF-Tools freischalten:</p>
  <ul>{items}</ul>
  <p>Nach Zahlung erhältst du Zugang zu allen Tools (30 Tage auf diesem Gerät).</p>
  <a class="cta" id="buy" href="#">PayPal {BUNDLE_PRICE} EUR</a>
  <a class="cta" id="btn-stripe-bundle" href="#" style="margin-left:0.5rem;background:linear-gradient(135deg,#635bff,#4f8cff);color:#fff">Stripe (Karte/PayPal)</a>
  <p style="margin-top:1.5rem"><a href="{base}/tools.html" style="color:#4f8cff">Einzelne Tools</a> ·
  <a href="{base}/" style="color:#4f8cff">Jami-Dating</a></p>
  <script src="/js/tools-pay.js" defer></script>
  <script>
    const q = new URLSearchParams({{
      cmd:'_xclick', business:'{PAYPAL_EMAIL}', currency_code:'EUR', amount:'{BUNDLE_PRICE.replace(",", ".")}',
      item_name:'Jami Tool-Bundle (alle PDF-Tools)',
      return: location.origin + '/bundle-danke.html', cancel_return: location.href
    }});
    document.getElementById('buy').href = 'https://www.paypal.com/cgi-bin/webscr?' + q;
    if (location.search.includes('unlocked=1')) {{
      localStorage.setItem('jamiToolBundle', JSON.stringify({{ until: Date.now() + 30*86400000 }}));
      ['bewerbungProPaid','rechnungProPaid','angebotProPaid','briefeProPaid'].forEach(k =>
        localStorage.setItem(k, JSON.stringify({{ until: Date.now() + 30*86400000 }})));
    }}
  </script>
</body>
</html>"""


def _bundle_danke_html(site_url: str) -> str:
    base = site_url.rstrip("/")
    return f"""<!DOCTYPE html>
<html lang="de"><head><meta charset="utf-8"/><title>Bundle freigeschaltet</title></head>
<body style="font-family:system-ui;text-align:center;padding:2rem;background:#0c1220;color:#fff;">
  <h1>Danke!</h1><p>Alle Tools freigeschaltet.</p>
  <script src="/js/tools-pay.js" defer></script>
  <script>
    const u = Date.now() + 30*86400000;
    ['jamiToolBundle','bewerbungProPaid','rechnungProPaid','angebotProPaid','briefeProPaid']
      .forEach(k => localStorage.setItem(k, JSON.stringify({{ until: u }})));
    setTimeout(() => location.href = '{base}/tools.html?unlocked=1', 1200);
  </script>
  <a href="{base}/tools.html?unlocked=1" style="color:#34d399">Zu den Tools</a>
</body></html>"""


def write_seo_pages(site_root: Path, *, site_url: str) -> list[str]:
    """Schreibt Stadt-Landingpages, sitemap.xml und IndexNow-Key. Gibt alle URLs zurück."""
    site_root = Path(site_root)
    site_root.mkdir(parents=True, exist_ok=True)
    base = site_url.rstrip("/")
    urls: list[str] = [
        f"{base}/",
        f"{base}/werben.html",
        f"{base}/promo.html",
        f"{base}/tools.html",
        f"{base}/bewerbung/",
        f"{base}/rechnung/",
        f"{base}/angebot/",
        f"{base}/briefe/",
        f"{base}/bundle.html",
    ]

    (site_root / "tools.html").write_text(_tools_hub_html(base), encoding="utf-8")
    (site_root / "bundle.html").write_text(_bundle_page_html(base), encoding="utf-8")
    (site_root / "bundle-danke.html").write_text(_bundle_danke_html(base), encoding="utf-8")

    for city in all_seo_cities():
        slug = city["slug"]
        fname = f"dating-{slug}.html"
        (site_root / fname).write_text(
            _city_page_html(city, base), encoding="utf-8"
        )
        urls.append(f"{base}/{fname}")
        single_fname = f"single-{slug}.html"
        (site_root / single_fname).write_text(
            _single_page_html(city, base), encoding="utf-8"
        )
        urls.append(f"{base}/{single_fname}")

    for topic in SEO_TOPICS:
        slug = topic["slug"]
        fname = f"guide-{slug}.html"
        (site_root / fname).write_text(_topic_page_html(topic, base), encoding="utf-8")
        urls.append(f"{base}/{fname}")

    key = indexnow_key(base)
    (site_root / f"{key}.txt").write_text(key, encoding="utf-8")
    (site_root / "indexnow-key.txt").write_text(key, encoding="utf-8")
    (site_root / "seo-slugs.json").write_text(
        json.dumps(
            {
                "cities": [c["slug"] for c in all_seo_cities()],
                "singles": [c["slug"] for c in all_seo_cities()],
                "guides": [t["slug"] for t in SEO_TOPICS],
            },
            ensure_ascii=False,
        ),
        encoding="utf-8",
    )

    sitemap_lines = ['<?xml version="1.0" encoding="UTF-8"?>']
    sitemap_lines.append('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">')
    for u in urls:
        sitemap_lines.append(f"  <url><loc>{u}</loc><changefreq>weekly</changefreq></url>")
    sitemap_lines.append("</urlset>")
    (site_root / "sitemap.xml").write_text("\n".join(sitemap_lines), encoding="utf-8")

    robots = site_root / "robots.txt"
    robots.write_text(
        f"User-agent: *\nAllow: /\nSitemap: {base}/sitemap.xml\n",
        encoding="utf-8",
    )
    return urls
