"""Tests for VelesQL v2.0 features in LangChain integration.

EPIC-016 US-052: VelesQL v2.0 - Filtres LangChain

Run with: pytest tests/test_velesql_v2.py -v
"""

import tempfile
import shutil
from typing import List

import pytest

try:
    from langchain_velesdb import VelesDBVectorStore
    from langchain_core.documents import Document
    from langchain_core.embeddings import Embeddings
except ImportError:
    pytest.skip("Dependencies not installed", allow_module_level=True)


class FakeEmbeddings(Embeddings):
    """Fake embeddings for testing."""

    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        return [[float(i) / 10 for i in range(4)] for _ in texts]

    def embed_query(self, text: str) -> List[float]:
        return [0.1, 0.2, 0.3, 0.4]


@pytest.fixture
def temp_db_path():
    """Create a temporary directory for database tests."""
    path = tempfile.mkdtemp(prefix="velesdb_langchain_v2_test_")
    yield path
    shutil.rmtree(path, ignore_errors=True)


@pytest.fixture
def embeddings():
    """Return fake embeddings for testing."""
    return FakeEmbeddings()


@pytest.fixture
def vectorstore(temp_db_path, embeddings):
    """Create a vector store with test data."""
    vs = VelesDBVectorStore(
        embedding=embeddings,
        path=temp_db_path,
        collection_name="test_v2",
    )
    # Add test documents with categories
    vs.add_texts(
        texts=["AI document 1", "AI document 2", "ML document 1"],
        metadatas=[
            {"category": "ai", "price": 100},
            {"category": "ai", "price": 200},
            {"category": "ml", "price": 150},
        ],
    )
    return vs


class TestVelesQLv2GroupBy:
    """Tests for GROUP BY with aggregates."""

    def test_similarity_search_basic(self, vectorstore):
        """Basic similarity search still works."""
        results = vectorstore.similarity_search("AI", k=2)
        assert len(results) <= 2
        assert all(isinstance(doc, Document) for doc in results)

    def test_similarity_search_with_filter_syntax(self, vectorstore):
        """Similarity search accepts filter parameter."""
        # Test that filter parameter is accepted (server handles VelesQL v2.0)
        results = vectorstore.similarity_search(
            "AI",
            k=10,
            filter={"category": "ai"},
        )
        # Filter may or may not work depending on backend, but API accepts it
        assert isinstance(results, list)


class TestVelesQLv2OrderBy:
    """Tests for ORDER BY enhancements."""

    def test_similarity_search_score_threshold(self, vectorstore):
        """Search with score threshold."""
        results = vectorstore.similarity_search_with_score("AI", k=10)
        assert all(isinstance(r, tuple) and len(r) == 2 for r in results)
        # Results should be ordered by score (descending)
        scores = [score for _, score in results]
        assert scores == sorted(scores, reverse=True)


class TestVelesQLv2DirectQuery:
    """Tests for direct VelesQL query execution."""

    def test_vectorstore_has_query_method(self, vectorstore):
        """VectorStore should have query method for VelesQL."""
        # Check if the vectorstore exposes query capability
        assert hasattr(vectorstore, '_collection') or hasattr(vectorstore, 'db')


class TestVelesQLv2Integration:
    """Integration tests for VelesQL v2.0 features."""

    def test_add_and_search_workflow(self, temp_db_path, embeddings):
        """Complete workflow: add documents, search with filters."""
        vs = VelesDBVectorStore(
            embedding=embeddings,
            path=temp_db_path,
            collection_name="workflow_test",
        )

        # Add documents with different categories
        vs.add_texts(
            texts=[
                "Python programming guide",
                "JavaScript tutorial",
                "Python data science",
                "JavaScript web development",
            ],
            metadatas=[
                {"category": "python", "level": "beginner"},
                {"category": "javascript", "level": "beginner"},
                {"category": "python", "level": "advanced"},
                {"category": "javascript", "level": "intermediate"},
            ],
        )

        # Search with category filter (API accepts filter param)
        python_docs = vs.similarity_search(
            "programming",
            k=10,
            filter={"category": "python"},
        )
        assert isinstance(python_docs, list)

        # Basic search without filter
        all_docs = vs.similarity_search("tutorial", k=10)
        assert len(all_docs) > 0

    def test_similarity_search_with_score(self, temp_db_path, embeddings):
        """Test similarity search returns scores."""
        vs = VelesDBVectorStore(
            embedding=embeddings,
            path=temp_db_path,
            collection_name="score_test",
        )
        vs.add_texts(["Doc 1", "Doc 2", "Doc 3"])
        
        results = vs.similarity_search_with_score("Doc", k=2)
        assert len(results) <= 2
        assert all(isinstance(r, tuple) and len(r) == 2 for r in results)

    def test_from_texts_classmethod(self, temp_db_path, embeddings):
        """Test creating vectorstore from texts."""
        vs = VelesDBVectorStore.from_texts(
            texts=["Document 1", "Document 2"],
            embedding=embeddings,
            path=temp_db_path,
            collection_name="from_texts_test",
        )
        assert vs is not None

        results = vs.similarity_search("Document", k=2)
        assert len(results) == 2


class TestVelesQLv2Documentation:
    """Tests to verify documented features work."""

    def test_readme_example_basic_usage(self, temp_db_path, embeddings):
        """Test basic usage from README."""
        # From README: Basic usage
        vectorstore = VelesDBVectorStore(
            embedding=embeddings,
            path=temp_db_path,
            collection_name="readme_test",
        )

        # Add documents
        vectorstore.add_texts(
            texts=["Hello VelesDB", "Fast vector search"],
            metadatas=[{"source": "test"}] * 2,
        )

        # Search
        results = vectorstore.similarity_search("vector", k=1)
        assert len(results) >= 1

    def test_readme_example_with_filter(self, temp_db_path, embeddings):
        """Test filtered search from README."""
        vectorstore = VelesDBVectorStore(
            embedding=embeddings,
            path=temp_db_path,
            collection_name="filter_test",
        )

        vectorstore.add_texts(
            texts=["Tech article", "Science paper"],
            metadatas=[
                {"category": "tech"},
                {"category": "science"},
            ],
        )

        # Filter parameter is accepted by API
        results = vectorstore.similarity_search(
            "article",
            k=10,
            filter={"category": "tech"},
        )
        # API accepts filter, actual filtering handled by VelesQL v2.0 backend
        assert isinstance(results, list)
