"""Files API client for V3 (multipart upload)."""

from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from concentriq.client import ConcentriqClient


class Files:
    """Client for file upload operations (/api/v3/files).

    Handles S3 multipart upload flow: create upload, get presigned URLs
    for each part, and complete/abort the upload.
    """

    def __init__(self, client: "ConcentriqClient"):
        self._client = client
        self._base_path = "/api/v3/files"

    def create_multipart_upload(
        self,
        resource_type: str,
        resource_id: int,
        storage_key: str,
    ) -> dict[str, Any]:
        """Initiate a multipart upload to S3.

        Args:
            resource_type: Resource type ("Image" or "Attachment")
            resource_id: ID of the resource
            storage_key: S3 storage key for the file

        Returns:
            Dict with Bucket, Key, and UploadId
        """
        response = self._client._request(
            "POST",
            f"{self._base_path}/upload/create",
            params={
                "resourceType": resource_type,
                "resourceId": resource_id,
                "storageKey": storage_key,
            },
        )
        return response.json()

    def get_part_upload_url(
        self,
        resource_type: str,
        resource_id: int,
        storage_key: str,
        upload_id: str,
        part_number: int,
    ) -> str:
        """Get a presigned S3 URL for uploading a single part.

        Args:
            resource_type: Resource type ("Image" or "Attachment")
            resource_id: ID of the resource
            storage_key: S3 storage key
            upload_id: The UploadId from create_multipart_upload
            part_number: Part number (1-indexed)

        Returns:
            Presigned S3 URL for PUT
        """
        response = self._client._request(
            "GET",
            f"{self._base_path}/upload/multi-part/url",
            params={
                "resourceType": resource_type,
                "resourceId": resource_id,
                "storageKey": storage_key,
                "UploadId": upload_id,
                "PartNumber": part_number,
            },
        )
        return response.json()["url"]

    def complete_multipart_upload(
        self,
        resource_type: str,
        resource_id: int,
        storage_key: str,
        upload_id: str,
        parts: list[dict[str, Any]],
    ) -> None:
        """Complete a multipart upload.

        Args:
            resource_type: Resource type ("Image" or "Attachment")
            resource_id: ID of the resource
            storage_key: S3 storage key
            upload_id: The UploadId from create_multipart_upload
            parts: List of {"PartNumber": int, "ETag": str} dicts
        """
        self._client._request(
            "POST",
            f"{self._base_path}/upload/multi-part/complete",
            params={
                "resourceType": resource_type,
                "resourceId": resource_id,
                "storageKey": storage_key,
                "UploadId": upload_id,
            },
            json={"Parts": parts},
        )

    def abort_multipart_upload(
        self,
        resource_type: str,
        resource_id: int,
        storage_key: str,
        upload_id: str,
    ) -> None:
        """Abort a multipart upload.

        Args:
            resource_type: Resource type ("Image" or "Attachment")
            resource_id: ID of the resource
            storage_key: S3 storage key
            upload_id: The UploadId from create_multipart_upload
        """
        self._client._request(
            "POST",
            f"{self._base_path}/upload/multi-part/abort",
            params={
                "resourceType": resource_type,
                "resourceId": resource_id,
                "storageKey": storage_key,
                "UploadId": upload_id,
            },
        )

    def get_upload_url(
        self,
        resource_type: str,
        resource_id: int,
        storage_key: str,
    ) -> str:
        """Get a presigned S3 URL for single-part upload.

        Args:
            resource_type: Resource type ("Image" or "Attachment")
            resource_id: ID of the resource
            storage_key: S3 storage key

        Returns:
            Presigned S3 URL for PUT
        """
        response = self._client._request(
            "GET",
            f"{self._base_path}/upload/url",
            params={
                "resourceType": resource_type,
                "resourceId": resource_id,
                "storageKey": storage_key,
            },
        )
        return response.json()["url"]
