#!/usr/bin/env python3
"""Patch onepager sites with theme-toggle wiring.

Inserts (idempotent):
  1. anti-FOUC inline IIFE after <meta name="viewport">
  2. <link rel="stylesheet" href="/shared/css/theme.css"> before first <style>
  3. <script src="/shared/theme.js"> before <script src="/shared/i18n.js">
  4. <script src="/shared/toggles.js"> after <script src="/shared/i18n.js">

Skips sites that already have any of the markers.

Usage:
  python3 tools/patch-theme.py <site-dir> [<site-dir> ...]
  python3 tools/patch-theme.py --all       # all sites with index.html, skip dynamic
"""
import re
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent
SITES_DIR = ROOT / "sites"

ANTI_FOUC = "<script>(function(){try{var t=localStorage.getItem('onepager-theme');if(!t)t=matchMedia('(prefers-color-scheme: light)').matches?'light':'dark';document.documentElement.setAttribute('data-theme',t);}catch(e){document.documentElement.setAttribute('data-theme','dark');}})();</script>"

THEME_LINK = '<link rel="stylesheet" href="/shared/css/theme.css">'
THEME_SCRIPT = '<script src="/shared/theme.js"></script>'
TOGGLES_SCRIPT = '<script src="/shared/toggles.js"></script>'


def detect_indent(line):
    """Return leading whitespace prefix of a line."""
    m = re.match(r"^(\s*)", line)
    return m.group(1) if m else ""


def patch(html):
    """Apply 4 insertions idempotently. Returns (new_html, changed_bool)."""
    changed = False

    # 1) Anti-FOUC after <meta name="viewport"...>
    if "onepager-theme" not in html:
        m = re.search(r'^([ \t]*)<meta\s+name="viewport"[^>]*>\s*$', html, re.MULTILINE)
        if m:
            indent = m.group(1)
            insert = f"\n{indent}{ANTI_FOUC}"
            html = html[: m.end()] + insert + html[m.end():]
            changed = True
        else:
            return html, False  # can't anchor — bail

    # 2) <link rel="stylesheet" href="/shared/css/theme.css"> before first <style>
    if THEME_LINK not in html:
        m = re.search(r'^([ \t]*)<style[ >]', html, re.MULTILINE)
        if m:
            indent = m.group(1)
            insert = f"{indent}{THEME_LINK}\n"
            html = html[: m.start()] + insert + html[m.start():]
            changed = True

    # 3) theme.js before i18n.js
    if "/shared/theme.js" not in html:
        m = re.search(r'^([ \t]*)<script\s+src="/shared/i18n\.js"></script>\s*$', html, re.MULTILINE)
        if m:
            indent = m.group(1)
            insert = f"{indent}{THEME_SCRIPT}\n"
            html = html[: m.start()] + insert + html[m.start():]
            changed = True

    # 4) toggles.js after i18n.js
    if "/shared/toggles.js" not in html:
        m = re.search(r'^([ \t]*)<script\s+src="/shared/i18n\.js"></script>\s*$', html, re.MULTILINE)
        if m:
            indent = m.group(1)
            # Insert AFTER the i18n.js line
            end = m.end()
            # Make sure we put on a new line
            insert = f"\n{indent}{TOGGLES_SCRIPT}"
            html = html[:end] + insert + html[end:]
            changed = True

    return html, changed


def main():
    if "--all" in sys.argv:
        sites = []
        for d in sorted(SITES_DIR.iterdir()):
            if d.is_dir() and (d / "index.html").exists():
                sites.append(d)
    else:
        sites = []
        for arg in sys.argv[1:]:
            p = Path(arg)
            if not p.is_absolute():
                p = SITES_DIR / arg
            if not p.is_dir():
                print(f"skip: {arg} not a directory", file=sys.stderr)
                continue
            if not (p / "index.html").exists():
                print(f"skip: {p}/index.html missing", file=sys.stderr)
                continue
            sites.append(p)

    if not sites:
        print("no sites to patch", file=sys.stderr)
        sys.exit(2)

    patched, skipped, missing_anchor = 0, 0, []
    for site in sites:
        path = site / "index.html"
        before = path.read_text()
        after, changed = patch(before)
        if not changed:
            if "onepager-theme" in before and "/shared/toggles.js" in before:
                skipped += 1
                print(f"  [unchanged] {site.name}")
            else:
                missing_anchor.append(site.name)
                print(f"  [no-anchor] {site.name}")
        else:
            path.write_text(after)
            patched += 1
            print(f"  [patched]   {site.name}")

    print(f"\nPatched: {patched}, Already-up-to-date: {skipped}, No-anchor: {len(missing_anchor)}")
    if missing_anchor:
        print("Missing anchors (manual fix needed):")
        for s in missing_anchor:
            print(f"  - {s}")
        sys.exit(1)


if __name__ == "__main__":
    main()
