"""PDF format guardrails for customer-facing document delivery.

ClientFlow normally receives Jasmin PDFs as opaque bytes.  For customer-facing
invoice sends we still need one cheap safety check: invoices should be printable
A4, not a narrow receipt-like page returned by a wrong Jasmin print layout.

The parser is deliberately dependency-free.  It reads common uncompressed page
boxes such as /MediaBox and /CropBox, which are present in PDFs returned by the
Jasmin print endpoints observed in production.
"""
from __future__ import annotations

import hashlib
import re
from typing import Any, Dict, List

A4_PORTRAIT_PT = (595.0, 842.0)
POINT_TO_MM = 25.4 / 72.0


def _looks_a4(width_pt: float, height_pt: float, tolerance_pt: float = 20.0) -> bool:
    pairs = [(width_pt, height_pt), (height_pt, width_pt)]
    return any(
        abs(w - A4_PORTRAIT_PT[0]) <= tolerance_pt and abs(h - A4_PORTRAIT_PT[1]) <= tolerance_pt
        for w, h in pairs
    )


def extract_pdf_boxes(data: bytes) -> List[Dict[str, Any]]:
    latin = data.decode("latin-1", errors="ignore")
    pattern = re.compile(
        r"/(MediaBox|CropBox)\s*\[\s*([-+0-9.]+)\s+([-+0-9.]+)\s+([-+0-9.]+)\s+([-+0-9.]+)\s*\]",
        re.I,
    )
    boxes: List[Dict[str, Any]] = []
    seen: set[tuple[str, float, float, float, float]] = set()
    for m in pattern.finditer(latin):
        kind = m.group(1)
        x0, y0, x1, y1 = (float(m.group(i)) for i in range(2, 6))
        key = (kind.lower(), x0, y0, x1, y1)
        if key in seen:
            continue
        seen.add(key)
        w = abs(x1 - x0)
        h = abs(y1 - y0)
        boxes.append({
            "kind": kind,
            "width_pt": round(w, 2),
            "height_pt": round(h, 2),
            "width_mm": round(w * POINT_TO_MM, 1),
            "height_mm": round(h * POINT_TO_MM, 1),
            "orientation": "landscape" if w > h else "portrait",
            "looks_a4": _looks_a4(w, h),
        })
    return boxes


def analyze_pdf_format(data: bytes, content_type: str = "application/pdf") -> Dict[str, Any]:
    info: Dict[str, Any] = {
        "content_type": content_type,
        "bytes": len(data or b""),
        "sha256_12": hashlib.sha256(data or b"").hexdigest()[:12] if data else "",
        "is_pdf_header": bool(data and data[:5] == b"%PDF-"),
        "page_count_hint": None,
        "boxes": [],
        "format_warning": "",
    }
    if not data:
        info["format_warning"] = "empty_response"
        return info
    if not info["is_pdf_header"]:
        info["format_warning"] = "not_pdf_header"
        return info
    latin = data.decode("latin-1", errors="ignore")
    page_count = len(re.findall(r"/Type\s*/Page(?!s)\b", latin))
    info["page_count_hint"] = page_count or None
    boxes = extract_pdf_boxes(data)
    info["boxes"] = boxes
    media_boxes = [b for b in boxes if str(b.get("kind") or "").lower() == "mediabox"]
    if media_boxes and not any(bool(b.get("looks_a4")) for b in media_boxes):
        info["format_warning"] = "non_a4_or_unexpected_mediabox"
    elif len(data) < 15_000:
        info["format_warning"] = "very_small_pdf"
    elif len(data) > 2_500_000:
        info["format_warning"] = "very_large_pdf"
    return info


def first_box_label(info: Dict[str, Any]) -> str:
    boxes = info.get("boxes") if isinstance(info, dict) else []
    if not boxes:
        return "sem MediaBox/CropBox legível"
    b = boxes[0]
    return f"{b.get('kind') or 'Box'} {b.get('width_mm')}x{b.get('height_mm')}mm a4={b.get('looks_a4')}"


def is_customer_send_blocking_pdf_warning(info: Dict[str, Any]) -> bool:
    return str((info or {}).get("format_warning") or "") in {"not_pdf_header", "empty_response", "non_a4_or_unexpected_mediabox"}


def invoice_pdf_block_message(document_number: str, info: Dict[str, Any]) -> str:
    warning = str((info or {}).get("format_warning") or "")
    box = first_box_label(info)
    if warning == "non_a4_or_unexpected_mediabox":
        return (
            f"PDF da fatura {document_number or ''} bloqueado: o Jasmin devolveu formato não-A4 "
            f"({box}). Verificar layout/template de impressão da série/tipo FA no Jasmin antes de enviar ao cliente."
        ).strip()
    if warning == "not_pdf_header":
        return f"PDF da fatura {document_number or ''} bloqueado: o endpoint Jasmin não devolveu um PDF válido.".strip()
    if warning == "empty_response":
        return f"PDF da fatura {document_number or ''} bloqueado: resposta vazia do Jasmin.".strip()
    return f"PDF da fatura {document_number or ''} bloqueado: {warning or 'formato inesperado'}.".strip()
