"""Task navigation, CRUD, statuses, assignments."""

from cerebro_mcp.connection import execute
from cerebro_mcp.converters import task_to_dict, days_from_2000, status_to_dict


def register(mcp):

    @mcp.tool()
    async def get_projects() -> str:
        """Получить список корневых проектов Cerebro."""
        try:
            raw = await execute("root_tasks")
            projects = [task_to_dict(t) for t in (raw or [])]
            return str(projects)
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def get_task(task_id: str) -> str:
        """Получить полную информацию о задаче по ID."""
        try:
            tid = int(task_id)
            raw = await execute("task", tid)
            if not raw:
                return f"Задача {task_id} не найдена"
            return str(task_to_dict(raw))
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def get_task_children(task_id: str) -> str:
        """Получить дочерние задачи (один уровень вложенности)."""
        try:
            tid = int(task_id)
            raw = await execute("task_children", tid)
            children = [task_to_dict(t) for t in (raw or [])]
            return str(children)
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def get_task_by_path(path: str) -> str:
        """Найти задачу по пути вида '/Проект/Эпизод/Шот'. Возвращает полные данные задачи."""
        try:
            result = await execute("task_by_url", path)
            if not result:
                return f"Задача по пути '{path}' не найдена"
            task_id = result[0] if isinstance(result, (list, tuple)) else result
            raw = await execute("task", task_id)
            if not raw:
                return f"Задача {task_id} не найдена"
            return str(task_to_dict(raw))
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def get_todo_list(user_id: str | None = None, with_done: bool = False) -> str:
        """Получить список задач, назначенных на пользователя. Без user_id — задачи текущего пользователя."""
        try:
            if user_id is None:
                uid = await execute("current_user_id")
            else:
                uid = int(user_id)
            raw = await execute("to_do_task_list", uid, with_done)
            tasks = [task_to_dict(t) for t in (raw or [])]
            return str(tasks)
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def create_task(parent_id: str, name: str, activity_id: str = "0") -> str:
        """Создать новую задачу. Возвращает ID. Запрещённые символы в name: \\ / : ? ' \" | * < > ]
        Для отправки уведомлений после создания вызовите add_definition()."""
        try:
            pid = int(parent_id)
            aid = int(activity_id)
            task_id = await execute("add_task", pid, name, aid)
            return str({"id": str(task_id), "name": name})
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def set_task_status(task_id: str, status_id: str) -> str:
        """Установить статус задачи. Получите допустимые статусы через get_possible_statuses()."""
        try:
            tid = int(task_id)
            sid = int(status_id)
            result = await execute("task_set_status", tid, sid)
            return str({"changed_ids": [str(x) for x in result] if result else []})
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def set_task_allocated(task_id: str, user_id: str) -> str:
        """Назначить пользователя на задачу. Для уведомления в задаче должна быть Definition."""
        try:
            tid = int(task_id)
            uid = int(user_id)
            result = await execute("task_set_allocated", tid, uid)
            return str({"changed_ids": [str(x) for x in result] if result else []})
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def remove_task_allocated(task_id: str, user_id: str) -> str:
        """Снять пользователя с задачи."""
        try:
            tid = int(task_id)
            uid = int(user_id)
            result = await execute("task_remove_allocated", tid, uid)
            return str({"changed_ids": [str(x) for x in result] if result else []})
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def set_task_progress(task_id: str, progress: int) -> str:
        """Установить прогресс задачи (0-100). 100 = Done."""
        try:
            tid = int(task_id)
            if not 0 <= progress <= 100:
                return "Ошибка: progress должен быть от 0 до 100"
            result = await execute("task_set_progress", tid, progress)
            return str({"changed_ids": [str(x) for x in result] if result else []})
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def set_task_priority(task_id: str, priority: int) -> str:
        """Установить приоритет: -2=low, -1=below_normal, 0=normal, 1=above_normal, 2=high, 3=critical."""
        try:
            tid = int(task_id)
            if priority not in (-2, -1, 0, 1, 2, 3):
                return "Ошибка: priority должен быть от -2 до 3"
            result = await execute("task_set_priority", tid, priority)
            return str({"changed_ids": [str(x) for x in result] if result else []})
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def set_task_dates(task_id: str, start: str | None = None, finish: str | None = None) -> str:
        """Установить даты задачи в формате ISO (YYYY-MM-DD). None = сбросить."""
        try:
            tid = int(task_id)
            results = []
            if start is not None:
                days = days_from_2000(start)
                r = await execute("task_set_start", tid, days)
                results.append(("start", [str(x) for x in r] if r else []))
            if finish is not None:
                days = days_from_2000(finish)
                r = await execute("task_set_finish", tid, days)
                results.append(("finish", [str(x) for x in r] if r else []))
            return str(results)
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def set_task_planned_time(task_id: str, hours: float) -> str:
        """Установить запланированное время в часах."""
        try:
            tid = int(task_id)
            result = await execute("task_set_planned_time", tid, hours)
            return str({"changed_ids": [str(x) for x in result] if result else []})
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def set_task_budget(task_id: str, budget: float) -> str:
        """Установить бюджет задачи."""
        try:
            tid = int(task_id)
            result = await execute("task_set_budget", tid, budget)
            return str({"changed_ids": [str(x) for x in result] if result else []})
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def set_task_name(task_id: str, name: str) -> str:
        """Переименовать задачу. Запрещённые символы: \\ / # : ? & ' \" , + |"""
        try:
            tid = int(task_id)
            result = await execute("task_set_name", tid, name)
            if isinstance(result, (set, list)):
                return str({"changed_ids": [str(x) for x in result]})
            return str({"changed_ids": [str(result)] if result else []})
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def link_tasks(first_id: str, second_id: str) -> str:
        """Создать связь-последовательность между задачами: first → second."""
        try:
            fid = int(first_id)
            sid = int(second_id)
            link_id = await execute("set_link_tasks", fid, sid)
            return str({"link_id": str(link_id)})
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def get_task_links(task_id: str) -> str:
        """Получить связи задачи с другими задачами."""
        try:
            tid = int(task_id)
            raw = await execute("task_links", tid)
            links = []
            for l in (raw or []):
                links.append({
                    "id": str(l[1]),
                    "deleted": l[2] == False,
                    "src": str(l[3]),
                    "dst": str(l[4]),
                    "flags": l[5],
                })
            return str(links)
        except Exception as e:
            return f"Ошибка: {e}"

    @mcp.tool()
    async def get_possible_statuses(task_id: str) -> str:
        """Получить допустимые статусы для задачи (зависит от прав и текущего статуса)."""
        try:
            tid = int(task_id)
            raw = await execute("task_possible_statuses", tid)
            statuses = [status_to_dict(s) for s in (raw or [])]
            return str(statuses)
        except Exception as e:
            return f"Ошибка: {e}"
