"""
File text extractor for the L0 quality layer.

Extracts a small sample of text from a translated file so the L0 checks
can run on a real output without requiring the translators to expose
their internal chunk data.

This module depends on the same libraries the translators use
(python-docx, openpyxl, python-pptx, PyMuPDF). All imports are lazy
and guarded, so a missing library only blocks the matching format —
other formats keep working.
"""

from __future__ import annotations

import zipfile
from pathlib import Path
from typing import List, Optional, TypedDict


class TextSample(TypedDict):
    """A (source_placeholder, translated) pair from an output file."""
    source: str
    translated: str


# Maximum samples per format — keeps the L0 check fast.
DEFAULT_MAX_SAMPLES = 20


def extract_sample(
    file_path: Path,
    file_extension: str,
    max_samples: int = DEFAULT_MAX_SAMPLES,
) -> List[TextSample]:
    """
    Extract a sample of translated text strings from a finished file.

    The "source" field is always empty — we don't have the original
    document at this point. The L0 checks that care about source/target
    ratio (length_checker) handle empty source gracefully.

    Returns an empty list if the file cannot be read.
    """
    if not file_path or not Path(file_path).exists():
        return []

    ext = (file_extension or Path(file_path).suffix).lower()
    try:
        if ext == ".docx":
            return _extract_docx(file_path, max_samples)
        if ext == ".xlsx":
            return _extract_xlsx(file_path, max_samples)
        if ext == ".pptx":
            return _extract_pptx(file_path, max_samples)
        if ext == ".pdf":
            return _extract_pdf(file_path, max_samples)
    except Exception:
        # Any failure: return an empty list. The route will log it.
        return []
    return []


def _extract_docx(path: Path, max_samples: int) -> List[TextSample]:
    """Extract text from a Word document."""
    from docx import Document
    doc = Document(str(path))
    samples: List[TextSample] = []
    for para in doc.paragraphs:
        text = (para.text or "").strip()
        if text and len(text) > 5:
            samples.append({"source": "", "translated": text})
            if len(samples) >= max_samples:
                break
    # If body had nothing, try tables.
    if not samples:
        for table in doc.tables:
            for row in table.rows:
                for cell in row.cells:
                    text = (cell.text or "").strip()
                    if text and len(text) > 5:
                        samples.append({"source": "", "translated": text})
                        if len(samples) >= max_samples:
                            return samples
    return samples


def _extract_xlsx(path: Path, max_samples: int) -> List[TextSample]:
    """Extract text from an Excel file."""
    from openpyxl import load_workbook
    wb = load_workbook(str(path), data_only=True, read_only=True)
    samples: List[TextSample] = []
    try:
        for ws in wb.worksheets:
            for row in ws.iter_rows():
                for cell in row:
                    val = cell.value
                    if isinstance(val, str):
                        text = val.strip()
                        if text and len(text) > 3:
                            samples.append({"source": "", "translated": text})
                            if len(samples) >= max_samples:
                                return samples
    finally:
        wb.close()
    return samples


def _extract_pptx(path: Path, max_samples: int) -> List[TextSample]:
    """Extract text from a PowerPoint file."""
    from pptx import Presentation
    pres = Presentation(str(path))
    samples: List[TextSample] = []
    for slide in pres.slides:
        for shape in slide.shapes:
            if not shape.has_text_frame:
                continue
            for para in shape.text_frame.paragraphs:
                text = (para.text or "").strip()
                if text and len(text) > 3:
                    samples.append({"source": "", "translated": text})
                    if len(samples) >= max_samples:
                        return samples
    return samples


def _extract_pdf(path: Path, max_samples: int) -> List[TextSample]:
    """Extract text from a PDF file (best-effort, layout-preserving format)."""
    try:
        import fitz  # PyMuPDF
    except ImportError:
        return []
    samples: List[TextSample] = []
    doc = fitz.open(str(path))
    try:
        for page in doc:
            text = page.get_text("text") or ""
            for line in text.splitlines():
                line = line.strip()
                if line and len(line) > 5:
                    samples.append({"source": "", "translated": line})
                    if len(samples) >= max_samples:
                        return samples
    finally:
        doc.close()
    return samples
