"""MetadataFields resource client for V1."""

from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from concentriq.client import ConcentriqClient


class MetadataFields:
    """Client for metadata field definitions (/api/metadata-fields)."""

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

        Args:
            client: ConcentriqClient instance
        """
        self._client = client
        self._base_path = "/api/metadata-fields"
        self._cache: list[dict[str, Any]] | None = None

    def list(self) -> list[dict[str, Any]]:
        """List metadata field definitions.

        Returns:
            List of metadata field dictionaries

        Raises:
            AuthenticationError: If not authenticated

        Example:
            fields = client.v1.metadata_fields.list()
            for field in fields:
                print(f"{field['name']}: {field['contentType']}")
        """
        response = self._client._request("GET", f"{self._base_path}/")
        data = response.json()

        # V1 API returns data in envelope format with 'fields' key
        return data.get("data", {}).get("fields", [])

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

        Args:
            id: Metadata field ID

        Returns:
            Metadata field dictionary

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

        Example:
            field = client.v1.metadata_fields.get(42)
            print(f"Field: {field['name']} ({field['contentType']})")
        """
        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 metadata field definition.

        Args:
            data: Field definition data (name, contentType, resourceType, etc.)

        Returns:
            Created metadata field dictionary

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

        Example:
            field = client.v1.metadata_fields.create({
                "name": "Patient ID",
                "contentType": "string",
                "resourceType": "image"
            })
            print(f"Created field {field['id']}: {field['name']}")
        """
        response = self._client._request("POST", f"{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 metadata field definition.

        Args:
            id: Metadata field ID
            data: Updated field data

        Returns:
            Updated metadata field dictionary

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

        Example:
            field = client.v1.metadata_fields.update(42, {
                "name": "Updated Field Name"
            })
            print(f"Updated field: {field['name']}")
        """
        response = self._client._request("PATCH", f"{self._base_path}/{id}", json=data)
        result = response.json()

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

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

        Args:
            id: Metadata field ID

        Returns:
            None

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

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

    def get_by_name(
        self,
        name: str,
        resource_type: str | None = None,
        refresh: bool = False,
    ) -> dict[str, Any] | None:
        """Look up a metadata field by name, using a cached field list.

        Args:
            name: Exact field name to search for
            resource_type: Optional filter (e.g. "image", "imageSet", "folder")
            refresh: If True, refetch fields from API instead of using cache

        Returns:
            Field definition dict, or None if not found

        Example:
            field = client.v1.metadata_fields.get_by_name("Status", resource_type="image")
        """
        if self._cache is None or refresh:
            self._cache = self.list()

        for field in self._cache:
            if field["name"] != name:
                continue
            if resource_type is not None and field.get("resourceType") != resource_type:
                continue
            return field

        return None
