#!/usr/bin/env python3
"""Generate server-rendered English Ghost templates from bilingual source templates."""
from __future__ import annotations

import html
import re
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]

PAGES = {
    "index": {
        "target": "index-en.hbs",
        "path": "",
        "title": "Cosmos Luminosity — living choice",
        "description": "Practices for thinking, state, body and meaning that support living choice.",
    },
    "page-magic-cloud": {
        "target": "page-magic-cloud-en.hbs",
        "path": "magic-cloud/",
        "title": "Magic Cloud — Cosmos Luminosity",
        "description": "A symbolic question practice for seeing one situation differently and choosing a concrete next step.",
    },
    "page-audioboosts": {
        "target": "page-audioboosts-en.hbs",
        "path": "audioboosts/",
        "title": "AudioBoosts — Cosmos Luminosity",
        "description": "Self-guided audio practices for attention, rhythm and integrating a chosen state.",
    },
    "page-gateways": {
        "target": "page-gateways-en.hbs",
        "path": "gateways/",
        "title": "Gateways — Cosmos Luminosity",
        "description": "An in-person light-touch practice supporting spaciousness, calm, clarity and presence.",
    },
    "page-portal": {
        "target": "page-portal-en.hbs",
        "path": "portal/",
        "title": "Portal — Cosmos Luminosity",
        "description": "A digital environment connecting knowledge, practices, art and research into personal routes.",
    },
    "page-cosmos-cacao": {
        "target": "page-cosmos-cacao-en.hbs",
        "path": "cosmos-cacao/",
        "title": "Cosmos Cacao — Cosmos Luminosity",
        "description": "Ceremonial cacao and a state journey for solo, couple or group practice.",
    },
    "page-lumoside": {
        "target": "page-lumoside-en.hbs",
        "path": "lumoside/",
        "title": "LumoSide — Cosmos Luminosity",
        "description": "A private online space for audio practices, body, intuition and new states.",
    },
    "page-privacy": {
        "target": "page-privacy-en.hbs",
        "path": "privacy/",
        "title": "Privacy policy — Cosmos Luminosity",
        "description": "How Cosmos Luminosity handles newsletter email addresses and privacy requests.",
    },
    "page-contact": {
        "target": "page-contact-en.hbs",
        "path": "contact/",
        "title": "Contact — Cosmos Luminosity",
        "description": "Contact Cosmos Luminosity about practices, participation terms or personal data.",
    },
    "page-webinar": {
        "target": "page-webinar-en.hbs",
        "path": "webinar/",
        "title": "Living Choice webinar — Cosmos Luminosity",
        "description": "A 90-minute live webinar for turning an inner signal into one real next step. $77 USD.",
    },
    "page-terms": {
        "target": "page-terms-en.hbs",
        "path": "terms/",
        "title": "Terms of sale — Cosmos Luminosity",
        "description": "Terms for buying and accessing Cosmos Luminosity webinars and digital products.",
    },
    "page-refund-policy": {
        "target": "page-refund-policy-en.hbs",
        "path": "refund-policy/",
        "title": "Refund policy — Cosmos Luminosity",
        "description": "Cancellation, rescheduling and refund rules for Cosmos Luminosity webinars and digital products.",
    },
}

LEAF = re.compile(
    r"(?P<open><(?P<tag>[a-zA-Z][\w:-]*)\b[^>]*\bdata-en=\"(?P<en>[^\"]*)\"[^>]*>)"
    r"(?P<text>[^<]*)"
    r"(?P<close></(?P=tag)>)"
)


def replace_attr(tag: str, name: str, value: str) -> str:
    escaped = html.escape(html.unescape(value), quote=True)
    pattern = re.compile(rf"\b{name}=\"[^\"]*\"")
    if pattern.search(tag):
        return pattern.sub(f'{name}="{escaped}"', tag, count=1)
    return tag[:-1] + f' {name}="{escaped}">'


def localize_leaf(match: re.Match[str]) -> str:
    return match.group("open") + html.unescape(match.group("en")) + match.group("close")


def localize_opening_tags(source: str) -> str:
    def transform(match: re.Match[str]) -> str:
        tag = match.group(0)
        en_aria = re.search(r'\bdata-aria-en="([^"]*)"', tag)
        en_alt = re.search(r'\bdata-alt-en="([^"]*)"', tag)
        if en_aria:
            tag = replace_attr(tag, "aria-label", en_aria.group(1))
        if en_alt:
            tag = replace_attr(tag, "alt", en_alt.group(1))
        return tag

    return re.sub(r"<[a-zA-Z][^>]*>", transform, source)


def prefix_internal_links(source: str) -> str:
    # Preserve assets, external URLs, fragments, mailto links and the English root itself.
    return re.sub(r'href="/(?!en(?:/|\")|/)([^"{}]*)"', r'href="/en/\1"', source)


def metadata(meta: dict[str, str]) -> str:
    ru = f"https://www.cosmosluminosity.com/{meta['path']}"
    en = f"https://www.cosmosluminosity.com/en/{meta['path']}"
    return (
        '{{! Generated by tools/generate_english_templates.py; edit the bilingual source instead. }}\n'
        '{{!< default-en}}\n'
        f'{{{{#contentFor "page_title"}}}}{meta["title"]}{{{{/contentFor}}}}\n'
        f'{{{{#contentFor "page_description"}}}}{meta["description"]}{{{{/contentFor}}}}\n'
        f'{{{{#contentFor "canonical_url"}}}}{en}{{{{/contentFor}}}}\n'
        f'{{{{#contentFor "ru_url"}}}}{ru}{{{{/contentFor}}}}\n'
        f'{{{{#contentFor "en_url"}}}}{en}{{{{/contentFor}}}}\n'
    )


def generate_page(source_name: str, meta: dict[str, str]) -> None:
    source = (ROOT / f"{source_name}.hbs").read_text(encoding="utf-8")
    source = re.sub(r"^\{\{!< default\}\}\s*", "", source, count=1)
    # The bilingual source owns Russian metadata. English metadata is emitted
    # above by metadata(); retaining these blocks makes Ghost resolve duplicate
    # contentFor values and can leak Russian canonical/title data into /en/.
    source = re.sub(
        r'^\{\{#contentFor "(?:page_title|page_description|canonical_url|ru_url|en_url)"\}\}.*?\{\{/contentFor\}\}\s*',
        "",
        source,
        flags=re.MULTILINE,
    )
    source = re.sub(r'^<div data-title-ru="[^"]*" data-title-en="[^"]*"></div>\s*', "", source, count=1)
    localized = LEAF.sub(localize_leaf, source)
    localized = localize_opening_tags(localized)
    localized = prefix_internal_links(localized)
    # Dynamic helpers should keep English URLs after user interaction.
    localized = localized.replace("href:item.href+(lang==='en'?'?lang=en':'')", "href:'/en'+item.href")
    (ROOT / meta["target"]).write_text(metadata(meta) + localized, encoding="utf-8")


def generate_layout() -> None:
    source = (ROOT / "default.hbs").read_text(encoding="utf-8")
    localized = LEAF.sub(localize_leaf, source)
    localized = localize_opening_tags(localized)
    localized = prefix_internal_links(localized)
    localized = localized.replace("<html lang=\"ru\">", "<html lang=\"en\">")
    localized = localized.replace('<meta property="og:locale" content="ru_RU">', '<meta property="og:locale" content="en_US">')
    localized = localized.replace('<meta property="og:locale:alternate" content="en_US">', '<meta property="og:locale:alternate" content="ru_RU">')
    localized = localized.replace('Cosmos Luminosity — практики мышления, состояния и тела для живого выбора.', 'Cosmos Luminosity — practices for thinking, state, body and meaning that support living choice.')
    localized = localized.replace('Cosmos Luminosity — живой выбор', 'Cosmos Luminosity — living choice')
    localized = localized.replace('lang="ru" class="active" aria-current="page"', 'lang="ru"')
    localized = localized.replace('lang="en" aria-label="EN — English language"', 'lang="en" class="active" aria-current="page" aria-label="EN — English language"')
    localized = localized.replace("const currentLanguage='ru';", "const currentLanguage='en';")
    localized = localized.replace("const languageRoot='';", "const languageRoot='/en';")
    (ROOT / "default-en.hbs").write_text(
        "{{! Generated by tools/generate_english_templates.py; edit default.hbs instead. }}\n" + localized,
        encoding="utf-8",
    )


def main() -> None:
    generate_layout()
    for source_name, meta in PAGES.items():
        generate_page(source_name, meta)


if __name__ == "__main__":
    main()
