#!/usr/bin/env python3
"""Generate contact sheets, PDF, and a browser audit report for courseware."""

from __future__ import annotations

import argparse
import importlib.util
import json
import shutil
import tempfile
from pathlib import Path

import fitz
from PIL import Image, ImageDraw, ImageFont


def load_auditor(script: Path):
    spec = importlib.util.spec_from_file_location("courseware_audit_browser", script)
    module = importlib.util.module_from_spec(spec)
    assert spec.loader
    spec.loader.exec_module(module)
    return module


def contact_sheet(images: list[Path], output: Path, title: str, columns: int = 4) -> None:
    opened = [Image.open(item).convert("RGB") for item in images]
    thumb_w, thumb_h = 360, 203
    gap, label_h, header_h = 22, 34, 72
    rows = (len(opened) + columns - 1) // columns
    canvas = Image.new("RGB", (gap + columns * (thumb_w + gap), header_h + rows * (thumb_h + label_h + gap)), "#E8F1F2")
    draw = ImageDraw.Draw(canvas)
    font = ImageFont.load_default()
    draw.text((gap, 24), title, fill="#17324D", font=font)
    for index, (source, image) in enumerate(zip(images, opened)):
        image.thumbnail((thumb_w, thumb_h))
        x = gap + (index % columns) * (thumb_w + gap)
        y = header_h + (index // columns) * (thumb_h + label_h + gap)
        tile = Image.new("RGB", (thumb_w, thumb_h), "white")
        tile.paste(image, ((thumb_w - image.width) // 2, (thumb_h - image.height) // 2))
        canvas.paste(tile, (x, y))
        draw.text((x, y + thumb_h + 9), images[index].stem, fill="#17212B", font=font)
    output.parent.mkdir(parents=True, exist_ok=True)
    canvas.save(output, quality=90, optimize=True)


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("project", type=Path)
    parser.add_argument("output", type=Path)
    args = parser.parse_args()
    project, output = args.project.resolve(), args.output.resolve()
    output.mkdir(parents=True, exist_ok=True)
    auditor = load_auditor(Path(__file__).with_name("audit-browser.py"))
    report_path = output / "audit-report.json"
    pdf_path = output / "demo-courseware.pdf"
    with tempfile.TemporaryDirectory(prefix="courseware-render-") as temp:
        shots = Path(temp)
        report = auditor.run_audit(project, report_path, shots, None, pdf_path)
        for mode in ["desktop", "mobile", "fullscreen"]:
            contact_sheet(sorted((shots / mode).glob("*.png")), output / f"{mode}-contact-sheet.jpg", f"{mode.upper()} · {report['pageCount']} pages")
        focus = output / "focus-pages"
        focus.mkdir(exist_ok=True)
        selections = {
            "mobile/05-text-and-visual.png": "mobile-05-text-and-visual.png",
            "mobile/07-flow.png": "mobile-07-flow.png",
            "mobile/14-table.png": "mobile-14-table.png",
            "mobile/16-exercise.png": "mobile-16-exercise.png",
            "desktop/09-matrix.png": "desktop-09-matrix.png",
            "fullscreen/18-qa.png": "fullscreen-18-qa.png",
        }
        for source, destination in selections.items():
            shutil.copy2(shots / source, focus / destination)
    document = fitz.open(pdf_path)
    pdf_pages = document.page_count
    document.close()
    if pdf_pages != report["pageCount"]:
        report["ok"] = False
        report["findings"].append({"severity": "error", "mode": "print", "pageId": "all", "code": "pdf-page-count", "message": f"PDF has {pdf_pages} pages; expected {report['pageCount']}"})
        report_path.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
    print(json.dumps({"ok": report["ok"], "output": str(output), "pdfPages": pdf_pages}, ensure_ascii=False, indent=2))
    return 0 if report["ok"] else 1


if __name__ == "__main__":
    raise SystemExit(main())
