"""Convert an HTML file to PDF with the Ironfang Render API.

Usage:
    export IRONFANG_API_KEY="if_live_..."
    python html_to_pdf.py invoice.html invoice.pdf

The HTML is sent to the hosted API and the PDF comes back in the response.
Needs Python 3.9 or newer and the requests package.
"""

import os
import sys
from pathlib import Path

import requests

API_URL = "https://api.ironfang.uk/render/v1/pdf"

FOOTER = (
    '<div style="font-size:9px;width:100%;text-align:center;'
    'color:#666;font-family:sans-serif">'
    'Page <span class="pageNumber"></span> of <span class="totalPages"></span>'
    "</div>"
)


def main() -> None:
    if len(sys.argv) != 3:
        sys.exit("Usage: python html_to_pdf.py INPUT.html OUTPUT.pdf")
    source, target = Path(sys.argv[1]), Path(sys.argv[2])

    key = os.environ.get("IRONFANG_API_KEY")
    if not key:
        sys.exit("Set IRONFANG_API_KEY to your Ironfang API key.")

    body = {
        "html": source.read_text(encoding="utf-8"),
        "paper_format": "a4",
        "print_background": True,
        # Inches, per side. The bottom margin leaves room for the footer.
        "margin": {"top": 0.6, "right": 0.5, "bottom": 0.8, "left": 0.5},
        # A footer on its own makes Chromium print its default date and
        # title header, so an empty header goes with it.
        "header_html": "<span></span>",
        "footer_html": FOOTER,
    }

    try:
        resp = requests.post(
            API_URL,
            headers={"Authorization": f"Bearer {key}"},
            json=body,
            timeout=60,
        )
    except requests.RequestException as exc:
        sys.exit(f"The request did not complete: {exc.__class__.__name__}")

    content_type = resp.headers.get("Content-Type", "")
    if resp.status_code != 200 or not content_type.startswith("application/pdf"):
        # Errors are JSON even though success is binary. Never save them
        # as the PDF.
        try:
            err = resp.json()["error"]
            detail = f"{err['code']}: {err['message']}"
        except (ValueError, KeyError, TypeError):
            detail = f"unexpected response ({content_type or 'no content type'})"
        retry = resp.headers.get("Retry-After")
        hint = f" Retry after {retry} seconds." if retry else ""
        sys.exit(f"HTTP {resp.status_code} {detail}.{hint}")

    target.write_bytes(resp.content)
    credits = resp.headers.get("X-Renderwolf-Credits", "?")
    print(f"Wrote {target}: {len(resp.content):,} bytes, {credits} credits used.")


if __name__ == "__main__":
    main()
