# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""ClickUp workflow method — list/search/get/create/update tasks and upload attachments."""

import logging

from modules.datamodels.datamodelWorkflowActions import WorkflowActionDefinition, WorkflowActionParameter
from modules.shared.frontendTypes import FrontendType
from modules.workflows.methods.methodBase import MethodBase

from .helpers.connection import ClickupConnectionHelper
from .actions.list_tasks import list_tasks
from .actions.list_fields import list_fields
from .actions.search_tasks import search_tasks
from .actions.get_task import get_task
from .actions.create_task import create_task
from .actions.update_task import update_task
from .actions.upload_attachment import upload_attachment

logger = logging.getLogger(__name__)


class MethodClickup(MethodBase):
    """ClickUp API actions for automation2 (lists as tables)."""

    def __init__(self, services):
        super().__init__(services)
        self.name = "clickup"
        self.description = "ClickUp task and list operations"
        self.connection = ClickupConnectionHelper(self)

        self._actions = {
            "listTasks": WorkflowActionDefinition(
                actionId="clickup.listTasks",
                description="List tasks in a ClickUp list (virtual path /team/{id}/list/{id})",
                dynamicMode=True,
                parameters={
                    "connectionReference": WorkflowActionParameter(
                        name="connectionReference",
                        type="str",
                        frontendType=FrontendType.USER_CONNECTION,
                        required=True,
                        description="ClickUp connection",
                    ),
                    "pathQuery": WorkflowActionParameter(
                        name="pathQuery",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=True,
                        description="Virtual path to list: /team/{teamId}/list/{listId}",
                    ),
                    "page": WorkflowActionParameter(
                        name="page",
                        type="int",
                        frontendType=FrontendType.NUMBER,
                        required=False,
                        default=0,
                        description="Page index",
                    ),
                    "includeClosed": WorkflowActionParameter(
                        name="includeClosed",
                        type="bool",
                        frontendType=FrontendType.CHECKBOX,
                        required=False,
                        default=False,
                        description="Include closed tasks",
                    ),
                },
                execute=list_tasks.__get__(self, self.__class__),
            ),
            "listFields": WorkflowActionDefinition(
                actionId="clickup.listFields",
                description="List custom and built-in field definitions for a ClickUp list (names, types, ids)",
                dynamicMode=True,
                parameters={
                    "connectionReference": WorkflowActionParameter(
                        name="connectionReference",
                        type="str",
                        frontendType=FrontendType.USER_CONNECTION,
                        required=True,
                        description="ClickUp connection",
                    ),
                    "listId": WorkflowActionParameter(
                        name="listId",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="ClickUp list ID (if set, pathQuery is optional)",
                    ),
                    "pathQuery": WorkflowActionParameter(
                        name="pathQuery",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Virtual path /team/{teamId}/list/{listId} (same as data source path)",
                    ),
                },
                execute=list_fields.__get__(self, self.__class__),
            ),
            "searchTasks": WorkflowActionDefinition(
                actionId="clickup.searchTasks",
                description="Search tasks in a ClickUp workspace (team)",
                dynamicMode=True,
                parameters={
                    "connectionReference": WorkflowActionParameter(
                        name="connectionReference",
                        type="str",
                        frontendType=FrontendType.USER_CONNECTION,
                        required=True,
                        description="ClickUp connection",
                    ),
                    "teamId": WorkflowActionParameter(
                        name="teamId",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=True,
                        description="Workspace (team) ID",
                    ),
                    "query": WorkflowActionParameter(
                        name="query",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=True,
                        description="Search query",
                    ),
                    "page": WorkflowActionParameter(
                        name="page",
                        type="int",
                        frontendType=FrontendType.NUMBER,
                        required=False,
                        default=0,
                        description="Page index",
                    ),
                    "listId": WorkflowActionParameter(
                        name="listId",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description=(
                            "If set, tasks are loaded from this list via the list API (not team search). "
                            "Use this to search the selected table."
                        ),
                    ),
                    "includeClosed": WorkflowActionParameter(
                        name="includeClosed",
                        type="bool",
                        frontendType=FrontendType.CHECKBOX,
                        required=False,
                        default=False,
                        description="When listId is set, include closed tasks in list pages.",
                    ),
                    "fullTaskData": WorkflowActionParameter(
                        name="fullTaskData",
                        type="bool",
                        frontendType=FrontendType.CHECKBOX,
                        required=False,
                        default=False,
                        description="If true, return raw ClickUp API task objects (large). Default is a slim payload.",
                    ),
                    "matchNameOnly": WorkflowActionParameter(
                        name="matchNameOnly",
                        type="bool",
                        frontendType=FrontendType.CHECKBOX,
                        required=False,
                        default=True,
                        description="If true, keep only tasks whose title contains the search query (default: true).",
                    ),
                },
                execute=search_tasks.__get__(self, self.__class__),
            ),
            "getTask": WorkflowActionDefinition(
                actionId="clickup.getTask",
                description="Get a single task by ID",
                dynamicMode=True,
                parameters={
                    "connectionReference": WorkflowActionParameter(
                        name="connectionReference",
                        type="str",
                        frontendType=FrontendType.USER_CONNECTION,
                        required=True,
                        description="ClickUp connection",
                    ),
                    "taskId": WorkflowActionParameter(
                        name="taskId",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Task ID",
                    ),
                    "pathQuery": WorkflowActionParameter(
                        name="pathQuery",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Optional virtual path ending in /task/{taskId}",
                    ),
                },
                execute=get_task.__get__(self, self.__class__),
            ),
            "createTask": WorkflowActionDefinition(
                actionId="clickup.createTask",
                description="Create a task in a list",
                dynamicMode=True,
                parameters={
                    "connectionReference": WorkflowActionParameter(
                        name="connectionReference",
                        type="str",
                        frontendType=FrontendType.USER_CONNECTION,
                        required=True,
                        description="ClickUp connection",
                    ),
                    "listId": WorkflowActionParameter(
                        name="listId",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="List ID (if not using path)",
                    ),
                    "pathQuery": WorkflowActionParameter(
                        name="pathQuery",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Virtual path to list /team/{teamId}/list/{listId}",
                    ),
                    "name": WorkflowActionParameter(
                        name="name",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=True,
                        description="Task name",
                    ),
                    "description": WorkflowActionParameter(
                        name="description",
                        type="str",
                        frontendType=FrontendType.TEXTAREA,
                        required=False,
                        description="Task description",
                    ),
                    "customFieldValues": WorkflowActionParameter(
                        name="customFieldValues",
                        type="str",
                        frontendType=FrontendType.TEXTAREA,
                        required=False,
                        description="Map of ClickUp custom field id to value (merged into custom_fields).",
                    ),
                    "taskFields": WorkflowActionParameter(
                        name="taskFields",
                        type="str",
                        frontendType=FrontendType.TEXTAREA,
                        required=False,
                        description="Optional extra JSON object merged into create payload (overrides standard fields)",
                    ),
                    "taskStatus": WorkflowActionParameter(
                        name="taskStatus",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="ClickUp status name for this list",
                    ),
                    "taskPriority": WorkflowActionParameter(
                        name="taskPriority",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Priority 1 (urgent)–4 (low), empty to omit",
                    ),
                    "taskDueDateMs": WorkflowActionParameter(
                        name="taskDueDateMs",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Due date as Unix ms timestamp",
                    ),
                    "taskAssigneeIds": WorkflowActionParameter(
                        name="taskAssigneeIds",
                        type="str",
                        frontendType=FrontendType.TEXTAREA,
                        required=False,
                        description="JSON array of ClickUp user ids, e.g. [123,456]",
                    ),
                    "taskTimeEstimateMs": WorkflowActionParameter(
                        name="taskTimeEstimateMs",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Time estimate in milliseconds",
                    ),
                    "taskTimeEstimateHours": WorkflowActionParameter(
                        name="taskTimeEstimateHours",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Time estimate in hours (converted to ms; preferred over taskTimeEstimateMs)",
                    ),
                },
                execute=create_task.__get__(self, self.__class__),
            ),
            "updateTask": WorkflowActionDefinition(
                actionId="clickup.updateTask",
                description="Update a task (JSON body per ClickUp API)",
                dynamicMode=True,
                parameters={
                    "connectionReference": WorkflowActionParameter(
                        name="connectionReference",
                        type="str",
                        frontendType=FrontendType.USER_CONNECTION,
                        required=True,
                        description="ClickUp connection",
                    ),
                    "taskId": WorkflowActionParameter(
                        name="taskId",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Task ID",
                    ),
                    "path": WorkflowActionParameter(
                        name="path",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Optional path ending in /task/{taskId}",
                    ),
                    "taskUpdate": WorkflowActionParameter(
                        name="taskUpdate",
                        type="str",
                        frontendType=FrontendType.TEXTAREA,
                        required=False,
                        description="JSON object for PUT /task/{id} (e.g. {\"name\":\"...\",\"status\":\"...\"}); built from editor rows if empty",
                    ),
                },
                execute=update_task.__get__(self, self.__class__),
            ),
            "uploadAttachment": WorkflowActionDefinition(
                actionId="clickup.uploadAttachment",
                description="Upload a file attachment to a task",
                dynamicMode=True,
                parameters={
                    "connectionReference": WorkflowActionParameter(
                        name="connectionReference",
                        type="str",
                        frontendType=FrontendType.USER_CONNECTION,
                        required=True,
                        description="ClickUp connection",
                    ),
                    "taskId": WorkflowActionParameter(
                        name="taskId",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Task ID",
                    ),
                    "path": WorkflowActionParameter(
                        name="path",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Optional path ending in /task/{taskId}",
                    ),
                    "fileName": WorkflowActionParameter(
                        name="fileName",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Attachment file name",
                    ),
                    "content": WorkflowActionParameter(
                        name="content",
                        type="Any",
                        frontendType=FrontendType.DOCUMENT_REFERENCE,
                        required=True,
                        description="File from upstream node",
                    ),
                },
                execute=upload_attachment.__get__(self, self.__class__),
            ),
        }
        self._validateActions()
