"""Integration tests for vector operations.

These tests require a running PostgreSQL instance with pgvector.
"""

import pytest

pytestmark = pytest.mark.integration


@pytest.fixture
def vector_table(db):
    """Create a test table with vector data."""
    db.sql("DROP TABLE IF EXISTS test_vectors")
    db.commit()
    db.sql(
        "CREATE TABLE test_vectors ("
        "  id serial PRIMARY KEY,"
        "  title text,"
        "  embedding vector(3)"
        ")"
    )
    db.commit()

    # Insert some test vectors
    db.sql(
        "INSERT INTO test_vectors (title, embedding) VALUES "
        "('doc1', '[1.0, 0.0, 0.0]'),"
        "('doc2', '[0.0, 1.0, 0.0]'),"
        "('doc3', '[0.0, 0.0, 1.0]'),"
        "('doc4', '[0.7, 0.7, 0.0]'),"
        "('doc5', '[0.5, 0.5, 0.5]')"
    )
    db.commit()

    yield "test_vectors"

    # Cleanup
    db.sql("DROP TABLE IF EXISTS test_vectors")
    db.commit()


def test_vector_search_cosine(db, vector_table):
    result = db.vector_search(
        vector_table, "embedding", [1.0, 0.0, 0.0],
        k=3, metric="cosine",
    )
    assert len(result) == 3
    df = result.to_df()
    assert "_distance" in df.columns
    # doc1 should be closest (exact match)
    assert df.iloc[0]["title"] == "doc1"


def test_vector_search_l2(db, vector_table):
    result = db.vector_search(
        vector_table, "embedding", [1.0, 0.0, 0.0],
        k=2, metric="l2",
    )
    assert len(result) == 2
    assert result.records[0]["title"] == "doc1"


def test_vector_search_with_where(db, vector_table):
    result = db.vector_search(
        vector_table, "embedding", [1.0, 0.0, 0.0],
        k=10, metric="cosine",
        where="title LIKE 'doc1%' OR title LIKE 'doc4%'",
    )
    assert len(result) <= 2


def test_vector_search_with_columns(db, vector_table):
    result = db.vector_search(
        vector_table, "embedding", [1.0, 0.0, 0.0],
        k=3, metric="cosine", columns=["id", "title"],
    )
    df = result.to_df()
    assert "id" in df.columns
    assert "title" in df.columns


def test_create_vector_index(db, vector_table):
    db.create_vector_index(
        vector_table, "embedding",
        method="hnsw", metric="cosine",
        name="test_hnsw_idx",
    )
    # Verify index exists
    from piggie._vector.index import list_vector_indexes
    indexes = list_vector_indexes(db.connection, vector_table)
    idx_names = [idx["name"] for idx in indexes]
    assert "test_hnsw_idx" in idx_names

    # Cleanup
    from piggie._vector.index import drop_vector_index
    drop_vector_index(db.connection, "test_hnsw_idx")


def test_invalid_metric(db, vector_table):
    from piggie.exceptions import VectorError
    with pytest.raises(VectorError, match="Unknown metric"):
        db.vector_search(
            vector_table, "embedding", [1.0, 0.0, 0.0],
            metric="invalid",
        )
