"""
ABOS AI Worker – PDF Extraction Utility
=========================================
Attempts to extract text from a PDF using pdfplumber (preferred — handles
tables and complex layouts well).  Falls back to PyPDF2 if pdfplumber is
unavailable or raises an exception.

Returns a (text, page_count) tuple.
"""

from __future__ import annotations

import io
import logging

logger = logging.getLogger(__name__)


def extract_text_from_pdf(pdf_bytes: bytes) -> tuple[str, int]:
    """
    Extract all text from *pdf_bytes*.

    Parameters
    ----------
    pdf_bytes:
        Raw bytes of the uploaded PDF file.

    Returns
    -------
    (raw_text, page_count)
        raw_text  – concatenated text for all pages, pages delimited by a
                    form-feed character (``\\f``).
        page_count – total number of pages in the document.

    Raises
    ------
    ValueError
        If the document contains no extractable text or both PDF libraries
        fail to open it.
    """
    # ── Try pdfplumber first ──────────────────────────────────────────────
    try:
        import pdfplumber  # type: ignore

        with pdfplumber.open(io.BytesIO(pdf_bytes)) as pdf:
            pages: list[str] = []
            for page in pdf.pages:
                text = page.extract_text() or ""
                pages.append(text)
            full_text = "\f".join(pages)
            page_count = len(pages)

        if full_text.strip():
            logger.debug(
                "pdfplumber extracted %d chars from %d pages.", len(full_text), page_count
            )
            return full_text, page_count

        logger.warning("pdfplumber returned empty text; falling back to PyPDF2.")

    except ImportError:
        logger.warning("pdfplumber not installed; falling back to PyPDF2.")
    except Exception as exc:  # noqa: BLE001
        logger.warning("pdfplumber failed (%s); falling back to PyPDF2.", exc)

    # ── Fallback: PyPDF2 ─────────────────────────────────────────────────
    try:
        from PyPDF2 import PdfReader  # type: ignore

        reader = PdfReader(io.BytesIO(pdf_bytes))
        pages = []
        for page in reader.pages:
            text = page.extract_text() or ""
            pages.append(text)
        full_text = "\f".join(pages)
        page_count = len(pages)

        if full_text.strip():
            logger.debug(
                "PyPDF2 extracted %d chars from %d pages.", len(full_text), page_count
            )
            return full_text, page_count

        raise ValueError("No extractable text found in the PDF (possibly scanned image).")

    except ImportError as exc:
        raise RuntimeError(
            "Neither pdfplumber nor PyPDF2 is installed. "
            "Install at least one of them: pip install pdfplumber PyPDF2"
        ) from exc
    except ValueError:
        raise
    except Exception as exc:  # noqa: BLE001
        raise ValueError(f"Failed to read PDF with PyPDF2: {exc}") from exc
