"""Folders 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 FolderFilters

if TYPE_CHECKING:
    from concentriq.client import ConcentriqClient


class Folders:
    """Client for Folder resources (/api/folders)."""

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

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

    def list(
        self,
        page: int | None = None,
        rows_per_page: int | None = None,
        filters: FolderFilters | None = None,
        include_metadata: bool | None = None,
    ) -> PaginatedResponse:
        """List folders with pagination and filters.

        Args:
            page: Page number (1-indexed)
            rows_per_page: Items per page
            filters: Filter criteria (FolderFilters model)
            include_metadata: Include metadata fields in response

        Returns:
            PaginatedResponse of folder dictionaries

        Raises:
            AuthenticationError: If not authenticated

        Example:
            filters = FolderFilters(imageSetId=[100], hasMetadata=True)
            folders = client.v1.folders.list(filters=filters)
            for folder in folders:
                print(f"{folder['label']}: {folder['imageSetId']}")
        """
        params = {}

        # Pagination is passed as JSON object in query string
        pagination = {}
        if page is not None:
            pagination["page"] = page
        if rows_per_page is not None:
            pagination["rowsPerPage"] = rows_per_page

        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 'folders' key
        meta = data.get("meta", {})
        items = data.get("data", {}).get("folders", [])
        return PaginatedResponse(items, meta=meta)

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

        Args:
            id: Folder ID

        Returns:
            Folder dictionary

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If folder not found

        Example:
            folder = client.v1.folders.get(123)
            print(f"Folder: {folder['label']} in ImageSet {folder['imageSetId']}")
        """
        response = self._client._request("GET", f"{self._base_path}/{id}")
        data = response.json()

        # V1 API returns data directly (not nested in 'folders')
        return data.get("data", {})

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

        Args:
            data: Folder data (label, imageSetId, folderParentId, hasMetadata)

        Returns:
            Created folder dictionary with id and rank

        Raises:
            AuthenticationError: If not authenticated
            ValidationError: If data is invalid

        Example:
            folder = client.v1.folders.create({
                "label": "New Folder",
                "imageSetId": 100,
                "folderParentId": None,
                "hasMetadata": False
            })
            print(f"Created folder {folder['id']} with rank {folder['rank']}")
        """
        response = self._client._request("POST", self._base_path, json=data)
        result = response.json()

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

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

        Args:
            id: Folder ID
            data: Updated folder data

        Returns:
            None (backend returns success message)

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If folder not found
            ValidationError: If data is invalid

        Example:
            client.v1.folders.update(123, {"label": "Updated Name"})
        """
        self._client._request("PATCH", f"{self._base_path}/{id}", json=data)
        # PATCH returns success message, no need to return anything

    def delete(self, id: int) -> None:
        """Delete a folder.

        Args:
            id: Folder ID

        Returns:
            None

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If folder not found

        Example:
            client.v1.folders.delete(123)
        """
        self._client._request("DELETE", f"{self._base_path}/{id}")
        # DELETE returns 204 No Content, no response body to parse
