"""
OCR Service — Extract text from uploaded legal documents (PDF and images).
Uses PyMuPDF for PDFs and pytesseract for scanned images.
Falls back gracefully if optional dependencies are not installed.
"""
import os
from pathlib import Path
from typing import Optional


def _configure_tesseract():
    """Point pytesseract at tesseract.exe when it isn't on PATH (common on Windows)."""
    import shutil
    import pytesseract
    if shutil.which("tesseract"):
        return
    candidates = [
        Path(os.environ.get("LOCALAPPDATA", "")) / "Programs" / "Tesseract-OCR" / "tesseract.exe",
        Path("C:/Program Files/Tesseract-OCR/tesseract.exe"),
        Path("C:/Program Files (x86)/Tesseract-OCR/tesseract.exe"),
    ]
    for exe in candidates:
        if exe.exists():
            pytesseract.pytesseract.tesseract_cmd = str(exe)
            return


def extract_text_from_pdf(file_path: str) -> str:
    """
    Extract text from a PDF file using PyMuPDF (fitz).
    Returns extracted text or empty string on failure.
    """
    try:
        import fitz  # PyMuPDF — pip install pymupdf
        doc = fitz.open(file_path)
        text_parts = []
        for page_num in range(len(doc)):
            page = doc.load_page(page_num)
            text = page.get_text("text")
            if text.strip():
                text_parts.append(f"[Page {page_num + 1}]\n{text.strip()}")
        doc.close()
        full_text = "\n\n".join(text_parts)
        print(f"[OCR] Extracted {len(full_text)} chars from PDF: {file_path}")
        return full_text
    except ImportError:
        print("[OCR] PyMuPDF not installed. Run: pip install pymupdf")
        return ""
    except Exception as e:
        print(f"[OCR] PDF extraction failed for {file_path}: {e}")
        return ""


def extract_text_from_image(file_path: str, lang: str = "eng") -> str:
    """
    Extract text from a scanned image using Tesseract OCR.
    lang='eng' for English, 'urd' for Urdu, 'eng+urd' for both.
    Requires: pip install pytesseract Pillow
    Also requires Tesseract binary installed on OS.
    """
    try:
        import pytesseract
        from PIL import Image
        _configure_tesseract()

        img = Image.open(file_path)
        # Tesseract works best on high-contrast images — convert to grayscale
        img = img.convert("L")
        text = pytesseract.image_to_string(img, lang=lang)
        clean = text.strip()
        print(f"[OCR] Extracted {len(clean)} chars from image: {file_path}")
        return clean
    except ImportError:
        print("[OCR] pytesseract or Pillow not installed. Run: pip install pytesseract Pillow")
        return ""
    except Exception as e:
        print(f"[OCR] Image OCR failed for {file_path}: {e}")
        return ""


def extract_text(file_path: str, urdu_mode: bool = False) -> str:
    """
    Auto-detect file type and extract text accordingly.
    This is the main entry point called by routers.
    """
    path = Path(file_path)
    suffix = path.suffix.lower()

    if not path.exists():
        print(f"[OCR] File not found: {file_path}")
        return ""

    if suffix == ".pdf":
        text = extract_text_from_pdf(file_path)
        # If PDF has no text layer (scanned), fall through to image OCR
        if len(text.strip()) < 50:
            print("[OCR] PDF appears to be a scanned document — attempting image OCR on pages.")
            text = _ocr_pdf_as_images(file_path, urdu_mode=urdu_mode)
        return text

    elif suffix in (".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".tif", ".webp"):
        lang = "eng+urd" if urdu_mode else "eng"
        return extract_text_from_image(file_path, lang=lang)

    else:
        print(f"[OCR] Unsupported file type: {suffix}")
        return ""


def _ocr_pdf_as_images(file_path: str, urdu_mode: bool = False) -> str:
    """
    Convert each PDF page to an image and run OCR on it.
    Used for scanned PDFs that have no embedded text layer.
    """
    try:
        import fitz
        import pytesseract
        from PIL import Image
        import io
        _configure_tesseract()

        lang = "eng+urd" if urdu_mode else "eng"
        doc = fitz.open(file_path)
        results = []

        for page_num in range(len(doc)):
            page = doc.load_page(page_num)
            # Render at 200 DPI for decent OCR quality without huge memory use
            pix = page.get_pixmap(dpi=200)
            img_bytes = pix.tobytes("png")
            img = Image.open(io.BytesIO(img_bytes)).convert("L")
            text = pytesseract.image_to_string(img, lang=lang)
            if text.strip():
                results.append(f"[Page {page_num + 1}]\n{text.strip()}")

        doc.close()
        return "\n\n".join(results)
    except Exception as e:
        print(f"[OCR] PDF-as-images OCR failed: {e}")
        return ""


def get_document_summary(extracted_text: str, max_chars: int = 500) -> str:
    """
    Return a short preview of extracted text for display in the UI.
    Truncates to max_chars and adds ellipsis if needed.
    """
    if not extracted_text:
        return ""
    clean = " ".join(extracted_text.split())   # collapse whitespace
    if len(clean) <= max_chars:
        return clean
    return clean[:max_chars].rsplit(" ", 1)[0] + "..."
