"""
export-carousel-pdf.py — Rendert ein LinkedIn-Carousel aus einer preview.html
in eine Mehrseiten-PDF (Default 1080 x 1350 px, 4:5 Portrait, LinkedIn-
Document-Post-Format).

Nutzt Playwright + Headless-Chromium und die @page-CSS-Regel der HTML
(prefer_css_page_size=True), damit jede .slide-Section automatisch zu einer
eigenen PDF-Page wird (Pflicht-Count: 10 Slides). Awaitet
document.fonts.ready, damit Mona Sans und Inter geladen sind, bevor das PDF
geschossen wird — sonst rendert Chromium einen Times-Fallback.

PDF-Format-Spezifikationen (Bundle-Pflicht aus SKILL.md):
- 10 Slides @ 1080 x 1350 px = 810 x 1013 pt (96 dpi)
- prefer_css_page_size=True liest @page { size: 1080px 1350px; margin: 0 }
- print_background=True für Hintergründe und Gradients
- Hard-Limit Dateigröße: 5 MB

Aufruf:
    python export-carousel-pdf.py                    # nimmt preview.html neben dem Script
    python export-carousel-pdf.py preview.html
    python export-carousel-pdf.py preview.html -o carousel.pdf
"""

from __future__ import annotations

import argparse
import sys
import time
from pathlib import Path
from urllib.parse import quote

from playwright.sync_api import sync_playwright


# Hard-Limit für LinkedIn-Document-Post-Upload (MB).
HARD_LIMIT_MB = 5
# Idealwert (MB) — Warnung wenn überschritten, aber unter Hard-Limit.
TARGET_LIMIT_MB = 3
# Pflicht-Slide-Count.
EXPECTED_SLIDE_COUNT = 10


def render_pdf(
    html_path: Path,
    pdf_path: Path,
    viewport_w: int,
    viewport_h: int,
    wait_ms: int,
    scale: float,
) -> None:
    """Rendert die HTML zu PDF via Playwright + Chromium."""
    file_url = "file:///" + quote(str(html_path.resolve()).replace("\\", "/"))

    with sync_playwright() as p:
        browser = p.chromium.launch()
        # device_scale_factor > 1 rendert Texte und Vektoren in höherer Pixeldichte.
        # LinkedIn komprimiert die PDF beim Upload zu JPEGs — höhere Render-
        # Auflösung liefert schärfere Headlines und gold-dot im Feed.
        context = browser.new_context(
            viewport={"width": viewport_w, "height": viewport_h},
            device_scale_factor=scale,
        )
        page = context.new_page()
        page.goto(file_url, wait_until="networkidle")

        # Webfonts müssen vor dem PDF-Snapshot geladen sein, sonst rendert
        # Chromium einen Times-Fallback und LinkedIn-Doku läuft mit Times.
        page.evaluate("document.fonts.ready")
        page.wait_for_timeout(wait_ms)

        page.pdf(
            path=str(pdf_path),
            print_background=True,
            prefer_css_page_size=True,
            margin={"top": "0", "bottom": "0", "left": "0", "right": "0"},
        )

        browser.close()


def main() -> int:
    parser = argparse.ArgumentParser(
        description="LinkedIn-Carousel als PDF rendern (1080 x 1350, 4:5)."
    )
    parser.add_argument(
        "html",
        nargs="?",
        default="preview.html",
        help="Pfad zur preview.html (Default: preview.html neben dem Script)",
    )
    parser.add_argument(
        "-o", "--output",
        help="Ziel-PDF (Default: carousel.pdf neben der HTML)",
    )
    parser.add_argument("--viewport-width", type=int, default=1080)
    parser.add_argument("--viewport-height", type=int, default=1350)
    parser.add_argument(
        "--wait", type=int, default=2000,
        help="Wartezeit nach Load in ms (Default 2000)",
    )
    parser.add_argument(
        "--scale", type=float, default=2.0,
        help="device_scale_factor (Default 2.0, für LinkedIn-Schärfe)",
    )
    args = parser.parse_args()

    script_dir = Path(__file__).parent
    html_arg = Path(args.html)
    html_path = (script_dir / args.html if not html_arg.is_absolute() else html_arg).resolve()

    if not html_path.exists():
        print(f"Datei nicht gefunden: {html_path}", file=sys.stderr)
        return 2

    pdf_path = (
        Path(args.output).resolve()
        if args.output
        else (html_path.parent / "carousel.pdf").resolve()
    )

    print(f"Rendere {html_path.name} -> {pdf_path.name} (scale {args.scale}x)")
    t0 = time.time()
    render_pdf(
        html_path, pdf_path,
        args.viewport_width, args.viewport_height,
        args.wait, args.scale,
    )
    size_bytes = pdf_path.stat().st_size
    size_mb = size_bytes / (1024 * 1024)
    print(f"Fertig in {time.time() - t0:.1f}s. PDF: {pdf_path}")
    print(f"Dateigröße: {size_mb:.2f} MB")

    if size_mb > HARD_LIMIT_MB:
        print(
            f"FEHLER: Dateigröße {size_mb:.2f} MB überschreitet Hard-Limit "
            f"{HARD_LIMIT_MB} MB. Bilder verkleinern und neu bauen.",
            file=sys.stderr,
        )
        return 3
    if size_mb > TARGET_LIMIT_MB:
        print(
            f"Warnung: Dateigröße {size_mb:.2f} MB über Idealwert "
            f"{TARGET_LIMIT_MB} MB. Verbesserung empfehlenswert.",
        )

    return 0


if __name__ == "__main__":
    sys.exit(main())
