# Copyright (c) 2025 Patrick Motsch
# All rights reserved.

import base64
import json
import logging
from typing import Any, Dict

from modules.datamodels.datamodelChat import ActionDocument, ActionResult
from ..helpers.pathparse import parse_task_id

logger = logging.getLogger(__name__)


async def upload_attachment(self, parameters: Dict[str, Any]) -> ActionResult:
    connection_reference = parameters.get("connectionReference")
    task_id = (parameters.get("taskId") or "").strip()
    path_hint = (parameters.get("path") or "").strip()
    if not connection_reference:
        return ActionResult.isFailure(error="connectionReference is required")
    if not task_id and path_hint:
        task_id = parse_task_id(path_hint) or ""
    if not task_id:
        return ActionResult.isFailure(error="taskId is required")

    conn = self.connection.get_clickup_connection(connection_reference)
    if not conn:
        return ActionResult.isFailure(error="No valid ClickUp connection")

    content_param = parameters.get("content")
    if not content_param:
        return ActionResult.isFailure(error="content is required (connect a file node upstream)")

    content = content_param[0] if isinstance(content_param, (list, tuple)) and content_param else content_param
    file_name = parameters.get("fileName")
    file_bytes = None

    if isinstance(content, dict):
        file_name = file_name or content.get("documentName") or content.get("fileName") or "attachment"
        raw_data = content.get("documentData")
        if (content.get("validationMetadata") or {}).get("fileId") and not raw_data:
            fid = content["validationMetadata"]["fileId"]
            try:
                raw = self.services.chat.getFileData(fid)
                file_bytes = raw if isinstance(raw, bytes) else str(raw).encode("utf-8")
            except Exception as e:
                return ActionResult.isFailure(error=f"Could not load file {fid}: {e}")
        elif raw_data is not None:
            if isinstance(raw_data, bytes):
                file_bytes = raw_data
            elif isinstance(raw_data, str):
                try:
                    file_bytes = base64.b64decode(raw_data)
                except Exception:
                    file_bytes = raw_data.encode("utf-8")
            else:
                return ActionResult.isFailure(error="Unsupported documentData type")
        else:
            return ActionResult.isFailure(error="Could not read file bytes from content")
    elif hasattr(content, "documentData"):
        file_name = file_name or getattr(content, "documentName", None) or getattr(content, "fileName", None) or "attachment"
        raw_data = content.documentData
        if isinstance(raw_data, bytes):
            file_bytes = raw_data
        elif isinstance(raw_data, str):
            try:
                file_bytes = base64.b64decode(raw_data)
            except Exception:
                file_bytes = raw_data.encode("utf-8")
        else:
            return ActionResult.isFailure(error="Unsupported documentData on ActionDocument")
    else:
        return ActionResult.isFailure(error="Unsupported content format")

    if not file_bytes:
        return ActionResult.isFailure(error="Empty file content")

    data = await self.services.clickup.uploadTaskAttachment(task_id, file_bytes, file_name or "file")
    if isinstance(data, dict) and data.get("error"):
        return ActionResult.isFailure(error=str(data.get("error")) + (data.get("body") or ""))

    doc = ActionDocument(
        documentName="clickup_upload_attachment.json",
        documentData=json.dumps(data, ensure_ascii=False, indent=2),
        mimeType="application/json",
        validationMetadata={"actionType": "clickup.uploadAttachment", "taskId": task_id},
    )
    return ActionResult.isSuccess(documents=[doc])
