"""Tests for todo functionality."""

import pytest
import tempfile
from pathlib import Path

from yier_agents.src.todo import Todo, TodoStorage, get_storage, set_storage
from yier_agents.src.tools import TodoWriteTool, TodoReadTool, TodoWriteParams, TodoReadParams
from yier_agents.src.tool import ToolContext


def test_todo_creation():
    """Test Todo model creation."""
    todo = Todo(
        content="Run tests",
        activeForm="Running tests",
        status="pending"
    )
    assert todo.content == "Run tests"
    assert todo.activeForm == "Running tests"
    assert todo.status == "pending"
    assert todo.id is None


def test_todo_with_id():
    """Test Todo with explicit ID."""
    todo = Todo(
        content="Build project",
        activeForm="Building project",
        status="in_progress",
        id="todo_123"
    )
    assert todo.id == "todo_123"


def test_todo_storage_save_and_load():
    """Test TodoStorage save and load."""
    with tempfile.TemporaryDirectory() as tmpdir:
        storage = TodoStorage(storage_dir=tmpdir)

        todos = [
            Todo(content="Task 1", activeForm="Doing task 1", status="pending", id="1"),
            Todo(content="Task 2", activeForm="Doing task 2", status="in_progress", id="2"),
        ]

        # Save
        storage.save("test-session", todos)

        # Load
        loaded = storage.load("test-session")
        assert len(loaded) == 2
        assert loaded[0].content == "Task 1"
        assert loaded[1].status == "in_progress"


def test_todo_storage_load_nonexistent():
    """Test loading todos from non-existent session."""
    with tempfile.TemporaryDirectory() as tmpdir:
        storage = TodoStorage(storage_dir=tmpdir)
        todos = storage.load("nonexistent-session")
        assert todos == []


@pytest.mark.asyncio
async def test_todo_write_tool():
    """Test TodoWrite tool execution."""
    with tempfile.TemporaryDirectory() as tmpdir:
        # Set custom storage
        original_storage = get_storage()
        set_storage(TodoStorage(storage_dir=tmpdir))

        try:
            todos = [
                Todo(content="Task 1", activeForm="Doing task 1", status="pending"),
                Todo(content="Task 2", activeForm="Doing task 2", status="in_progress"),
                Todo(content="Task 3", activeForm="Doing task 3", status="completed"),
            ]

            params = TodoWriteParams(todos=todos)
            ctx = ToolContext(
                session_id="test-session",
                message_id="msg-1",
                call_id="call-1"
            )

            result = await TodoWriteTool.execute(params, ctx)

            assert "Updated todo list" in result.content
            assert result.metadata["total"] == 3
            assert result.metadata["status_counts"]["pending"] == 1
            assert result.metadata["status_counts"]["in_progress"] == 1
            assert result.metadata["status_counts"]["completed"] == 1

            # Verify IDs were auto-generated
            storage = get_storage()
            loaded = storage.load("test-session")
            assert all(todo.id is not None for todo in loaded)

        finally:
            # Restore original storage
            set_storage(original_storage)


@pytest.mark.asyncio
async def test_todo_read_tool_empty():
    """Test TodoRead with no todos."""
    with tempfile.TemporaryDirectory() as tmpdir:
        original_storage = get_storage()
        set_storage(TodoStorage(storage_dir=tmpdir))

        try:
            params = TodoReadParams()
            ctx = ToolContext(
                session_id="empty-session",
                message_id="msg-1",
                call_id="call-1"
            )

            result = await TodoReadTool.execute(params, ctx)

            assert "No todos found" in result.content
            assert result.metadata["total"] == 0

        finally:
            set_storage(original_storage)


@pytest.mark.asyncio
async def test_todo_read_tool_with_todos():
    """Test TodoRead with existing todos."""
    with tempfile.TemporaryDirectory() as tmpdir:
        original_storage = get_storage()
        storage = TodoStorage(storage_dir=tmpdir)
        set_storage(storage)

        try:
            # Save some todos first
            todos = [
                Todo(content="Task 1", activeForm="Doing task 1", status="pending", id="1"),
                Todo(content="Task 2", activeForm="Doing task 2", status="in_progress", id="2"),
                Todo(content="Task 3", activeForm="Doing task 3", status="completed", id="3"),
            ]
            storage.save("test-session", todos)

            # Read todos
            params = TodoReadParams()
            ctx = ToolContext(
                session_id="test-session",
                message_id="msg-1",
                call_id="call-1"
            )

            result = await TodoReadTool.execute(params, ctx)

            assert "Current todo list" in result.content
            assert "Task 1" in result.content
            assert "Doing task 2" in result.content  # Shows activeForm for in_progress
            assert "Task 3" in result.content
            assert "1/3 completed" in result.content or "Summary: 1/3" in result.content
            assert result.metadata["total"] == 3

        finally:
            set_storage(original_storage)


@pytest.mark.asyncio
async def test_todo_write_and_read_integration():
    """Test TodoWrite and TodoRead integration."""
    with tempfile.TemporaryDirectory() as tmpdir:
        original_storage = get_storage()
        set_storage(TodoStorage(storage_dir=tmpdir))

        try:
            # Write todos
            write_params = TodoWriteParams(todos=[
                Todo(content="Setup project", activeForm="Setting up project", status="completed"),
                Todo(content="Write tests", activeForm="Writing tests", status="in_progress"),
                Todo(content="Deploy", activeForm="Deploying", status="pending"),
            ])
            write_ctx = ToolContext(
                session_id="integration-test",
                message_id="msg-1",
                call_id="call-1"
            )

            write_result = await TodoWriteTool.execute(write_params, write_ctx)
            assert "Updated todo list" in write_result.content

            # Read todos
            read_params = TodoReadParams()
            read_ctx = ToolContext(
                session_id="integration-test",
                message_id="msg-2",
                call_id="call-2"
            )

            read_result = await TodoReadTool.execute(read_params, read_ctx)
            assert "Setup project" in read_result.content
            assert "Writing tests" in read_result.content  # activeForm
            assert "Deploy" in read_result.content

        finally:
            set_storage(original_storage)
