import json
from typing import Optional, Type

from pydantic import BaseModel, Field

from app.agent.tools.base import MoviePilotTool
from app.agent.tools.tags import ToolTag
from app.core.config import settings
from app.db.agenttask_oper import AgentTaskOper


class QueryAgentTasksInput(BaseModel):
    """查询 Agent 自主定时任务的输入参数。"""

    task_id: Optional[int] = Field(
        None,
        ge=1,
        description="Optional task ID. Omit it to list tasks owned by the current user.",
    )
    enabled: Optional[bool] = Field(
        None,
        description="Optional enabled-state filter used when listing tasks.",
    )


class QueryAgentTasksTool(MoviePilotTool):
    """查询当前用户创建的 Agent 自主定时任务。"""

    name: str = "query_agent_tasks"
    tags: list[str] = [ToolTag.Read, ToolTag.Scheduler, ToolTag.Admin]
    description: str = (
        "Query persistent autonomous agent tasks, including their task content, exact "
        "date or cron trigger, enabled state, next run time, and latest execution result."
    )
    args_schema: Type[BaseModel] = QueryAgentTasksInput
    require_admin: bool = True

    def get_tool_message(self, **kwargs: object) -> Optional[str]:
        """生成查询定时任务的提示消息。"""
        task_id = kwargs.get("task_id")
        return f"查询自主定时任务：{task_id}" if task_id else "查询自主定时任务"

    def _query_tasks(
            self,
            task_id: Optional[int],
            enabled: Optional[bool],
    ) -> list[dict]:
        """读取当前用户的任务及运行时下一次触发时间。"""
        from app.scheduler import Scheduler

        oper = AgentTaskOper()
        if task_id:
            task = oper.get(task_id=task_id, user_id=str(self._user_id))
            tasks = [task] if task else []
        else:
            tasks = oper.list(user_id=str(self._user_id), enabled=enabled)
        scheduler = Scheduler()
        result = []
        for task in tasks:
            data = oper.to_dict(
                task,
                next_run_at=scheduler.get_agent_task_next_run(task.id),
                timezone=settings.TZ,
            )
            result.append(data)
        return result

    async def run(
            self,
            task_id: Optional[int] = None,
            enabled: Optional[bool] = None,
            **kwargs: object,
    ) -> str:
        """查询 Agent 自主定时任务。"""
        payload = QueryAgentTasksInput(task_id=task_id, enabled=enabled)
        tasks = await self.run_blocking(
            "db",
            self._query_tasks,
            payload.task_id,
            payload.enabled,
        )
        return json.dumps(
            {"total": len(tasks), "tasks": tasks},
            ensure_ascii=False,
            indent=2,
        )
