"""API client methods for tasks."""

from __future__ import annotations

from typing import Any

from peon_mcp.common.base_client import BaseAPIClient


class TaskClient(BaseAPIClient):
    """Task API client methods."""

    async def create_task(
        self,
        project_id: str,
        title: str,
        description: str = "",
        priority: str = "medium",
        status: str = "todo",
        commit_base: str = "",
        commit_head: str = "",
        branch: str = "",
        worktree_path: str = "",
        pr_url: str = "",
        feature_id: int | None = None,
        depends_on: list[int] | None = None,
    ) -> dict | str:
        body: dict[str, Any] = {
            "title": title,
            "description": description,
            "priority": priority,
            "status": status,
            "commit_base": commit_base,
            "commit_head": commit_head,
            "branch": branch,
            "worktree_path": worktree_path,
            "pr_url": pr_url,
        }
        if feature_id is not None:
            body["feature_id"] = feature_id
        if depends_on is not None:
            body["depends_on"] = depends_on
        return await self._request(
            "POST", f"/api/projects/{project_id}/tasks", json=body
        )

    async def list_tasks(
        self,
        project_id: str,
        priority: str | None = None,
        status: str | None = None,
        feature_id: int | None = None,
        sort: str | None = None,
    ) -> list[dict] | str:
        params: dict[str, Any] = {}
        if priority is not None:
            params["priority"] = priority
        if status is not None:
            params["status"] = status
        if feature_id is not None:
            params["feature_id"] = feature_id
        if sort is not None:
            params["sort"] = sort
        return await self._paginate_all(
            f"/api/projects/{project_id}/tasks", params=params
        )

    async def get_task(self, task_id: int) -> dict | str:
        return await self._request("GET", f"/api/tasks/{task_id}")

    async def next_task(
        self,
        project_id: str = "",
        commit_base: str = "",
        feature_id: int | None = None,
        host: str = "",
    ) -> dict | str:
        body: dict[str, Any] = {
            "project_id": project_id,
            "commit_base": commit_base,
            "host": host,
        }
        if feature_id is not None:
            body["feature_id"] = feature_id
        return await self._request("POST", "/api/next-task", json=body)

    async def update_task(
        self,
        task_id: int,
        title: str | None = None,
        description: str | None = None,
        priority: str | None = None,
        status: str | None = None,
        commit_base: str | None = None,
        commit_head: str | None = None,
        branch: str | None = None,
        worktree_path: str | None = None,
        pr_url: str | None = None,
        feature_id: int | None = None,
        lines_added: int | None = None,
        lines_deleted: int | None = None,
        tokens_used: int | None = None,
    ) -> dict | str:
        body: dict[str, Any] = {}
        if title is not None:
            body["title"] = title
        if description is not None:
            body["description"] = description
        if priority is not None:
            body["priority"] = priority
        if status is not None:
            body["status"] = status
        if commit_base is not None:
            body["commit_base"] = commit_base
        if commit_head is not None:
            body["commit_head"] = commit_head
        if branch is not None:
            body["branch"] = branch
        if worktree_path is not None:
            body["worktree_path"] = worktree_path
        if pr_url is not None:
            body["pr_url"] = pr_url
        if feature_id is not None:
            body["feature_id"] = feature_id
        if lines_added is not None:
            body["lines_added"] = lines_added
        if lines_deleted is not None:
            body["lines_deleted"] = lines_deleted
        if tokens_used is not None:
            body["tokens_used"] = tokens_used
        return await self._request("PUT", f"/api/tasks/{task_id}", json=body)

    async def delete_task(self, task_id: int) -> str:
        result = await self._request("DELETE", f"/api/tasks/{task_id}")
        if isinstance(result, dict) and result.get("ok"):
            return f"Task {task_id} deleted"
        if isinstance(result, str):
            return result
        return f"Task {task_id} deleted"

    async def find_recoverable_tasks(
        self, project_id: str, max_age_hours: int = 24
    ) -> list[dict] | str:
        return await self._request(
            "GET", f"/api/projects/{project_id}/tasks/recoverable",
            params={"max_age_hours": max_age_hours},
        )

    async def update_task_progress(
        self, task_id: int, progress: float
    ) -> dict | str:
        return await self._request(
            "PUT", f"/api/tasks/{task_id}/progress",
            json={"progress": progress},
        )

    async def bulk_update_task_status(
        self, task_ids: list[int], status: str
    ) -> dict | str:
        return await self._request(
            "PUT", "/api/tasks/bulk-update",
            json={"task_ids": task_ids, "status": status},
        )

    async def add_task_dependency(
        self, task_id: int, depends_on_task_id: int
    ) -> dict | str:
        return await self._request(
            "POST", f"/api/tasks/{task_id}/dependencies",
            json={"depends_on_task_id": depends_on_task_id},
        )

    async def remove_task_dependency(
        self, task_id: int, depends_on_task_id: int
    ) -> str:
        result = await self._request(
            "DELETE", f"/api/tasks/{task_id}/dependencies/{depends_on_task_id}",
        )
        if isinstance(result, dict) and result.get("ok"):
            return f"Dependency {task_id} -> {depends_on_task_id} removed"
        if isinstance(result, str):
            return result
        return f"Dependency {task_id} -> {depends_on_task_id} removed"

    async def list_task_dependencies(self, task_id: int) -> dict | str:
        return await self._request("GET", f"/api/tasks/{task_id}/dependencies")
