from __future__ import annotations

import asyncio
from pathlib import Path

import pytest

from aicd.db.store import TaskStore
from aicd.tasks.main_inbox import main_inbox_id
from aicd.tasks.safe_ids import is_safe_task_id, validate_topic_slug


def test_task_messages_roundtrip(tmp_path: Path) -> None:
    async def _go() -> None:
        db = tmp_path / "t.db"
        store = TaskStore(db)
        conn = await store.connect()
        tid = await store.insert_task(
            conn,
            task_type="ai_agent",
            status="pending",
            parent_id=None,
            payload={"instruction": "x"},
        )
        mid = await store.insert_task_message(
            conn,
            to_task_id=tid,
            from_task_id="parent-1",
            kind="status",
            body={"pct": 50},
            thread_root_id="thr1",
        )
        rows = await store.list_task_messages(conn, to_task_id=tid, since_id=0, limit=10)
        assert len(rows) == 1
        assert rows[0].id == mid
        assert rows[0].kind == "status"
        assert rows[0].body == {"pct": 50}
        await store.mark_task_messages_read(conn, [mid])
        rows2 = await store.list_task_messages(conn, to_task_id=tid, since_id=0, limit=10)
        assert rows2[0].read_at is not None

    asyncio.run(_go())


def test_topic_slug_validation() -> None:
    assert validate_topic_slug(None) is None
    assert validate_topic_slug("My-Topic_2") == "my-topic_2"
    with pytest.raises(ValueError):
        validate_topic_slug("Bad/Slash")
    with pytest.raises(ValueError):
        validate_topic_slug("../x")


def test_safe_task_id() -> None:
    assert is_safe_task_id("abc-def_12")
    assert not is_safe_task_id("../x")
    assert not is_safe_task_id("")


def test_main_inbox_and_session_thread_tasks(tmp_path: Path) -> None:
    async def _go() -> None:
        db = tmp_path / "t.db"
        store = TaskStore(db)
        conn = await store.connect()
        sess = "chat-session-abc"
        tid = await store.insert_task(
            conn,
            task_type="ai_agent",
            status="completed",
            parent_id=None,
            payload={"thread_root_id": sess, "display_title": "Job"},
        )
        listed = await store.list_top_level_tasks_for_session_thread(
            conn, sess, limit=10
        )
        assert len(listed) == 1
        assert listed[0].id == tid
        inbox = main_inbox_id(sess)
        mid = await store.insert_task_message(
            conn,
            to_task_id=inbox,
            from_task_id=tid,
            kind="lifecycle",
            body={"phase": "completed", "child_task_id": tid},
            thread_root_id=sess,
        )
        rows = await store.list_task_messages(
            conn, to_task_id=inbox, since_id=0, limit=10
        )
        assert len(rows) == 1
        assert rows[0].id == mid
        assert rows[0].kind == "lifecycle"

    asyncio.run(_go())
