"""Tests for hybrid_search threshold filtering and language parameter."""

from __future__ import annotations

from unittest.mock import AsyncMock, MagicMock

import pytest

from app.rag.search import hybrid_search

pytestmark = pytest.mark.anyio


def _mock_row(id, content, source, metadata, rrf_score):
    row = MagicMock()
    row.id = id
    row.content = content
    row.source = source
    row.metadata = metadata
    row.rrf_score = rrf_score
    return row


async def test_results_above_threshold_are_returned():
    session = AsyncMock()
    rows = [
        _mock_row("1", "High match", "faq", {}, 0.02),
        _mock_row("2", "Medium match", "faq", {}, 0.01),
    ]
    exec_result = MagicMock()
    exec_result.fetchall.return_value = rows
    session.execute.return_value = exec_result

    results = await hybrid_search(session, "test query", [0.1] * 10, "rest-1", min_score=0.008)

    assert len(results) == 2
    assert results[0]["score"] == 0.02
    assert results[1]["score"] == 0.01


async def test_min_score_param_is_passed_to_sql():
    """Verify min_score is passed as a SQL bind parameter."""
    session = AsyncMock()
    exec_result = MagicMock()
    exec_result.fetchall.return_value = []
    session.execute.return_value = exec_result

    await hybrid_search(session, "test", [0.1], "rest-1", min_score=0.05)

    call_args = session.execute.call_args
    params = call_args[0][1]
    assert params["min_score"] == 0.05


async def test_language_param_is_passed_to_sql():
    session = AsyncMock()
    exec_result = MagicMock()
    exec_result.fetchall.return_value = []
    session.execute.return_value = exec_result

    await hybrid_search(session, "test", [0.1], "rest-1", language="english")

    params = session.execute.call_args[0][1]
    assert params["language"] == "english"


async def test_unsupported_language_falls_back_to_dutch():
    session = AsyncMock()
    exec_result = MagicMock()
    exec_result.fetchall.return_value = []
    session.execute.return_value = exec_result

    await hybrid_search(session, "test", [0.1], "rest-1", language="french")

    params = session.execute.call_args[0][1]
    assert params["language"] == "dutch"


async def test_empty_results_returns_empty_list():
    session = AsyncMock()
    exec_result = MagicMock()
    exec_result.fetchall.return_value = []
    session.execute.return_value = exec_result

    results = await hybrid_search(session, "", [0.1], "rest-1")

    assert results == []


async def test_default_min_score_is_0_008():
    session = AsyncMock()
    exec_result = MagicMock()
    exec_result.fetchall.return_value = []
    session.execute.return_value = exec_result

    await hybrid_search(session, "test", [0.1], "rest-1")

    params = session.execute.call_args[0][1]
    assert params["min_score"] == 0.008


async def test_default_language_is_dutch():
    session = AsyncMock()
    exec_result = MagicMock()
    exec_result.fetchall.return_value = []
    session.execute.return_value = exec_result

    await hybrid_search(session, "test", [0.1], "rest-1")

    params = session.execute.call_args[0][1]
    assert params["language"] == "dutch"
