"""
Use cases resource classes.

Auto-generated from OpenAPI specification.
Generated: 2026-01-28T01:42:33.414545+00:00
Source: 0.1.0
"""

from __future__ import annotations

from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, Union

from pydantic import BaseModel, TypeAdapter

from ..errors import ApiError, ClientValidationError
from ..models import (
    PaginatedResponse,
    PaginationInfo,
    UseCaseCreate,
    UseCaseResponse,
    UseCaseUpdate,
)


class UseCasesResource:
    """Resource class for use_cases operations

    Provides structured Pydantic types for all use_cases API operations.
    All methods return validated Pydantic models with comprehensive error handling.

    Available operations:
        - create(): Create Use Case
        - list(): List Use Cases
        - get(): Get Use Case
        - update(): Update Use Case
        - delete(): Delete Use Case
    Example:
        >>> client = CredoAI("https://api.example.com", "your-api-key")
        >>> use_cases_resource = client.use_cases
        >>> client.use_cases.create(data=UseCaseCreate(...))
    """

    def __init__(self, client):
        """Initialize the UseCasesResource.

        Args:
            client: The parent client instance providing HTTP functionality.
        """
        self._client = client

    def create(
        self,
        data: UseCaseCreate,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> UseCaseResponse:
        """Create Use Case.

                Create a new use case.

        This endpoint creates a new use case using the authenticated context
        provided by the router-level authentication dependency. The context
        is resolved once at the router level and reused here.

                Args:
                    data (UseCaseCreate): Request data as validated Pydantic model.
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    UseCaseResponse: Validated response data.

                Response Codes:
                    201: Successful Response
                    422: Error

                Raises:
                    ApiError: When the API returns an error status code.
                    ClientValidationError: When response validation fails.
                    httpx.TimeoutException: When request times out."""
        url = "/use_cases"

        return self._client._make_request(
            method="POST",
            url=url,
            data=data,
            timeout=timeout,
            headers=headers,
            response_model=UseCaseResponse,
            is_list_response=False,
        )

    def list(
        self,
        page_limit: Optional[Any] = None,
        page_after: Optional[Any] = None,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> PaginatedResponse[UseCaseResponse]:
        """List Use Cases.

                List all use cases.

        This endpoint retrieves all use cases with optional pagination.
        Returns a paginated response with items and pagination metadata.

                Args:
                    page_limit (Any, optional): Parameter
                    page_after (Any, optional): Parameter
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    List[UseCaseResponse]: Validated response data.

                Response Codes:
                    200: Successful Response
                    422: Error

                Raises:
                    ApiError: When the API returns an error status code.
                    ClientValidationError: When response validation fails.
                    httpx.TimeoutException: When request times out."""
        url = "/use_cases"

        # Build query parameters
        params: Dict[str, Any] = {}
        if page_limit is not None:
            params["page_limit"] = page_limit
        if page_after is not None:
            params["page_after"] = page_after

        return self._client._make_request(
            method="GET",
            url=url,
            params=params if params else None,
            timeout=timeout,
            headers=headers,
            response_model=PaginatedResponse[UseCaseResponse],
            is_list_response=False,
        )

    def get(
        self,
        use_case_id: str,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> UseCaseResponse:
        """Get Use Case.

                Get a use case by ID.

        This endpoint retrieves an existing use case by its ID.

                Args:
                    use_case_id (str): Parameter
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    UseCaseResponse: Validated response data.

                Response Codes:
                    200: Successful Response
                    422: Error

                Raises:
                    ApiError: When the API returns an error status code.
                    ClientValidationError: When response validation fails.
                    httpx.TimeoutException: When request times out."""
        url = "/use_cases/{use_case_id}"
        url = url.replace("{" + "use_case_id" + "}", str(use_case_id))

        return self._client._make_request(
            method="GET",
            url=url,
            timeout=timeout,
            headers=headers,
            response_model=UseCaseResponse,
            is_list_response=False,
        )

    def update(
        self,
        use_case_id: str,
        data: UseCaseUpdate,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> UseCaseResponse:
        """Update Use Case.

                Update an existing use case.

        This endpoint updates an existing use case with the provided data.
        Only the fields provided in the request will be updated.

                Args:
                    use_case_id (str): Parameter
                    data (UseCaseUpdate): Request data as validated Pydantic model.
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    UseCaseResponse: Validated response data.

                Response Codes:
                    200: Successful Response
                    422: Error

                Raises:
                    ApiError: When the API returns an error status code.
                    ClientValidationError: When response validation fails.
                    httpx.TimeoutException: When request times out."""
        url = "/use_cases/{use_case_id}"
        url = url.replace("{" + "use_case_id" + "}", str(use_case_id))

        return self._client._make_request(
            method="PATCH",
            url=url,
            data=data,
            timeout=timeout,
            headers=headers,
            response_model=UseCaseResponse,
            is_list_response=False,
        )

    def delete(
        self,
        use_case_id: str,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> Any:
        """Delete Use Case.

                Delete a use case by ID.

        This endpoint deletes an existing use case by its ID.

                Args:
                    use_case_id (str): Parameter
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    Any: Raw API response data.

                Response Codes:
                    204: Successful Response
                    422: Error

                Raises:
                    ApiError: When the API returns an error status code.
                    ClientValidationError: When response validation fails.
                    httpx.TimeoutException: When request times out."""
        url = "/use_cases/{use_case_id}"
        url = url.replace("{" + "use_case_id" + "}", str(use_case_id))

        return self._client._make_request(
            method="DELETE",
            url=url,
            timeout=timeout,
            headers=headers,
        )

    def list_all(
        self,
        page_size: int = 100,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> Iterator[UseCaseResponse]:
        """Iterate through all use_cases with automatic pagination.

        This generator yields items one at a time, automatically fetching
        the next page when needed. Use this for efficiently processing
        large result sets without loading everything into memory.

        Args:
            page_size (int): Number of items to fetch per page. Default: 100
            timeout (float, optional): Request timeout in seconds.
            headers (Dict[str, str], optional): Additional headers to send.

        Yields:
            UseCaseResponse: Individual items from the list.

        Example:
            >>> for item in client.use_cases.list_all(page_size=50):
            ...     print(item.id)
            >>>
            >>> # Collect all into a list
            >>> all_items = list(client.use_cases.list_all())
        """
        page_after = None
        while True:
            response = self.list(
                page_limit=page_size,
                page_after=page_after,
                timeout=timeout,
                headers=headers,
            )
            # Handle paginated response with items and pagination metadata
            items = response.items
            if not items:
                break
            for item in items:
                yield item
            # Use pagination cursor for next page
            if not response.pagination.has_more:
                break
            page_after = response.pagination.next_cursor

    def __call__(self, use_case_id: str) -> "UseCase":
        """Get a fluent accessor for a specific use_case.

        Enables intuitive subresource access:
            >>> client.use_cases(use_case_id).questionnaires.list()
            >>> client.use_cases(use_case_id).questionnaires.add(data)
            >>> client.use_cases(use_case_id).models.list()
            >>> client.use_cases(use_case_id).models.add(data)
            >>> client.use_cases(use_case_id).vendors.list()
            >>> client.use_cases(use_case_id).vendors.add(data)

        Args:
            use_case_id: The ID of the use_case

        Returns:
            UseCase: Fluent accessor for subresource operations
        """
        from ..fluent import UseCase

        return UseCase(self._client, use_case_id)


class AsyncUseCasesResource:
    """Async resource class for use_cases operations

    Provides async methods with structured Pydantic types for all use_cases API operations.
    All methods are async and return validated Pydantic models with comprehensive error handling.

    Available async operations:
        - create(): Create Use Case
        - list(): List Use Cases
        - get(): Get Use Case
        - update(): Update Use Case
        - delete(): Delete Use Case
    Example:
        >>> async_client = AsyncCredoAI("https://api.example.com", "your-api-key")
        >>> use_cases_resource = async_client.use_cases
        >>> result = await async_client.use_cases.create(data=UseCaseCreate(...))
    """

    def __init__(self, client):
        """Initialize the AsyncUseCasesResource.

        Args:
            client: The parent async client instance providing HTTP functionality.
        """
        self._client = client

    async def create(
        self,
        data: UseCaseCreate,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> UseCaseResponse:
        """Create Use Case.

                Create a new use case.

        This endpoint creates a new use case using the authenticated context
        provided by the router-level authentication dependency. The context
        is resolved once at the router level and reused here.

                Args:
                    data (UseCaseCreate): Request data as validated Pydantic model.
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    UseCaseResponse: Validated response data.

                Response Codes:
                    201: Successful Response
                    422: Error

                Raises:
                    ApiError: When the API returns an error status code.
                    ClientValidationError: When response validation fails.
                    httpx.TimeoutException: When request times out."""
        # Prepare URL with path parameters
        url = "/use_cases"

        # Prepare headers
        request_headers = {"Accept": "application/json"}
        if headers:
            request_headers.update(headers)
        # Serialize request data
        json_data = None
        if data is not None:
            if isinstance(data, BaseModel):
                json_data = data.model_dump(exclude_unset=True, by_alias=True)
            else:
                json_data = data
            request_headers["Content-Type"] = "application/json"

        # Make async request
        httpx_client = self._client.get_async_httpx_client()
        response = await httpx_client.request(
            method="POST",
            url=url,
            json=json_data,
            headers=request_headers,
            timeout=timeout,
        )

        # Handle errors
        if response.status_code >= 400:
            raise ApiError(
                status_code=response.status_code,
                message=f"POST {url} failed",
                response=response,
            )

        # Parse and validate response
        if self._client._validate_responses and response.content:
            try:
                response_data = response.json()

                # Handle JSON:API format
                if isinstance(response_data, dict) and "data" in response_data:
                    from ..models import JsonApiResponse

                    jsonapi_response = JsonApiResponse.model_validate(response_data)
                    data = jsonapi_response.data
                    # Check for attributes in both dict and object forms
                    if isinstance(data, dict) and "attributes" in data:
                        # Merge id from data level with attributes
                        merged = {"id": data.get("id"), **data["attributes"]}
                        parsed_data = UseCaseResponse.model_validate(merged)
                    elif hasattr(data, "attributes"):
                        parsed_data = UseCaseResponse.model_validate(data.attributes)
                    else:
                        parsed_data = UseCaseResponse.model_validate(data)
                    return parsed_data
                parsed_data = UseCaseResponse.model_validate(response_data)
                return parsed_data

            except Exception as e:
                if self._client._validate_responses:
                    raise ClientValidationError(f"Response validation failed: {e}")

        # Return basic response wrapper
        from ..models import ClientResponse

        return ClientResponse.from_httpx_response(
            response, response.json() if response.content else None
        )

    async def list(
        self,
        page_limit: Optional[Any] = None,
        page_after: Optional[Any] = None,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> PaginatedResponse[UseCaseResponse]:
        """List Use Cases.

                List all use cases.

        This endpoint retrieves all use cases with optional pagination.
        Returns a paginated response with items and pagination metadata.

                Args:
                    page_limit (Any, optional): Parameter
                    page_after (Any, optional): Parameter
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    List[UseCaseResponse]: Validated response data.

                Response Codes:
                    200: Successful Response
                    422: Error

                Raises:
                    ApiError: When the API returns an error status code.
                    ClientValidationError: When response validation fails.
                    httpx.TimeoutException: When request times out."""
        # Prepare URL with path parameters
        url = "/use_cases"

        # Build query parameters
        params: Dict[str, Any] = {}
        if page_limit is not None:
            params["page_limit"] = page_limit
        if page_after is not None:
            params["page_after"] = page_after

        # Prepare headers
        request_headers = {"Accept": "application/json"}
        if headers:
            request_headers.update(headers)

        # Make async request
        httpx_client = self._client.get_async_httpx_client()
        response = await httpx_client.request(
            method="GET",
            url=url,
            params=params if params else None,
            headers=request_headers,
            timeout=timeout,
        )

        # Handle errors
        if response.status_code >= 400:
            raise ApiError(
                status_code=response.status_code,
                message=f"GET {url} failed",
                response=response,
            )

        # Parse and validate response
        if self._client._validate_responses and response.content:
            try:
                response_data = response.json()

                # Handle JSON:API format
                if isinstance(response_data, dict) and "data" in response_data:
                    from ..models import JsonApiResponse

                    jsonapi_response = JsonApiResponse.model_validate(response_data)
                    data = jsonapi_response.data
                    # Check for attributes in both dict and object forms
                    if isinstance(data, dict) and "attributes" in data:
                        # Merge id from data level with attributes
                        merged = {"id": data.get("id"), **data["attributes"]}
                        parsed_data = UseCaseResponse.model_validate(merged)
                    elif hasattr(data, "attributes"):
                        parsed_data = UseCaseResponse.model_validate(data.attributes)
                    else:
                        parsed_data = UseCaseResponse.model_validate(data)
                    return parsed_data
                # Handle paginated response
                parsed_data = PaginatedResponse[UseCaseResponse].model_validate(
                    response_data
                )
                return parsed_data

            except Exception as e:
                if self._client._validate_responses:
                    raise ClientValidationError(f"Response validation failed: {e}")

        # Return basic response wrapper
        from ..models import ClientResponse

        return ClientResponse.from_httpx_response(
            response, response.json() if response.content else None
        )

    async def get(
        self,
        use_case_id: str,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> UseCaseResponse:
        """Get Use Case.

                Get a use case by ID.

        This endpoint retrieves an existing use case by its ID.

                Args:
                    use_case_id (str): Parameter
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    UseCaseResponse: Validated response data.

                Response Codes:
                    200: Successful Response
                    422: Error

                Raises:
                    ApiError: When the API returns an error status code.
                    ClientValidationError: When response validation fails.
                    httpx.TimeoutException: When request times out."""
        # Prepare URL with path parameters
        url = "/use_cases/{use_case_id}"
        url = url.replace("{" + "use_case_id" + "}", str(use_case_id))

        # Prepare headers
        request_headers = {"Accept": "application/json"}
        if headers:
            request_headers.update(headers)

        # Make async request
        httpx_client = self._client.get_async_httpx_client()
        response = await httpx_client.request(
            method="GET", url=url, headers=request_headers, timeout=timeout
        )

        # Handle errors
        if response.status_code >= 400:
            raise ApiError(
                status_code=response.status_code,
                message=f"GET {url} failed",
                response=response,
            )

        # Parse and validate response
        if self._client._validate_responses and response.content:
            try:
                response_data = response.json()

                # Handle JSON:API format
                if isinstance(response_data, dict) and "data" in response_data:
                    from ..models import JsonApiResponse

                    jsonapi_response = JsonApiResponse.model_validate(response_data)
                    data = jsonapi_response.data
                    # Check for attributes in both dict and object forms
                    if isinstance(data, dict) and "attributes" in data:
                        # Merge id from data level with attributes
                        merged = {"id": data.get("id"), **data["attributes"]}
                        parsed_data = UseCaseResponse.model_validate(merged)
                    elif hasattr(data, "attributes"):
                        parsed_data = UseCaseResponse.model_validate(data.attributes)
                    else:
                        parsed_data = UseCaseResponse.model_validate(data)
                    return parsed_data
                parsed_data = UseCaseResponse.model_validate(response_data)
                return parsed_data

            except Exception as e:
                if self._client._validate_responses:
                    raise ClientValidationError(f"Response validation failed: {e}")

        # Return basic response wrapper
        from ..models import ClientResponse

        return ClientResponse.from_httpx_response(
            response, response.json() if response.content else None
        )

    async def update(
        self,
        use_case_id: str,
        data: UseCaseUpdate,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> UseCaseResponse:
        """Update Use Case.

                Update an existing use case.

        This endpoint updates an existing use case with the provided data.
        Only the fields provided in the request will be updated.

                Args:
                    use_case_id (str): Parameter
                    data (UseCaseUpdate): Request data as validated Pydantic model.
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    UseCaseResponse: Validated response data.

                Response Codes:
                    200: Successful Response
                    422: Error

                Raises:
                    ApiError: When the API returns an error status code.
                    ClientValidationError: When response validation fails.
                    httpx.TimeoutException: When request times out."""
        # Prepare URL with path parameters
        url = "/use_cases/{use_case_id}"
        url = url.replace("{" + "use_case_id" + "}", str(use_case_id))

        # Prepare headers
        request_headers = {"Accept": "application/json"}
        if headers:
            request_headers.update(headers)
        # Serialize request data
        json_data = None
        if data is not None:
            if isinstance(data, BaseModel):
                json_data = data.model_dump(exclude_unset=True, by_alias=True)
            else:
                json_data = data
            request_headers["Content-Type"] = "application/json"

        # Make async request
        httpx_client = self._client.get_async_httpx_client()
        response = await httpx_client.request(
            method="PATCH",
            url=url,
            json=json_data,
            headers=request_headers,
            timeout=timeout,
        )

        # Handle errors
        if response.status_code >= 400:
            raise ApiError(
                status_code=response.status_code,
                message=f"PATCH {url} failed",
                response=response,
            )

        # Parse and validate response
        if self._client._validate_responses and response.content:
            try:
                response_data = response.json()

                # Handle JSON:API format
                if isinstance(response_data, dict) and "data" in response_data:
                    from ..models import JsonApiResponse

                    jsonapi_response = JsonApiResponse.model_validate(response_data)
                    data = jsonapi_response.data
                    # Check for attributes in both dict and object forms
                    if isinstance(data, dict) and "attributes" in data:
                        # Merge id from data level with attributes
                        merged = {"id": data.get("id"), **data["attributes"]}
                        parsed_data = UseCaseResponse.model_validate(merged)
                    elif hasattr(data, "attributes"):
                        parsed_data = UseCaseResponse.model_validate(data.attributes)
                    else:
                        parsed_data = UseCaseResponse.model_validate(data)
                    return parsed_data
                parsed_data = UseCaseResponse.model_validate(response_data)
                return parsed_data

            except Exception as e:
                if self._client._validate_responses:
                    raise ClientValidationError(f"Response validation failed: {e}")

        # Return basic response wrapper
        from ..models import ClientResponse

        return ClientResponse.from_httpx_response(
            response, response.json() if response.content else None
        )

    async def delete(
        self,
        use_case_id: str,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> Any:
        """Delete Use Case.

                Delete a use case by ID.

        This endpoint deletes an existing use case by its ID.

                Args:
                    use_case_id (str): Parameter
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    Any: Raw API response data.

                Response Codes:
                    204: Successful Response
                    422: Error

                Raises:
                    ApiError: When the API returns an error status code.
                    ClientValidationError: When response validation fails.
                    httpx.TimeoutException: When request times out."""
        # Prepare URL with path parameters
        url = "/use_cases/{use_case_id}"
        url = url.replace("{" + "use_case_id" + "}", str(use_case_id))

        # Prepare headers
        request_headers = {"Accept": "application/json"}
        if headers:
            request_headers.update(headers)

        # Make async request
        httpx_client = self._client.get_async_httpx_client()
        response = await httpx_client.request(
            method="DELETE", url=url, headers=request_headers, timeout=timeout
        )

        # Handle errors
        if response.status_code >= 400:
            raise ApiError(
                status_code=response.status_code,
                message=f"DELETE {url} failed",
                response=response,
            )

        # Parse and validate response

        # Return basic response wrapper
        from ..models import ClientResponse

        return ClientResponse.from_httpx_response(
            response, response.json() if response.content else None
        )

    async def list_all(
        self,
        page_size: int = 100,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> AsyncIterator[UseCaseResponse]:
        """Asynchronously iterate through all use_cases with automatic pagination.

        This async generator yields items one at a time, automatically fetching
        the next page when needed. Use this for efficiently processing
        large result sets without loading everything into memory.

        Args:
            page_size (int): Number of items to fetch per page. Default: 100
            timeout (float, optional): Request timeout in seconds.
            headers (Dict[str, str], optional): Additional headers to send.

        Yields:
            UseCaseResponse: Individual items from the list.

        Example:
            >>> async for item in client.use_cases.list_all(page_size=50):
            ...     print(item.id)
            >>>
            >>> # Collect all into a list
            >>> all_items = [item async for item in client.use_cases.list_all()]
        """
        page_after = None
        while True:
            response = await self.list(
                page_limit=page_size,
                page_after=page_after,
                timeout=timeout,
                headers=headers,
            )
            # Handle paginated response with items and pagination metadata
            items = response.items
            if not items:
                break
            for item in items:
                yield item
            # Use pagination cursor for next page
            if not response.pagination.has_more:
                break
            page_after = response.pagination.next_cursor

    def __call__(self, use_case_id: str) -> "AsyncUseCase":
        """Get an async fluent accessor for a specific use_case.

        Enables intuitive subresource access with async/await:
            >>> await client.use_cases(use_case_id).questionnaires.list()
            >>> await client.use_cases(use_case_id).questionnaires.add(data)
            >>> await client.use_cases(use_case_id).models.list()
            >>> await client.use_cases(use_case_id).models.add(data)
            >>> await client.use_cases(use_case_id).vendors.list()
            >>> await client.use_cases(use_case_id).vendors.add(data)

        Args:
            use_case_id: The ID of the use_case

        Returns:
            AsyncUseCase: Async fluent accessor for subresource operations
        """
        from ..fluent import AsyncUseCase

        return AsyncUseCase(self._client, use_case_id)
