"""
Policy control bases resource classes.

Auto-generated from OpenAPI specification.
"""

from __future__ import annotations

from typing import (
    TYPE_CHECKING,
    Any,
    AsyncIterator,
    Dict,
    Iterator,
    Optional,
)

if TYPE_CHECKING:
    from ..fluent import AsyncPolicyControlBase, PolicyControlBase

from pydantic import BaseModel

from ..errors import ApiError, ClientValidationError
from ..models import (
    PaginatedResponse,
    PolicyControlBaseCreate,
    PolicyControlBaseResponse,
    PolicyControlBaseUpdate,
)


class PolicyControlBasesResource:
    """Resource class for policy_control_bases operations

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

    Available operations:
        - list(): List Policy Control Bases
        - create(): Create Policy Control Base
        - get(): Get Policy Control Base
        - update(): Update Policy Control Base
        - delete(): Delete Policy Control Base
    Example:
        >>> client = CredoAI("https://api.example.com", "your-api-key")
        >>> policy_control_bases_resource = client.policy_control_bases
        >>> client.policy_control_bases.list()
    """

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

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

    def list(
        self,
        page_limit: Optional[Any] = None,
        page_after: Optional[Any] = None,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> PaginatedResponse[PolicyControlBaseResponse]:
        """List Policy Control Bases.

                List all custom policy control bases.

        Returns a paginated list of policy control bases defined by the tenant.

                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[PolicyControlBaseResponse]: 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 = "/policy_control_bases"

        # 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[PolicyControlBaseResponse],
            is_list_response=False,
        )

    def create(
        self,
        data: PolicyControlBaseCreate,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> PolicyControlBaseResponse:
        """Create Policy Control Base.

                Create a new custom policy control base.

        Creates a new policy control base that can have versions attached to it.

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

                Returns:
                    PolicyControlBaseResponse: 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 = "/policy_control_bases"

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

    def get(
        self,
        base_id: str,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> PolicyControlBaseResponse:
        """Get Policy Control Base.

                Get a specific policy control base by ID.

        Returns the details of a custom policy control base.

                Args:
                    base_id (str): The policy control base ID
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    PolicyControlBaseResponse: 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 = "/policy_control_bases/{base_id}"
        url = url.replace("{" + "base_id" + "}", str(base_id))

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

    def update(
        self,
        base_id: str,
        data: PolicyControlBaseUpdate,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> PolicyControlBaseResponse:
        """Update Policy Control Base.

                Update an existing policy control base.

        Updates the specified policy control base. Currently supports archiving.

                Args:
                    base_id (str): The policy control base ID
                    data (PolicyControlBaseUpdate): Request data as validated Pydantic model.
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    PolicyControlBaseResponse: 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 = "/policy_control_bases/{base_id}"
        url = url.replace("{" + "base_id" + "}", str(base_id))

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

    def delete(
        self,
        base_id: str,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> Any:
        """Delete Policy Control Base.

                Delete a policy control base.

        Deletes the specified policy control base and all associated versions.

                Args:
                    base_id (str): The policy control base ID
                    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 = "/policy_control_bases/{base_id}"
        url = url.replace("{" + "base_id" + "}", str(base_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[PolicyControlBaseResponse]:
        """Iterate through all policy_control_bases 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:
            PolicyControlBaseResponse: Individual items from the list.

        Example:
            >>> for item in client.policy_control_bases.list_all(page_size=50):
            ...     print(item.id)
            >>>
            >>> # Collect all into a list
            >>> all_items = list(client.policy_control_bases.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, policy_control_base_id: str) -> "PolicyControlBase":
        """Get a fluent accessor for a specific policy_control_base.

        Enables intuitive subresource access:
            >>> client.policy_control_bases(policy_control_base_id).versions.list()

        Args:
            policy_control_base_id: The ID of the policy_control_base

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

        return PolicyControlBase(self._client, policy_control_base_id)


class AsyncPolicyControlBasesResource:
    """Async resource class for policy_control_bases operations

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

    Available async operations:
        - list(): List Policy Control Bases
        - create(): Create Policy Control Base
        - get(): Get Policy Control Base
        - update(): Update Policy Control Base
        - delete(): Delete Policy Control Base
    Example:
        >>> async_client = AsyncCredoAI("https://api.example.com", "your-api-key")
        >>> policy_control_bases_resource = async_client.policy_control_bases
        >>> result = await async_client.policy_control_bases.list()
    """

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

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

    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[PolicyControlBaseResponse]:
        """List Policy Control Bases.

                List all custom policy control bases.

        Returns a paginated list of policy control bases defined by the tenant.

                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[PolicyControlBaseResponse]: 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 = "/policy_control_bases"

        # 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 = PolicyControlBaseResponse.model_validate(merged)
                    elif hasattr(data, "attributes"):
                        parsed_data = PolicyControlBaseResponse.model_validate(
                            data.attributes
                        )
                    else:
                        parsed_data = PolicyControlBaseResponse.model_validate(data)
                    return parsed_data
                # Handle paginated response
                parsed_data = PaginatedResponse[
                    PolicyControlBaseResponse
                ].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 create(
        self,
        data: PolicyControlBaseCreate,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> PolicyControlBaseResponse:
        """Create Policy Control Base.

                Create a new custom policy control base.

        Creates a new policy control base that can have versions attached to it.

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

                Returns:
                    PolicyControlBaseResponse: 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 = "/policy_control_bases"

        # 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 = PolicyControlBaseResponse.model_validate(merged)
                    elif hasattr(data, "attributes"):
                        parsed_data = PolicyControlBaseResponse.model_validate(
                            data.attributes
                        )
                    else:
                        parsed_data = PolicyControlBaseResponse.model_validate(data)
                    return parsed_data
                parsed_data = PolicyControlBaseResponse.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,
        base_id: str,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> PolicyControlBaseResponse:
        """Get Policy Control Base.

                Get a specific policy control base by ID.

        Returns the details of a custom policy control base.

                Args:
                    base_id (str): The policy control base ID
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    PolicyControlBaseResponse: 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 = "/policy_control_bases/{base_id}"
        url = url.replace("{" + "base_id" + "}", str(base_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 = PolicyControlBaseResponse.model_validate(merged)
                    elif hasattr(data, "attributes"):
                        parsed_data = PolicyControlBaseResponse.model_validate(
                            data.attributes
                        )
                    else:
                        parsed_data = PolicyControlBaseResponse.model_validate(data)
                    return parsed_data
                parsed_data = PolicyControlBaseResponse.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,
        base_id: str,
        data: PolicyControlBaseUpdate,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> PolicyControlBaseResponse:
        """Update Policy Control Base.

                Update an existing policy control base.

        Updates the specified policy control base. Currently supports archiving.

                Args:
                    base_id (str): The policy control base ID
                    data (PolicyControlBaseUpdate): Request data as validated Pydantic model.
                    timeout (float, optional): Request timeout in seconds.
                    headers (Dict[str, str], optional): Additional headers to send.

                Returns:
                    PolicyControlBaseResponse: 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 = "/policy_control_bases/{base_id}"
        url = url.replace("{" + "base_id" + "}", str(base_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 = PolicyControlBaseResponse.model_validate(merged)
                    elif hasattr(data, "attributes"):
                        parsed_data = PolicyControlBaseResponse.model_validate(
                            data.attributes
                        )
                    else:
                        parsed_data = PolicyControlBaseResponse.model_validate(data)
                    return parsed_data
                parsed_data = PolicyControlBaseResponse.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,
        base_id: str,
        *,
        timeout: Optional[float] = None,
        headers: Optional[Dict[str, str]] = None,
    ) -> Any:
        """Delete Policy Control Base.

                Delete a policy control base.

        Deletes the specified policy control base and all associated versions.

                Args:
                    base_id (str): The policy control base ID
                    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 = "/policy_control_bases/{base_id}"
        url = url.replace("{" + "base_id" + "}", str(base_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[PolicyControlBaseResponse]:
        """Asynchronously iterate through all policy_control_bases 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:
            PolicyControlBaseResponse: Individual items from the list.

        Example:
            >>> async for item in client.policy_control_bases.list_all(page_size=50):
            ...     print(item.id)
            >>>
            >>> # Collect all into a list
            >>> all_items = [item async for item in client.policy_control_bases.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, policy_control_base_id: str) -> "AsyncPolicyControlBase":
        """Get an async fluent accessor for a specific policy_control_base.

        Enables intuitive subresource access with async/await:
            >>> await client.policy_control_bases(policy_control_base_id).versions.list()

        Args:
            policy_control_base_id: The ID of the policy_control_base

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

        return AsyncPolicyControlBase(self._client, policy_control_base_id)
