"""Tests for design-search BM25 engine"""

import sys
from pathlib import Path

# Add parent to path for imports
sys.path.insert(0, str(Path(__file__).parent))

from core import (  # pyright: ignore[reportMissingImports]
    BM25,
    CSV_CONFIG,
    DATA_DIR,
    STACK_CONFIG,
    detect_domain,
    search,
    search_stack,
)

# ============ BM25 UNIT TESTS ============


def test_bm25_basic():
    """BM25 basic operation: fit + score returns ranked results"""
    bm25 = BM25(k1=1.5, b=0.75)
    docs = [
        "warm red premium color palette",
        "cold blue minimal design",
        "warm golden luxury premium",
    ]
    bm25.fit(docs)
    scores = bm25.score("warm premium")

    # Should return 3 scored entries
    assert len(scores) == 3

    # First result should be most relevant (contains both "warm" and "premium")
    _, top_score = scores[0]
    assert top_score > 0
    # doc 0 and doc 2 both contain "warm" or "premium"; top should have score > last
    _, last_score = scores[-1]
    assert top_score >= last_score


def test_bm25_empty_corpus():
    """BM25 handles empty corpus without error"""
    bm25 = BM25()
    bm25.fit([])
    scores = bm25.score("anything")
    assert scores == []


# ============ SEARCH FUNCTION TESTS ============


def test_search_color_warm_premium():
    """search('warm premium', 'color') returns at least 1 result"""
    result = search("warm premium", "color")
    assert "error" not in result
    assert result["domain"] == "color"
    assert int(result["count"]) > 0
    assert len(result["results"]) > 0


def test_search_style():
    """search('minimalism dark', 'style') returns at least 1 result"""
    result = search("minimalism dark", "style")
    assert "error" not in result
    assert result["domain"] == "style"
    assert int(result["count"]) > 0
    assert len(result["results"]) > 0


def test_search_typography():
    """search('modern clean', 'typography') returns at least 1 result"""
    result = search("modern clean", "typography")
    assert "error" not in result
    assert result["domain"] == "typography"
    assert int(result["count"]) > 0
    assert len(result["results"]) > 0


def test_search_auto_detect():
    """search('warm color palette') auto-detects domain as 'color'"""
    result = search("warm color palette")
    assert "error" not in result
    assert result["domain"] == "color"


# ============ STACK SEARCH TESTS ============


def test_search_stack_nextjs():
    """search_stack('server components', 'nextjs') returns at least 1 result"""
    result = search_stack("server components", "nextjs")
    assert "error" not in result
    assert result["stack"] == "nextjs"
    assert int(result["count"]) > 0
    assert len(result["results"]) > 0


def test_search_stack_unknown():
    """search_stack with unknown stack returns error key"""
    result = search_stack("test query", "unknown_stack")
    assert "error" in result


# ============ DETECT DOMAIN TESTS ============


def test_detect_domain_color():
    """detect_domain('warm color palette') returns 'color'"""
    domain = detect_domain("warm color palette")
    assert domain == "color"


def test_detect_domain_style():
    """detect_domain('minimalist design ui') returns 'style'"""
    domain = detect_domain("minimalist design ui")
    assert domain == "style"


# ============ FILE EXISTENCE TESTS ============


def test_csv_file_missing():
    """search with missing CSV file returns error key"""
    # Temporarily test with a domain whose file we know doesn't exist
    # We'll test by passing a made-up domain that falls back to style,
    # or by directly calling _search_csv with a nonexistent path
    from core import _search_csv  # pyright: ignore[reportMissingImports]

    nonexistent = Path("/tmp/definitely_does_not_exist_xyz.csv")
    results = _search_csv(nonexistent, ["col"], ["col"], "query", 3)
    # _search_csv returns empty list if file doesn't exist
    assert results == []


def test_all_csv_exist():
    """All CSV files listed in CSV_CONFIG exist in data/ directory"""
    missing = []
    for domain, config in CSV_CONFIG.items():
        filepath = DATA_DIR / config["file"]
        if not filepath.exists():
            missing.append(f"{domain}: {filepath}")
    assert missing == [], f"Missing CSV files: {missing}"


def test_all_stack_csv_exist():
    """All CSV files listed in STACK_CONFIG exist in data/stacks/ directory"""
    missing = []
    for stack, config in STACK_CONFIG.items():
        filepath = DATA_DIR / config["file"]
        if not filepath.exists():
            missing.append(f"{stack}: {filepath}")
    assert missing == [], f"Missing stack CSV files: {missing}"
