# Render a representative spread, including explicit furnished floor cutaways.
import argparse
import json
from pathlib import Path
import subprocess

ROOT = Path(__file__).resolve().parents[1]
PYTHON = Path('/opt/venv/bin/python')
RENDERER = Path('/work/generator/MCRender/node_modules/.bin/vite-node')
CUTTER = Path('/opt/tools/cutaway.py')


def main():
    """Render both exterior sides and floor cutaways of every client in the corpus."""
    parser = argparse.ArgumentParser()
    parser.add_argument('--manifest', type=Path, default=ROOT / 'samples/manifest.json')
    parser.add_argument('--all-seeds', action='store_true')
    args = parser.parse_args()
    manifest = json.loads(args.manifest.read_text())
    jobs = []
    selected = set()
    for sample in manifest['samples']:
        client = Path(sample['client']).stem
        if client in selected and not args.all_seeds:
            continue
        selected.add(client)
        key = f'{client}-{sample["seed"]}'
        source = args.manifest.parent / sample['schematic']
        folder = ROOT / 'previews' / key
        folder.mkdir(parents=True, exist_ok=True)
        jobs.append({'input': str(source.resolve()), 'folder': str(folder), 'name': key, 'views': ['front', 'rear']})
        metadata = json.loads((args.manifest.parent / sample['metadata']).read_text())
        floors = sorted({level['floor'] for mass in sample['resolved']['masses'] for level in mass['levels']})
        for i, floor in enumerate(floors):
            path = folder / f'floor-{i}.litematic'
            height = floor + 3 - metadata['origin'][1]
            subprocess.run([str(PYTHON), str(CUTTER), '--input', str(source), '--output', str(path), '--max-y', str(height)], check=True, stdout=subprocess.DEVNULL)
            owners = ', '.join(mass['name'] for mass in sample['resolved']['masses'] if any(level['floor'] == floor for level in mass['levels']))
            jobs.append({'input': str(path), 'folder': str(folder), 'name': f'{key}, {owners}, floor elevation {floor}', 'views': [f'floor-{i}']})
    jobs_path = ROOT / 'previews/render_jobs.json'
    jobs_path.write_text(json.dumps(jobs, indent=2) + '\n')
    subprocess.run(['xvfb-run', '-a', str(RENDERER), '--script', str(ROOT / 'render_batch.mjs'), '--', str(jobs_path)], check=True)
    # Cutaway schematic files are render intermediates; final image labels record the level.
    for job in jobs:
        path = Path(job['input'])
        if path.parent.parent == ROOT / 'previews':
            path.unlink(missing_ok=True)
    create_index(jobs)


def create_index(jobs):
    """Build an offline review index with unambiguous client, seed and floor labels."""
    rows = []
    for job in jobs:
        for view in job['views']:
            rel = Path(job['folder']).name + '/' + view + '.png'
            rows.append(f'<figure><a href="{rel}"><img loading="lazy" src="{rel}"></a><figcaption>{job["name"]}: {view}</figcaption></figure>')
    page = '<!doctype html><meta charset="utf-8"><title>Hearthwright review</title><style>body{background:#252d32;color:#f5e9d2;font:16px system-ui;margin:2rem}main{display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));gap:1rem}figure{margin:0}img{width:100%}figcaption{padding:.6rem}</style><h1>Hearthwright sample review</h1><p>Exterior pairs and furnished floor cutaways. Every schematic was validated before and after export.</p><main>' + ''.join(rows) + '</main>'
    (ROOT / 'previews/index.html').write_text(page)


if __name__ == '__main__':
    main()
