"""Render a PDF page and draw labeled normalized boxes on it."""

from __future__ import annotations

from pathlib import Path
from typing import List, Sequence, Tuple

import fitz
from PIL import Image, ImageDraw, ImageFont

Box = Tuple[float, float, float, float]


def _font(size: int):
    try:
        return ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", size)
    except Exception:
        return ImageFont.load_default()


def render_page(pdf: Path, page: int, dpi: int = 150) -> Image.Image:
    doc = fitz.open(str(pdf))
    pix = doc[page - 1].get_pixmap(dpi=dpi)
    return Image.frombytes("RGB", [pix.width, pix.height], pix.samples).convert("RGB")


def draw_boxes(
    img: Image.Image,
    layers: Sequence[Tuple[str, Sequence[Box], Tuple[int, int, int]]],
) -> Image.Image:
    """Draw several labeled box layers. Each layer = (name, boxes, rgb)."""
    out = img.copy()
    dr = ImageDraw.Draw(out)
    W, H = out.size
    font = _font(15)
    for li, (name, boxes, rgb) in enumerate(layers):
        for bi, (x0, y0, x1, y1) in enumerate(boxes):
            px = [x0 * W, y0 * H, x1 * W, y1 * H]
            # offset each layer slightly so coincident edges stay visible
            off = li * 2
            dr.rectangle([px[0] - off, px[1] - off, px[2] + off, px[3] + off], outline=rgb, width=2)
            dr.text((px[0] + 2, max(0, px[1] - 16 - li * 14)), f"{name}{bi+1}", fill=rgb, font=font)
    return out
