"""Tests for src/webui/data.py data access functions."""

from __future__ import annotations

import sys
from functools import wraps
from pathlib import Path

import pytest

# Ensure webui is importable
_project_root = Path(__file__).resolve().parent.parent
if str(_project_root / "src") not in sys.path:
    sys.path.insert(0, str(_project_root / "src"))

from webui.data import (
    get_overview_stats,
    get_category_counts,
    get_drafts_page,
    get_draft_detail,
    get_ideas_by_type,
    get_all_gaps,
    get_timeline_data,
    get_top_authors,
)


def _skip_on_missing_module(fn):
    """Decorator that skips tests when webui.data references unavailable modules."""
    @wraps(fn)
    def wrapper(*args, **kwargs):
        try:
            return fn(*args, **kwargs)
        except (ModuleNotFoundError, AttributeError) as e:
            pytest.skip(f"webui.data depends on module not in this worktree: {e}")
    return wrapper


def test_get_overview_stats(seeded_db):
    """Overview stats should return correct counts from seeded data."""
    stats = get_overview_stats(seeded_db)
    assert stats["total_drafts"] == 5
    assert stats["rated_count"] == 5
    assert stats["author_count"] == 3
    # 2 + 1 + 1 = 4 ideas in seeded data
    assert stats["idea_count"] == 4
    assert stats["gap_count"] == 0
    assert "input_tokens" in stats
    assert "output_tokens" in stats


def test_get_category_counts(seeded_db):
    """Category counts should reflect the seeded ratings."""
    counts = get_category_counts(seeded_db)
    assert isinstance(counts, dict)
    assert "A2A protocols" in counts
    assert counts["A2A protocols"] == 1
    assert "ML traffic mgmt" in counts


@_skip_on_missing_module
def test_get_drafts_page_basic(seeded_db):
    """Drafts page should return paginated results."""
    result = get_drafts_page(seeded_db, page=1, per_page=3)
    assert len(result["drafts"]) == 3
    assert result["total"] == 5
    assert result["page"] == 1
    assert result["per_page"] == 3
    assert result["pages"] == 2


@_skip_on_missing_module
def test_get_drafts_page_with_category_filter(seeded_db):
    """Filtering by category should narrow results."""
    result = get_drafts_page(seeded_db, category="A2A protocols")
    assert result["total"] == 1
    assert result["drafts"][0]["categories"] == ["A2A protocols"]


@_skip_on_missing_module
def test_get_drafts_page_with_search_filter(seeded_db):
    """Text search should filter by name/title/summary."""
    result = get_drafts_page(seeded_db, search="alpha")
    assert result["total"] == 1
    assert "alpha" in result["drafts"][0]["name"]


@_skip_on_missing_module
def test_get_drafts_page_empty_search(seeded_db):
    """Search for non-matching term should return 0 results."""
    result = get_drafts_page(seeded_db, search="zzzznonexistent")
    assert result["total"] == 0
    assert result["drafts"] == []


@_skip_on_missing_module
def test_get_draft_detail(seeded_db):
    """Draft detail should include draft, rating, authors, ideas, refs."""
    detail = get_draft_detail(seeded_db, "draft-alpha-agent-comm")
    assert detail is not None
    assert detail["name"] == "draft-alpha-agent-comm"
    assert detail["title"] == "Alpha Agent Communication"
    assert "rating" in detail
    assert detail["rating"]["novelty"] == 4
    assert len(detail["authors"]) == 2
    assert len(detail["ideas"]) == 2
    assert len(detail["refs"]) == 3


@_skip_on_missing_module
def test_get_draft_detail_not_found(seeded_db):
    """Draft detail for non-existent draft should return None."""
    assert get_draft_detail(seeded_db, "draft-nonexistent") is None


def test_get_ideas_by_type(seeded_db):
    """Ideas by type should group and count correctly."""
    result = get_ideas_by_type(seeded_db)
    assert result["total"] == 4
    assert "by_type" in result
    assert isinstance(result["by_type"], dict)
    # We have protocol, mechanism, extension types
    assert "protocol" in result["by_type"] or "mechanism" in result["by_type"]


def test_get_all_gaps_empty(seeded_db):
    """With no gaps inserted, should return empty list."""
    gaps = get_all_gaps(seeded_db)
    assert gaps == []


def test_get_all_gaps_with_data(seeded_db):
    """After inserting gaps, should return them."""
    seeded_db.insert_gaps([
        {"topic": "Gap A", "description": "Desc A", "severity": "high", "evidence": "Ev A"},
    ])
    gaps = get_all_gaps(seeded_db)
    assert len(gaps) == 1
    assert gaps[0]["topic"] == "Gap A"


def test_get_timeline_data(seeded_db):
    """Timeline data should group drafts by month."""
    data = get_timeline_data(seeded_db)
    assert "months" in data
    assert "series" in data
    assert "categories" in data
    # Seeded drafts span Jan-May 2025
    assert len(data["months"]) >= 1


def test_get_top_authors(seeded_db):
    """Top authors should return ranked list with draft counts."""
    authors = get_top_authors(seeded_db, limit=10)
    assert len(authors) >= 1
    assert "name" in authors[0]
    assert "draft_count" in authors[0]
    assert authors[0]["draft_count"] >= 2
