# document_analysis/loaders/dispatcher.py

from __future__ import annotations

import os
import tempfile
from typing import Optional

import fitz  # PyMuPDF

from .pdf_loader import extract_text_from_pdf      # extração digital (pdfplumber)
from .docx_loader import extract_text_from_docx
from .ocr_loader import extract_text_from_image, extract_text_from_pdf as ocr_pdf

SUPPORTED_IMAGE_EXTS = {".png", ".jpg", ".jpeg", ".webp", ".tif", ".tiff"}
SUPPORTED_DOC_EXTS = {".docx"}
SUPPORTED_PDF_EXTS = {".pdf"}


def _safe_len(s: Optional[str]) -> int:
    return len(s.strip()) if s else 0


def _ocr_pdf_with_pymupdf(pdf_path: str, dpi: int = 200) -> str:
    """
    Converte cada página do PDF para imagem e roda OCR.
    Agora utiliza a função do ocr_loader que usa a classe OCRExtractor.
    """
    return ocr_pdf(pdf_path, dpi=dpi)


def load_document(file_path: str, *, min_text_chars_for_digital_pdf: int = 120) -> str:
    """
    Carrega e extrai texto de:
    - PDF digital (pdfplumber) com fallback OCR se necessário
    - PDF escaneado (fallback OCR)
    - DOCX (python-docx)
    - Imagens (OCR)

    Params:
      - min_text_chars_for_digital_pdf: abaixo disso, assume que o PDF pode ser escaneado
    """
    if not os.path.exists(file_path):
        raise FileNotFoundError(f"Documento não encontrado: {file_path}")

    ext = os.path.splitext(file_path)[1].lower()

    # ---- PDF
    if ext in SUPPORTED_PDF_EXTS:
        digital_text = extract_text_from_pdf(file_path)

        # Se vier texto suficiente, consideramos PDF digital OK
        if _safe_len(digital_text) >= min_text_chars_for_digital_pdf:
            return digital_text

        # Fallback OCR
        ocr_text = _ocr_pdf_with_pymupdf(file_path)
        if _safe_len(ocr_text) > 0:
            return ocr_text

        # Se ambos falharem, devolve o que tiver (mesmo vazio)
        return digital_text or ""

    # ---- DOCX
    if ext in SUPPORTED_DOC_EXTS:
        return extract_text_from_docx(file_path)

    # ---- IMAGEM
    if ext in SUPPORTED_IMAGE_EXTS:
        return extract_text_from_image(file_path)

    raise ValueError(
        f"Formato não suportado: {ext}. Suportados: PDF, DOCX, imagens ({', '.join(sorted(SUPPORTED_IMAGE_EXTS))})"
    )