"""
Tests for Vision Embedding Provider

Tests for multimodal image embedding capabilities.
"""

from pathlib import Path

import pytest

# ─────────────────────────────────────────────────────────────────────────────
# Unit Tests: VisionEmbeddingProvider
# ─────────────────────────────────────────────────────────────────────────────


class TestVisionEmbeddingProvider:
    """Tests for VisionEmbeddingProvider."""

    def test_initialization(self):
        """Test provider initialization."""
        from mcard.rag.embeddings import VisionEmbeddingProvider

        provider = VisionEmbeddingProvider()

        assert provider.vision_model == "moondream"
        assert provider.text_embedder is not None
        assert provider.dimensions == 768  # nomic-embed-text default

    def test_custom_models(self):
        """Test provider with custom models."""
        from mcard.rag.embeddings import VisionEmbeddingProvider

        provider = VisionEmbeddingProvider(
            vision_model="llava", embedding_model="bge-m3"
        )

        assert provider.vision_model == "llava"
        assert provider.text_embedder.model_name == "bge-m3"
        assert provider.dimensions == 1024

    def test_model_name_property(self):
        """Test combined model name property."""
        from mcard.rag.embeddings import VisionEmbeddingProvider

        provider = VisionEmbeddingProvider()
        model_name = provider.model_name

        assert "vision" in model_name
        assert "moondream" in model_name
        assert "nomic-embed-text" in model_name

    def test_provider_name(self):
        """Test provider name property."""
        from mcard.rag.embeddings import VisionEmbeddingProvider

        provider = VisionEmbeddingProvider()
        assert provider.provider_name == "ollama-vision"

    def test_get_info(self):
        """Test get_info method."""
        from mcard.rag.embeddings import VisionEmbeddingProvider

        provider = VisionEmbeddingProvider()
        info = provider.get_info()

        assert "provider" in info
        assert "vision_model" in info
        assert "embedding_model" in info
        assert "dimensions" in info
        assert "vision_models_available" in info

    def test_text_embedding_delegation(self):
        """Test that text embedding delegates to text embedder."""
        from mcard.rag.embeddings import VisionEmbeddingProvider

        provider = VisionEmbeddingProvider()

        # Test embed method exists and is callable
        assert callable(provider.embed)
        assert callable(provider.embed_batch)


# ─────────────────────────────────────────────────────────────────────────────
# Unit Tests: Vision Models Configuration
# ─────────────────────────────────────────────────────────────────────────────


class TestVisionModelsConfig:
    """Tests for vision models configuration."""

    def test_vision_models_exist(self):
        """Test that vision models are defined."""
        from mcard.rag.embeddings import VISION_MODELS

        assert "moondream" in VISION_MODELS
        assert "llama3.2-vision" in VISION_MODELS
        assert "llava" in VISION_MODELS
        assert "minicpm-v" in VISION_MODELS

    def test_vision_model_structure(self):
        """Test vision model config structure."""
        from mcard.rag.embeddings import VISION_MODELS

        for model_name, config in VISION_MODELS.items():
            assert "description" in config

    def test_config_vision_models(self):
        """Test vision models in RAG config."""
        from mcard.rag.config import DEFAULT_VISION_MODEL, VISION_MODELS

        assert DEFAULT_VISION_MODEL in VISION_MODELS
        assert VISION_MODELS[DEFAULT_VISION_MODEL]["description"]


# ─────────────────────────────────────────────────────────────────────────────
# Mock Tests: Image Processing
# ─────────────────────────────────────────────────────────────────────────────


class TestImageProcessing:
    """Tests for image data handling."""

    def test_base64_image_handling(self):
        """Test that base64 images are handled correctly."""
        from mcard.rag.embeddings import VisionEmbeddingProvider

        # Create a minimal PNG (1x1 pixel)
        # This is the smallest valid PNG
        minimal_png_b64 = (
            "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4"
            "nGNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg=="
        )

        provider = VisionEmbeddingProvider()

        # Just test that provider can be created and has correct methods
        assert hasattr(provider, "describe_image")
        assert hasattr(provider, "embed_image")
        assert hasattr(provider, "embed_image_with_description")


# ─────────────────────────────────────────────────────────────────────────────
# Integration Tests (Require Ollama with Vision Model)
# ─────────────────────────────────────────────────────────────────────────────


@pytest.mark.network
@pytest.mark.slow
@pytest.mark.skipif(
    False,  # Enable for live testing
    reason="Live tests require Ollama with vision model",
)
class TestLiveVisionEmbedding:
    """Live integration tests for vision embedding."""

    def test_validate_connection(self):
        """Test connection validation."""
        from mcard.rag.embeddings import VisionEmbeddingProvider

        provider = VisionEmbeddingProvider()
        assert provider.validate_connection()

    def test_describe_image(self):
        """Test image description generation."""
        from mcard.rag.embeddings import VisionEmbeddingProvider

        image_path = Path("tests/test_data/sample.png")
        if not image_path.exists():
            pytest.skip("Sample image not found")

        provider = VisionEmbeddingProvider()
        description = provider.describe_image(image_path)

        assert description
        assert len(description) > 0

    def test_embed_image(self):
        """Test image embedding generation."""
        from mcard.rag.embeddings import VisionEmbeddingProvider

        image_path = Path("tests/test_data/sample.png")
        if not image_path.exists():
            pytest.skip("Sample image not found")

        provider = VisionEmbeddingProvider()
        embedding = provider.embed_image(image_path)

        assert len(embedding) == 768
        assert all(isinstance(x, float) for x in embedding)

    def test_embed_image_with_description(self):
        """Test combined embedding and description."""
        from mcard.rag.embeddings import VisionEmbeddingProvider

        image_path = Path("tests/test_data/sample.png")
        if not image_path.exists():
            pytest.skip("Sample image not found")

        provider = VisionEmbeddingProvider()
        embedding, description = provider.embed_image_with_description(image_path)

        assert len(embedding) == 768
        assert description

    def test_cross_modal_search(self):
        """Test that image embeddings can find similar text."""
        from mcard import MCard
        from mcard.rag import MCardRAGEngine
        from mcard.rag.embeddings import VisionEmbeddingProvider

        # Create RAG engine
        rag = MCardRAGEngine(vector_db_path=":memory:")

        # Index Python-related content
        mcard = MCard("Python is a programming language with a snake logo.")
        rag.vector_store.index(mcard)

        # Describe a Python logo image
        provider = VisionEmbeddingProvider()
        description = "A blue and yellow Python programming language logo"

        # Search using text that matches image content
        results = rag.vector_store.search(description, k=1)

        assert len(results) > 0
