"""Tests for search domain models."""

from __future__ import annotations

import pytest

from search.models import (
    IndexConfig,
    SearchDocument,
    SearchQuery,
    SearchResponse,
    SearchResult,
)


class TestSearchDocument:
    def test_create_document(self):
        doc = SearchDocument(id="1", content={"title": "Hello"}, index_name="articles")
        assert doc.id == "1"
        assert doc.content == {"title": "Hello"}
        assert doc.index_name == "articles"

    def test_document_with_nested_content(self):
        doc = SearchDocument(
            id="2",
            content={"title": "Test", "tags": ["a", "b"], "meta": {"views": 100}},
            index_name="articles",
        )
        assert doc.content["tags"] == ["a", "b"]
        assert doc.content["meta"]["views"] == 100


class TestSearchQuery:
    def test_defaults(self):
        q = SearchQuery(query="hello")
        assert q.page == 1
        assert q.per_page == 20
        assert q.filters == {}
        assert q.facets == []
        assert q.sort_by is None
        assert q.highlight is True

    def test_custom_pagination(self):
        q = SearchQuery(query="test", page=3, per_page=50)
        assert q.page == 3
        assert q.per_page == 50

    def test_page_validation(self):
        with pytest.raises(Exception):
            SearchQuery(query="test", page=0)

    def test_per_page_max(self):
        with pytest.raises(Exception):
            SearchQuery(query="test", per_page=300)

    def test_filters_and_facets(self):
        q = SearchQuery(
            query="python",
            filters={"category": "tech", "status": "published"},
            facets=["category", "author"],
        )
        assert q.filters["category"] == "tech"
        assert "author" in q.facets


class TestSearchResult:
    def test_defaults(self):
        r = SearchResult(id="1")
        assert r.score == 0.0
        assert r.highlights == {}
        assert r.document == {}

    def test_with_data(self):
        r = SearchResult(
            id="1",
            score=0.95,
            highlights={"title": "<em>Python</em> Guide"},
            document={"title": "Python Guide", "body": "A comprehensive guide."},
        )
        assert r.score == 0.95
        assert "<em>" in r.highlights["title"]


class TestSearchResponse:
    def test_defaults(self):
        resp = SearchResponse()
        assert resp.results == []
        assert resp.total == 0
        assert resp.facets == {}
        assert resp.page == 1

    def test_with_results(self):
        resp = SearchResponse(
            results=[SearchResult(id="1", score=1.0)],
            total=1,
            query_time_ms=5.2,
        )
        assert len(resp.results) == 1
        assert resp.query_time_ms == 5.2


class TestIndexConfig:
    def test_minimal(self):
        cfg = IndexConfig(name="test")
        assert cfg.name == "test"
        assert cfg.searchable_fields == []
        assert cfg.filterable_fields == []

    def test_full(self):
        cfg = IndexConfig(
            name="products",
            searchable_fields=["name", "description"],
            filterable_fields=["category", "price"],
            sortable_fields=["price", "name"],
            ranking_rules=["words", "typo", "proximity"],
        )
        assert "name" in cfg.searchable_fields
        assert "price" in cfg.sortable_fields
        assert len(cfg.ranking_rules) == 3
