"""Unit tests for PDF document conversion functionality."""

import uuid
from pathlib import Path
from unittest.mock import MagicMock, Mock, patch

import pytest

from src.extraction_v2.document_converter import DocumentToHtmlConverter


class TestPdfConversion:
    """Test PDF conversion functionality."""

    @pytest.fixture
    def converter(self):
        """Create a DocumentToHtmlConverter instance for testing."""
        return DocumentToHtmlConverter()

    def test_convert_pdf_to_markdown_success(self, converter, tmp_path):
        """Test successful PDF to Markdown conversion."""
        # Create a test PDF file with proper PDF header
        pdf_file = tmp_path / "test.pdf"
        pdf_file.write_bytes(b"%PDF-1.4\n%Test PDF content")

        # Mock the Docling converter
        mock_result = Mock()
        mock_document = Mock()
        mock_document.export_to_markdown = Mock(return_value="# Test Markdown\n\nSample content")
        mock_result.document = mock_document
        converter.converter.convert = Mock(return_value=mock_result)

        # Test conversion
        markdown = converter._convert_pdf_to_markdown(str(pdf_file))

        assert markdown is not None
        assert len(markdown) > 0
        assert "Test Markdown" in markdown
        converter.converter.convert.assert_called_once_with(str(pdf_file))

    def test_convert_pdf_validation_failure_file_not_found(self, converter):
        """Test PDF conversion with missing file."""
        markdown = converter._convert_pdf_to_markdown("nonexistent.pdf")
        assert markdown is None

    def test_convert_pdf_validation_failure_too_large(self, converter, tmp_path):
        """Test PDF validation fails for files larger than 100MB."""
        pdf_file = tmp_path / "large.pdf"
        pdf_file.write_bytes(b"%PDF-1.4\n" + b"x" * (101 * 1024 * 1024))

        markdown = converter._convert_pdf_to_markdown(str(pdf_file))
        assert markdown is None

    def test_convert_pdf_validation_failure_invalid_extension(self, converter, tmp_path):
        """Test PDF validation fails for non-PDF extension."""
        txt_file = tmp_path / "test.txt"
        txt_file.write_text("Not a PDF")

        markdown = converter._convert_pdf_to_markdown(str(txt_file))
        assert markdown is None

    def test_convert_pdf_validation_failure_invalid_header(self, converter, tmp_path):
        """Test PDF validation fails for invalid PDF header."""
        invalid_pdf = tmp_path / "invalid.pdf"
        invalid_pdf.write_bytes(b"Not a PDF file")

        markdown = converter._convert_pdf_to_markdown(str(invalid_pdf))
        assert markdown is None

    def test_convert_pdf_docling_failure(self, converter, tmp_path):
        """Test handling of Docling conversion failure."""
        pdf_file = tmp_path / "test.pdf"
        pdf_file.write_bytes(b"%PDF-1.4\n%Test PDF content")

        # Mock Docling to raise an exception
        converter.converter.convert = Mock(side_effect=RuntimeError("Docling error"))

        markdown = converter._convert_pdf_to_markdown(str(pdf_file))
        assert markdown is None

    def test_convert_pdf_empty_result(self, converter, tmp_path):
        """Test handling when Docling returns empty result."""
        pdf_file = tmp_path / "test.pdf"
        pdf_file.write_bytes(b"%PDF-1.4\n%Test PDF content")

        # Mock Docling to return None
        converter.converter.convert = Mock(return_value=None)

        markdown = converter._convert_pdf_to_markdown(str(pdf_file))
        assert markdown is None


class TestPdfValidation:
    """Test PDF file validation."""

    @pytest.fixture
    def converter(self):
        """Create a DocumentToHtmlConverter instance for testing."""
        return DocumentToHtmlConverter()

    def test_validate_pdf_file_valid(self, converter, tmp_path):
        """Test validation of a valid PDF file."""
        pdf_file = tmp_path / "valid.pdf"
        pdf_file.write_bytes(b"%PDF-1.4\nSome PDF content")

        valid, msg = converter._validate_pdf_file(pdf_file)
        assert valid is True
        assert msg is None

    def test_validate_pdf_file_not_found(self, converter):
        """Test validation fails for non-existent file."""
        valid, msg = converter._validate_pdf_file(Path("nonexistent.pdf"))
        assert valid is False
        assert "not found" in msg.lower()

    def test_validate_pdf_file_too_large(self, converter, tmp_path):
        """Test validation fails for files over 100MB."""
        large_pdf = tmp_path / "large.pdf"
        # Create a file larger than 100MB
        large_pdf.write_bytes(b"%PDF-1.4\n" + b"x" * (101 * 1024 * 1024))

        valid, msg = converter._validate_pdf_file(large_pdf)
        assert valid is False
        assert "too large" in msg.lower()

    def test_validate_pdf_file_wrong_extension(self, converter, tmp_path):
        """Test validation fails for non-PDF extension."""
        txt_file = tmp_path / "test.txt"
        txt_file.write_text("Not a PDF")

        valid, msg = converter._validate_pdf_file(txt_file)
        assert valid is False
        assert "not a pdf" in msg.lower()

    def test_validate_pdf_file_invalid_header(self, converter, tmp_path):
        """Test validation fails for files without PDF header."""
        invalid_pdf = tmp_path / "invalid.pdf"
        invalid_pdf.write_bytes(b"Not a real PDF")

        valid, msg = converter._validate_pdf_file(invalid_pdf)
        assert valid is False
        assert "invalid" in msg.lower() or "missing" in msg.lower()

    def test_validate_pdf_file_short_header(self, converter, tmp_path):
        """Test validation handles files with partial PDF header."""
        short_pdf = tmp_path / "short.pdf"
        short_pdf.write_bytes(b"%PD")  # Incomplete header

        valid, msg = converter._validate_pdf_file(short_pdf)
        assert valid is False
        assert "invalid" in msg.lower() or "missing" in msg.lower()


class TestConvertToHtmlRouting:
    """Test document type routing in convert_to_html."""

    @pytest.fixture
    def converter(self):
        """Create a DocumentToHtmlConverter instance for testing."""
        return DocumentToHtmlConverter()

    def test_convert_to_html_routes_pdf(self, converter, tmp_path):
        """Test that PDF files are routed to _convert_pdf_to_markdown."""
        pdf_file = tmp_path / "test.pdf"
        pdf_file.write_bytes(b"%PDF-1.4\nTest content")

        # Mock the PDF conversion method
        converter._convert_pdf_to_markdown = Mock(return_value="# PDF Markdown")

        result = converter.convert_to_html(str(pdf_file))

        converter._convert_pdf_to_markdown.assert_called_once_with(str(pdf_file))
        assert result == "# PDF Markdown"

    def test_convert_to_html_unsupported_format(self, converter, tmp_path):
        """Test that unsupported formats return None."""
        txt_file = tmp_path / "test.txt"
        txt_file.write_text("Plain text")

        result = converter.convert_to_html(str(txt_file))
        assert result is None
