"""Headless browser PDF fetching via Playwright (fallback module)."""

import asyncio
from pathlib import Path

from huntpdf.errors import DownloadFailed, PDFNotFound

_PLAYWRIGHT_INSTALL_MSG = (
    "Playwright browsers are not installed. "
    "Run: playwright install chromium"
)

_TIMEOUT_MS = 30_000

try:
    from playwright.async_api import async_playwright
except ImportError:
    async_playwright = None


async def fetch_pdf_browser(url: str, output: Path) -> Path:
    """Navigate to a URL with headless Chromium and intercept a PDF response.

    Args:
        url: The page URL expected to serve or redirect to a PDF.
        output: Destination file path for the downloaded PDF.

    Returns:
        The output path on success.

    Raises:
        PDFNotFound: If no PDF response is intercepted before the page settles.
        DownloadFailed: If Playwright browsers are not installed.
    """
    if async_playwright is None:
        raise DownloadFailed(_PLAYWRIGHT_INSTALL_MSG)

    pdf_body: bytes | None = None

    async def _on_response(response):
        nonlocal pdf_body
        content_type = response.headers.get("content-type", "")
        if "application/pdf" in content_type:
            pdf_body = await response.body()

    try:
        async with async_playwright() as pw:
            try:
                browser = await pw.chromium.launch(headless=True)
            except Exception as exc:
                if "Executable doesn't exist" in str(exc):
                    raise DownloadFailed(_PLAYWRIGHT_INSTALL_MSG) from exc
                raise

            page = await browser.new_page()
            page.on("response", _on_response)

            try:
                await page.goto(url, timeout=_TIMEOUT_MS, wait_until="networkidle")
            except Exception:
                pass

            await browser.close()
    except DownloadFailed:
        raise
    except Exception as exc:
        raise DownloadFailed(str(exc)) from exc

    if pdf_body is None:
        raise PDFNotFound(f"No PDF response intercepted from {url}")

    output.parent.mkdir(parents=True, exist_ok=True)
    output.write_bytes(pdf_body)
    return output


def fetch_pdf_browser_sync(url: str, output: Path) -> Path:
    """Synchronous wrapper around fetch_pdf_browser."""
    return asyncio.run(fetch_pdf_browser(url, output))
