# -*- coding: utf-8 -*-
"""The creating task tool class."""
from typing import Any

from pydantic import BaseModel, Field

from ._task_tool_base import _TaskToolBase
from .._response import ToolChunk
from ...state import AgentState, Task
from ...exception import DeveloperOrientedException
from ...message import TextBlock, ToolResultState


class _TaskCreateParams(BaseModel):
    """The params of the creating task tool."""

    subject: str = Field(description="A brief title for the task")
    description: str = Field(description="What needs to be done")
    metadata: dict[str, Any] | None = Field(
        default=None,
        description="Arbitrary metadata to attach to the task",
    )


class TaskCreate(_TaskToolBase):
    """Create a task for the agent to perform."""

    name: str = "TaskCreate"

    description: str = """Use this tool to create a structured task list for \
your current session. This helps you track progress, organize complex tasks, \
and demonstrate thoroughness to the user.
It also helps the user understand the progress of the task and overall \
progress of their requests.

## When to Use This Tool
Use this tool proactively in these scenarios:

- Complex multi-step tasks - When a task requires 3 or more distinct steps \
or actions
- Non-trivial and complex tasks - Tasks that require careful planning or \
multiple operations
- Plan mode - When using plan mode, create a task list to track the work
- User explicitly requests todo list - When the user directly asks you to \
use the todo list
- User provides multiple tasks - When users provide a list of things to be \
done (numbered or comma-separated)
- After receiving new instructions - Immediately capture user requirements \
as tasks
- When you start working on a task - Mark it as in_progress BEFORE \
beginning work
- After completing a task - Mark it as completed and add any new follow-up \
tasks discovered during implementation

## When NOT to Use This Tool

Skip using this tool when:
- There is only **one single, straightforward** task
- The task is trivial and tracking it provides no organizational benefit
- The task can be completed in less than 3 trivial steps
- The task is purely conversational or informational

NOTE that you should **NOT** use this tool if there is only one trivial task \
to do. In this case you are better off just doing the task directly.

## Task Fields

- **subject**: A brief, actionable title in imperative form (e.g., \
"Fix authentication bug in login flow")
- **description**: What needs to be done

All tasks are created with status `pending`.

## Tips

- Create tasks with clear, specific subjects that describe the outcome
- After creating tasks, use TaskUpdate to set up dependencies \
(blocks/blockedBy) if needed
- Check TaskList first to avoid creating duplicate tasks"""

    input_schema: dict = _TaskCreateParams.model_json_schema()

    async def call(
        self,
        _agent_state: AgentState,
        subject: str,
        description: str,
        metadata: dict[str, Any] | None = None,
    ) -> ToolChunk:
        """Create the subtask and add it into the agent state."""
        if not isinstance(_agent_state, AgentState):
            # Expose error to the developer
            raise DeveloperOrientedException(
                f"Error: TaskCreate requires AgentState to be provided, got "
                f"{_agent_state} instead.",
            )

        try:
            # Derive the next sequential id from existing tasks.
            # Existing ids that look numeric are considered; any
            # non-numeric ids (e.g. legacy UUIDs) are ignored.
            max_numeric = 0
            for t in _agent_state.tasks_context.tasks:
                try:
                    max_numeric = max(max_numeric, int(t.id))
                except (ValueError, TypeError):
                    pass
            next_id = str(max_numeric + 1)

            task = Task(
                id=next_id,
                subject=subject,
                description=description,
                metadata=metadata or {},
            )
            _agent_state.tasks_context.tasks.append(task)

            return ToolChunk(
                content=[
                    TextBlock(
                        text=f"Task (id={next_id}) created successfully: "
                        f"{task.subject}",
                    ),
                ],
            )
        except Exception as e:
            return ToolChunk(
                content=[
                    TextBlock(text=f"CreateTaskError: {e}"),
                ],
                state=ToolResultState.ERROR,
            )
