"""Annotations 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 AnnotationFilters

if TYPE_CHECKING:
    from concentriq.client import ConcentriqClient


class Annotations:
    """Client for Annotation resources (/api/annotations)."""

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

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

    def list(
        self,
        page: int | None = None,
        rows_per_page: int | None = None,
        filters: AnnotationFilters | None = None,
    ) -> PaginatedResponse:
        """List annotations with pagination and filters.

        Args:
            page: Page number (1-indexed)
            rows_per_page: Items per page
            filters: Filter criteria (AnnotationFilters model)

        Returns:
            PaginatedResponse of annotation dictionaries

        Raises:
            AuthenticationError: If not authenticated

        Example:
            filters = AnnotationFilters(imageId=[100], text=["ROI"])
            annotations = client.v1.annotations.list(filters=filters)
            for annotation in annotations:
                print(f"{annotation['text']}: {annotation['imageId']}")
        """
        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)

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

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

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

        Args:
            id: Annotation ID

        Returns:
            Annotation dictionary

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

        Example:
            annotation = client.v1.annotations.get(123)
            print(f"Annotation: {annotation['text']} on image {annotation['imageId']}")
        """
        response = self._client._request("GET", f"{self._base_path}/{id}")
        data = response.json()

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

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

        Args:
            data: Annotation data (imageId, shape, shapeString, captureBounds, isSegmenting, etc.)

        Returns:
            Created annotation dictionary with id

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

        Example:
            annotation = client.v1.annotations.create({
                "text": "Region of Interest",
                "imageId": 100,
                "shape": "rect",
                "shapeString": "0,0,100,100",
                "captureBounds": "0,0,1000,1000",
                "isSegmenting": False,
                "color": "#FF0000"
            })
            print(f"Created annotation {annotation['id']}")
        """
        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]) -> dict[str, Any]:
        """Update an existing annotation.

        Args:
            id: Annotation ID
            data: Updated annotation data

        Returns:
            Updated annotation dictionary

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

        Example:
            annotation = client.v1.annotations.update(123, {
                "text": "Updated Label",
                "color": "#00FF00"
            })
            print(f"Updated annotation {annotation['id']}")
        """
        response = self._client._request("PATCH", f"{self._base_path}/{id}", json=data)
        result = response.json()

        # V1 API returns updated annotation data
        return result.get("data", {})

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

        Args:
            id: Annotation ID

        Returns:
            None

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

        Example:
            client.v1.annotations.delete(123)
        """
        self._client._request("DELETE", f"{self._base_path}/{id}")
        # DELETE returns success message, no need to return anything
