import subprocess
import sys
import tempfile
from pathlib import Path
from typing import BinaryIO, Any

sys.path.insert(0, str(Path(__file__).parent))
from _vlm_base import VLMBase
from _slides import render_pdf_as_slides

import openai
from markitdown import MarkItDown
from markitdown._base_converter import DocumentConverterResult
from markitdown._stream_info import StreamInfo

_SLIDE_PROMPT = "Describe the content of this slide accurately (all text must be verbatim) and concisely."


class SlideshowConverter(VLMBase):
    """Converts PPTX slides to images via LibreOffice, then describes each with an LLM."""

    def accepts(self, _file_stream: BinaryIO, stream_info: StreamInfo, **_kwargs: Any) -> bool:
        ext = (stream_info.extension or "").lower()
        mime = (stream_info.mimetype or "").lower()
        return ext == ".pptx" or "presentationml" in mime

    def convert(self, file_stream: BinaryIO, stream_info: StreamInfo, **kwargs: Any) -> DocumentConverterResult:
        llm_client = kwargs.get("llm_client") or self._llm_client
        llm_model = kwargs.get("llm_model") or self._llm_model

        source_name = Path(stream_info.filename or "presentation").stem.replace(" ", "-")
        local_path = stream_info.local_path or stream_info.filename
        output_dir = Path(local_path).parent if local_path else Path.cwd()

        with tempfile.TemporaryDirectory() as tmp:
            tmp_path = Path(tmp)
            pptx_path = tmp_path / "presentation.pptx"
            pptx_path.write_bytes(file_stream.read())

            result = subprocess.run(
                ["libreoffice", "--headless", "--convert-to", "pdf", "--outdir", tmp, str(pptx_path)],
                capture_output=True, text=True
            )
            if result.returncode != 0:
                raise RuntimeError(f"LibreOffice conversion failed: {result.stderr}")

            pdf_files = list(tmp_path.glob("*.pdf"))
            if not pdf_files:
                raise RuntimeError("LibreOffice produced no PDF output")

            describe = (lambda p: self._describe(p, llm_client, llm_model, _SLIDE_PROMPT)) if llm_client and llm_model else None
            markdown = render_pdf_as_slides(pdf_files[0], output_dir, source_name, describe)

        return DocumentConverterResult(markdown=markdown)


def register_converters(markitdown_instance, **_kwargs):
    markitdown_instance.register_converter(SlideshowConverter())


if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument("pptx", help="Path to the .pptx file")
    parser.add_argument("--output", "-o", help="Output markdown file (default: <name>.md)")
    args = parser.parse_args()

    pptx_path = Path(args.pptx)
    out_path = Path(args.output) if args.output else pptx_path.with_stem(pptx_path.stem.replace(" ", "-")).with_suffix(".md")

    client = openai.OpenAI(base_url="http://localhost:8500/v1", api_key="none")
    md = MarkItDown(llm_client=client, llm_model="Qwen3.6-35B-A3B-UD-IQ2_XXS.gguf")
    md.register_converter(SlideshowConverter())

    result = md.convert(str(pptx_path))
    out_path.write_text(result.text_content)
    print(f"Written to {out_path}")
