"""ImageSets resource client for V1."""

from __future__ import annotations

import json
from typing import TYPE_CHECKING, Any

from concentriq.models.paginated import PaginatedResponse
from concentriq.models.v1.filters import ImageSetFilters

if TYPE_CHECKING:
    from concentriq.client import ConcentriqClient


class ImageSets:
    """Client for ImageSet resources (/api/imageSets)."""

    def __init__(self, client: "ConcentriqClient"):
        """Initialize with client instance.

        Args:
            client: ConcentriqClient instance
        """
        self._client = client
        self._base_path = "/api/imageSets"

    def list(
        self,
        page: int | None = None,
        rows_per_page: int | None = None,
        sort_by: str | None = None,
        descending: bool | None = None,
        filters: ImageSetFilters | None = None,
        include_metadata: bool | None = None,
    ) -> PaginatedResponse:
        """List image sets with pagination and filters.

        Args:
            page: Page number (1-indexed)
            rows_per_page: Items per page
            sort_by: Field to sort by (e.g., 'name', 'created')
            descending: Sort descending if True, ascending if False
            filters: Filter criteria (ImageSetFilters model)
            include_metadata: Include metadata fields in response

        Returns:
            PaginatedResponse of image set data dictionaries

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If resource not found
            ValidationError: If parameters are invalid

        Example:
            filters = ImageSetFilters(ownerId=[1], isFavorite=True)
            image_sets = client.v1.image_sets.list(filters=filters)
        """
        params: dict[str, Any] = {}

        # Pagination is passed as JSON object in query string
        pagination: dict[str, Any] = {}
        if page is not None:
            pagination["page"] = page
        if rows_per_page is not None:
            pagination["rowsPerPage"] = rows_per_page
        if sort_by is not None:
            pagination["sortBy"] = sort_by
        if descending is not None:
            pagination["descending"] = descending

        if pagination:
            params["pagination"] = json.dumps(pagination)

        if filters is not None:
            params["filters"] = filters.model_dump_json(exclude_none=True)

        if include_metadata is not None:
            params["includeMetadata"] = "true" if include_metadata else "false"

        response = self._client._request("GET", self._base_path, params=params)
        data = response.json()

        # V1 API returns data in envelope format with 'imageSets' key
        meta = data.get("meta", {})
        items = data.get("data", {}).get("imageSets", [])
        return PaginatedResponse(items, meta=meta)

    def get(self, id: int) -> dict[str, Any]:
        """Get a single image set by ID.

        Args:
            id: Image set ID

        Returns:
            Image set data dictionary

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If image set not found
        """
        response = self._client._request("GET", f"{self._base_path}/{id}")
        data = response.json()

        # V1 API returns data in envelope format
        return data.get("data", {})

    def create(self, data: dict[str, Any]) -> dict[str, Any]:
        """Create a new image set.

        Args:
            data: Image set data (name, description, etc.)

        Returns:
            Created image set data dictionary

        Raises:
            AuthenticationError: If not authenticated
            ValidationError: If data is invalid
        """
        response = self._client._request("POST", self._base_path, json=data)
        response_data = response.json()

        # V1 API returns data in envelope format
        return response_data.get("data", {})

    def update(self, id: int, data: dict[str, Any]) -> dict[str, Any]:
        """Update an existing image set.

        Args:
            id: Image set ID
            data: Updated image set data

        Returns:
            Updated image set data dictionary

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If image set not found
            ValidationError: If data is invalid
        """
        response = self._client._request("PATCH", f"{self._base_path}/{id}", json=data)
        response_data = response.json()

        # V1 API returns data in envelope format
        return response_data.get("data", {})

    def delete(self, id: int) -> None:
        """Delete an image set.

        Args:
            id: Image set ID

        Returns:
            None

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If image set not found
        """
        self._client._request("DELETE", f"{self._base_path}/{id}")
        # DELETE typically returns 204 No Content
        return None
