"""Regenerate static related cards from the shared public pool.

Run from any directory: python3 scripts/build-related-projects.py
The public overview owns the pool, card content and imagery. No runtime dependency.
"""
import json
import re
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent
# The overview is the authoritative public catalogue, including responsive images
# and project-specific crop classes. Never select covers from case galleries.
overview = re.sub(r'<!--.*?-->', '', (ROOT / 'projekte.html').read_text(), flags=re.S)
POOL = {}
for card in re.findall(r'<a class="projekte-card".*?</a>', overview, flags=re.S):
    slug = re.search(r'href="([^"]+)"', card)[1]
    assert not any(name in slug for name in ('schenck', 'dornbach')), slug
    title_id = re.search(r'aria-labelledby="([^"]+)"', card)[1]
    card = card.replace(f'aria-labelledby="{title_id}"', 'aria-labelledby="RELATED_ID"')
    card = card.replace(f'id="{title_id}"', 'id="RELATED_ID"')
    # Related cards keep lazy loading; image paths, srcsets and crops are exact.
    card = re.sub(r'fetchpriority="[^"]*"\s*', '', card)
    card = re.sub(r'loading="[^"]*"', 'loading="lazy"', card)
    POOL[slug] = card
assert len(POOL) >= 4
(ROOT / 'scripts/public-projects.json').write_text(
    json.dumps(POOL, ensure_ascii=False, indent=2) + '\n')

# Export the same approved covers for the responsive homepage; no second mapping.
covers = {}
for slug, card in POOL.items():
    covers[slug] = {
        'src': re.search(r'<img src="([^"]+)"', card)[1],
        'srcset': re.search(r'<source[^>]*srcset="([^"]+)"', card)[1],
        'width': 800, 'height': 600,
    }
components = ROOT / 'shared-components.js'
source = components.read_text()
source, count = re.subn(r'  // BEGIN GENERATED PROJECT COVERS.*?  // END GENERATED PROJECT COVERS',
    lambda _: '  // BEGIN GENERATED PROJECT COVERS — owned by projekte.html\n'
        + '  const projectCovers = Object.freeze(' + json.dumps(covers, ensure_ascii=False, indent=2) + ');\n'
        + '  // END GENERATED PROJECT COVERS', source, flags=re.S)
assert count == 1
components.write_text(source)

for page in sorted(ROOT.glob('projekt-*.html')):
    if 'case-related-grid' not in page.read_text():
        continue  # Legacy redirect aliases have no project content.
    slugs = list(POOL)
    # Rotate through the same pool, excluding the current project.
    start = (slugs.index(page.name) + 1) if page.name in slugs else 0
    ordered = slugs[start:] + slugs[:start]
    selected = [slug for slug in ordered if slug != page.name][:3]
    cards = '\n'.join(POOL[slug].replace('RELATED_ID', f'related-project-{i}')
                      for i, slug in enumerate(selected, 1))
    source = page.read_text()
    source, count = re.subn(
        r'(<div class="case-related-grid">).*?(</div>\s*</div>\s*</section>)',
        lambda match: match[1] + cards + match[2], source, count=1, flags=re.S)
    assert count == 1, page
    page.write_text(source)
