"""Studies API client for V3."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any, List

if TYPE_CHECKING:
    from concentriq.client import ConcentriqClient


class Studies:
    """Client for Study resources (/api/v3/studies).

    Studies are research projects that manage fields, users, and data collection.
    """

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

        Args:
            client: The ConcentriqClient instance
        """
        self._client = client
        self._base_path = "/api/v3/studies"

    def list(self) -> dict[str, Any]:
        """List all studies.

        Returns:
            Dictionary with "items" (list of studies) and "total"

        Raises:
            AuthenticationError: If not authenticated
        """
        response = self._client._request("GET", self._base_path)
        return response.json()

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

        Args:
            id: Study ID

        Returns:
            Study data

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If study doesn't exist
        """
        response = self._client._request("GET", f"{self._base_path}/{id}")
        return response.json()

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

        Args:
            data: Study data
                - name: Study name (required)
                - description: Description (optional)

        Returns:
            Created study data

        Raises:
            AuthenticationError: If not authenticated
            ValidationError: If required fields are missing
        """
        response = self._client._request("POST", self._base_path, json=data)
        return response.json()

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

        Args:
            id: Study ID
            data: Study data to update

        Returns:
            Updated study data

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If study doesn't exist
        """
        response = self._client._request("PUT", f"{self._base_path}/{id}", json=data)
        return response.json()

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

        Args:
            id: Study ID

        Returns:
            None

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If study doesn't exist
        """
        self._client._request("DELETE", f"{self._base_path}/{id}")

    def get_fields(self, study_id: int) -> List[dict[str, Any]]:
        """Get fields in use by the study.

        Args:
            study_id: Study ID

        Returns:
            List of study field data

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If study doesn't exist
        """
        response = self._client._request("GET", f"{self._base_path}/{study_id}/fields")
        return response.json()

    def add_field(self, study_id: int, field_id: int) -> None:
        """Add field to study.

        Args:
            study_id: Study ID
            field_id: Field ID to add

        Returns:
            None

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If study or field doesn't exist
        """
        self._client._request("POST", f"{self._base_path}/{study_id}/fields/{field_id}")

    def remove_field(self, study_id: int, field_id: int) -> None:
        """Remove field from study.

        Args:
            study_id: Study ID
            field_id: Field ID to remove

        Returns:
            None

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If study or field doesn't exist
        """
        self._client._request("DELETE", f"{self._base_path}/{study_id}/fields/{field_id}")

    def get_users(self, study_id: int) -> List[dict[str, Any]]:
        """Get users in the study.

        Args:
            study_id: Study ID

        Returns:
            List of study user data with userId and role

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If study doesn't exist
        """
        response = self._client._request("GET", f"{self._base_path}/{study_id}/users")
        return response.json()

    def upsert_user(self, study_id: int, user_id: int, data: dict[str, Any]) -> dict[str, Any]:
        """Add or update user in study.

        Args:
            study_id: Study ID
            user_id: User ID
            data: User data (e.g., {"role": "participant"})

        Returns:
            Updated user data

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If study or user doesn't exist
        """
        response = self._client._request(
            "PUT", f"{self._base_path}/{study_id}/users/{user_id}", json=data
        )
        return response.json()

    def remove_user(self, study_id: int, user_id: int) -> None:
        """Remove user from study.

        Args:
            study_id: Study ID
            user_id: User ID to remove

        Returns:
            None

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If study or user doesn't exist
        """
        self._client._request("DELETE", f"{self._base_path}/{study_id}/users/{user_id}")

    def get_statistics(self, study_id: int) -> List[dict[str, Any]]:
        """Get study statistics.

        Returns statistics about user responses in the study.

        Args:
            study_id: Study ID

        Returns:
            List of statistics with:
                - studyId: Study ID
                - userId: User ID
                - resourceType: "Image" or "Folder"
                - responseCount: Number of responses
                - fieldsCount: Number of fields
                - resourceCount: Number of resources

        Raises:
            AuthenticationError: If not authenticated
            NotFoundError: If study doesn't exist
        """
        response = self._client._request("GET", f"{self._base_path}/{study_id}/statistics")
        return response.json()
