"""Tests for task-level comments — store CRUD operations."""

from __future__ import annotations

import pytest

from loom.graph import store
from loom.graph.store import TaskNotFoundError
from loom.graph.task import Task, TaskStatus


@pytest.fixture
async def task(pool, project):
    """Create a test task."""
    t = Task(
        id="loom-comment-test",
        project_id=project,
        title="Comment Test Task",
        status=TaskStatus.PENDING,
    )
    return await store.create_task(pool, t)


@pytest.mark.asyncio
async def test_add_comment(pool, project, task):
    """Can add a comment to a task."""
    result = await store.add_comment(pool, task.id, "agent-1", "This looks good")
    assert result["task_id"] == task.id
    assert result["author"] == "agent-1"
    assert result["body"] == "This looks good"
    assert result["id"].startswith("comment-")
    assert result["created_at"] is not None


@pytest.mark.asyncio
async def test_add_comment_nonexistent_task(pool, project):
    """Adding a comment to a nonexistent task raises TaskNotFoundError."""
    with pytest.raises(TaskNotFoundError):
        await store.add_comment(pool, "loom-nonexistent", "agent-1", "Hello")


@pytest.mark.asyncio
async def test_get_comments_empty(pool, project, task):
    """Getting comments on a task with none returns empty list."""
    result = await store.get_comments(pool, task.id)
    assert result == []


@pytest.mark.asyncio
async def test_get_comments_ordered_newest_first(pool, project, task):
    """Comments are returned newest first."""
    await store.add_comment(pool, task.id, "agent-1", "First")
    await store.add_comment(pool, task.id, "agent-2", "Second")
    await store.add_comment(pool, task.id, "agent-1", "Third")
    result = await store.get_comments(pool, task.id)
    assert len(result) == 3
    assert result[0]["body"] == "Third"
    assert result[1]["body"] == "Second"
    assert result[2]["body"] == "First"


@pytest.mark.asyncio
async def test_get_comments_limit(pool, project, task):
    """Respects the limit parameter."""
    for i in range(5):
        await store.add_comment(pool, task.id, "agent-1", f"Comment {i}")
    result = await store.get_comments(pool, task.id, limit=2)
    assert len(result) == 2


@pytest.mark.asyncio
async def test_comments_scoped_to_task(pool, project):
    """Comments on one task don't appear on another."""
    t1 = Task(id="loom-t1", project_id=project, title="Task 1")
    t2 = Task(id="loom-t2", project_id=project, title="Task 2")
    await store.create_task(pool, t1)
    await store.create_task(pool, t2)
    await store.add_comment(pool, t1.id, "agent-1", "On T1")
    await store.add_comment(pool, t2.id, "agent-2", "On T2")
    r1 = await store.get_comments(pool, t1.id)
    r2 = await store.get_comments(pool, t2.id)
    assert len(r1) == 1
    assert r1[0]["body"] == "On T1"
    assert len(r2) == 1
    assert r2[0]["body"] == "On T2"


@pytest.mark.asyncio
async def test_multiple_authors(pool, project, task):
    """Multiple agents can comment on the same task."""
    await store.add_comment(pool, task.id, "agent-1", "From agent 1")
    await store.add_comment(pool, task.id, "agent-2", "From agent 2")
    result = await store.get_comments(pool, task.id)
    authors = {c["author"] for c in result}
    assert authors == {"agent-1", "agent-2"}
