"""Markitdown parser implementation."""

import asyncio
import logging
import tempfile
from pathlib import Path

from .base import FileParser

logger = logging.getLogger(__name__)


class MarkitdownParser(FileParser):
    """
    Markitdown file parser.

    Uses Microsoft's markitdown library to convert various file formats
    to markdown including PDF, Office docs, images (via OCR), audio, HTML.

    Supported formats:
    - PDF (.pdf)
    - Word (.docx, .doc)
    - PowerPoint (.pptx, .ppt)
    - Excel (.xlsx, .xls)
    - Images (.jpg, .jpeg, .png) - with OCR
    - HTML (.html, .htm)
    - Text (.txt, .md)
    - Audio (.mp3, .wav) - with transcription
    """

    def __init__(self):
        """Initialize markitdown parser."""
        # Lazy import to avoid requiring markitdown for all users
        try:
            from markitdown import MarkItDown

            self._markitdown = MarkItDown()
        except ImportError as e:
            raise ImportError(
                "markitdown package is required for file parsing. Install with: pip install markitdown"
            ) from e

    async def convert(self, file_data: bytes, filename: str) -> str:
        """Parse file to markdown using markitdown."""
        # markitdown is synchronous, so we run it in executor to avoid blocking
        loop = asyncio.get_event_loop()
        return await loop.run_in_executor(None, self._convert_sync, file_data, filename)

    def _convert_sync(self, file_data: bytes, filename: str) -> str:
        """Synchronous parsing (runs in thread pool)."""
        # Write to temp file (markitdown requires file path)
        with tempfile.NamedTemporaryFile(suffix=Path(filename).suffix, delete=False) as tmp:
            tmp.write(file_data)
            tmp_path = tmp.name

        try:
            # Parse using markitdown
            result = self._markitdown.convert(tmp_path)

            if not result or not result.text_content:
                raise RuntimeError(f"No content extracted from '{filename}'")

            return result.text_content

        except Exception as e:
            logger.error(f"Markitdown parsing failed for {filename}: {e}")
            raise RuntimeError(f"Failed to parse '{filename}': {e}") from e

        finally:
            # Clean up temp file
            try:
                Path(tmp_path).unlink()
            except Exception:
                pass

    def supports(self, filename: str, content_type: str | None = None) -> bool:
        """Check if markitdown supports this file type."""
        # Supported extensions (from markitdown docs)
        supported_extensions = {
            # Documents
            ".pdf",
            ".docx",
            ".doc",
            ".pptx",
            ".ppt",
            ".xlsx",
            ".xls",
            # Images (with OCR)
            ".jpg",
            ".jpeg",
            ".png",
            # Web
            ".html",
            ".htm",
            # Text
            ".txt",
            ".md",
            ".csv",
            # Audio (with transcription)
            ".mp3",
            ".wav",
        }

        ext = Path(filename).suffix.lower()
        return ext in supported_extensions

    def name(self) -> str:
        """Get parser name."""
        return "markitdown"
