"""
Fluent accessor classes for UseCase resources.

Auto-generated from OpenAPI specification.
"""

from typing import TYPE_CHECKING, Any, Dict, Optional, Union

from ..models import (
    ModelResponse,
    PaginatedResponse,
    QuestionnaireAttachment,
    QuestionnaireAttachmentResponse,
    QuestionnaireAttachmentUpdate,
    RelationshipAdd,
    VendorResponse,
)

if TYPE_CHECKING:
    from ..client import AsyncCredoAI, CredoAI


# =============================================================================
# UseCase Fluent Accessors (Sync)
# =============================================================================


class UseCaseQuestionnairesAccessor:
    """Manage questionnaires for a specific use_case.

    This accessor provides methods to add, list, patch, remove
    questionnaires associated with a use_case.

    Example:
        >>> client.use_case("use_case-id").questionnaires.list()
        >>> client.use_case("use_case-id").questionnaires.add(QuestionnaireAttachment(key="...", version=1))
        >>> client.use_case("use_case-id").questionnaires.remove("questionnaire-id")
    """

    def __init__(self, client: "CredoAI", use_case_id: str):
        """Initialize the questionnaires accessor.

        Args:
            client: The CredoAI client instance
            use_case_id: The ID of the parent use_case
        """
        self._client = client
        self._use_case_id = use_case_id

    def list(
        self,
        cursor: Optional[str] = None,
        limit: Optional[int] = None,
    ) -> "PaginatedResponse[QuestionnaireAttachmentResponse]":
        """List questionnaires associated with this use_case.

        Args:
            cursor: Pagination cursor for next page
            limit: Maximum number of results to return

        Returns:
            PaginatedResponse containing QuestionnaireAttachmentResponse items
        """
        params: Dict[str, Any] = {}
        if cursor is not None:
            params["cursor"] = cursor
        if limit is not None:
            params["limit"] = limit

        return self._client._make_request(
            method="GET",
            url=f"/use_cases/{self._use_case_id}/questionnaires",
            params=params if params else None,
            response_model=PaginatedResponse[QuestionnaireAttachmentResponse],
        )

    def add(
        self,
        questionnaire: "Union[QuestionnaireAttachment, QuestionnaireAttachmentResponse]",
    ) -> "QuestionnaireAttachmentResponse":
        """Add a questionnaire to this use_case.

        Args:
            questionnaire: A QuestionnaireAttachment object, or a QuestionnaireAttachmentResponse to extract fields from

        Returns:
            QuestionnaireAttachmentResponse: The added questionnaire

        Examples:
            >>> # Using request model directly
            >>> use_case.questionnaires.add(QuestionnaireAttachment(...))
            >>> # Using a fetched response object (extracts matching fields)
            >>> fetched = client.questionnaires.get("id")
            >>> use_case.questionnaires.add(fetched)
        """
        if isinstance(questionnaire, QuestionnaireAttachment):
            data = questionnaire
        else:
            # Extract fields from response object to create request model
            field_values = {
                field: getattr(questionnaire, field)
                for field in QuestionnaireAttachment.model_fields
                if hasattr(questionnaire, field)
            }
            data = QuestionnaireAttachment(**field_values)

        return self._client._make_request(
            method="POST",
            url=f"/use_cases/{self._use_case_id}/questionnaires",
            data=data,
            response_model=QuestionnaireAttachmentResponse,
        )

    def remove(self, questionnaire_id: str) -> None:
        """Remove a questionnaire from this use_case.

        Args:
            questionnaire_id: The ID of the questionnaire to remove
        """
        self._client._make_request(
            method="DELETE",
            url=f"/use_cases/{self._use_case_id}/questionnaires/{questionnaire_id}",
        )


class UseCaseModelsAccessor:
    """Manage models for a specific use_case.

    This accessor provides methods to add, list, remove
    models associated with a use_case.

    Example:
        >>> client.use_case("use_case-id").models.list()
        >>> client.use_case("use_case-id").models.add("model-id")
        >>> client.use_case("use_case-id").models.remove("model-id")
    """

    def __init__(self, client: "CredoAI", use_case_id: str):
        """Initialize the models accessor.

        Args:
            client: The CredoAI client instance
            use_case_id: The ID of the parent use_case
        """
        self._client = client
        self._use_case_id = use_case_id

    def list(
        self,
        cursor: Optional[str] = None,
        limit: Optional[int] = None,
    ) -> "PaginatedResponse[ModelResponse]":
        """List models associated with this use_case.

        Args:
            cursor: Pagination cursor for next page
            limit: Maximum number of results to return

        Returns:
            PaginatedResponse containing ModelResponse items
        """
        params: Dict[str, Any] = {}
        if cursor is not None:
            params["cursor"] = cursor
        if limit is not None:
            params["limit"] = limit

        return self._client._make_request(
            method="GET",
            url=f"/use_cases/{self._use_case_id}/models",
            params=params if params else None,
            response_model=PaginatedResponse[ModelResponse],
        )

    def add(self, model: "Union[str, ModelResponse]") -> "ModelResponse":
        """Add a model to this use_case.

        Args:
            model: The model ID as a string, or a ModelResponse object

        Returns:
            ModelResponse: The added model

        Examples:
            >>> # Using ID directly
            >>> use_case.models.add("model-123")
            >>> # Using a fetched/created response object
            >>> created = client.models.create(...)
            >>> use_case.models.add(created)
        """
        model_id = model if isinstance(model, str) else model.id

        return self._client._make_request(
            method="POST",
            url=f"/use_cases/{self._use_case_id}/models",
            data={"id": model_id},
            response_model=ModelResponse,
        )

    def remove(self, model_id: str) -> None:
        """Remove a model from this use_case.

        Args:
            model_id: The ID of the model to remove
        """
        self._client._make_request(
            method="DELETE",
            url=f"/use_cases/{self._use_case_id}/models/{model_id}",
        )


class UseCaseVendorsAccessor:
    """Manage vendors for a specific use_case.

    This accessor provides methods to add, list, remove
    vendors associated with a use_case.

    Example:
        >>> client.use_case("use_case-id").vendors.list()
        >>> client.use_case("use_case-id").vendors.add("vendor-id")
        >>> client.use_case("use_case-id").vendors.remove("vendor-id")
    """

    def __init__(self, client: "CredoAI", use_case_id: str):
        """Initialize the vendors accessor.

        Args:
            client: The CredoAI client instance
            use_case_id: The ID of the parent use_case
        """
        self._client = client
        self._use_case_id = use_case_id

    def list(
        self,
        cursor: Optional[str] = None,
        limit: Optional[int] = None,
    ) -> "PaginatedResponse[VendorResponse]":
        """List vendors associated with this use_case.

        Args:
            cursor: Pagination cursor for next page
            limit: Maximum number of results to return

        Returns:
            PaginatedResponse containing VendorResponse items
        """
        params: Dict[str, Any] = {}
        if cursor is not None:
            params["cursor"] = cursor
        if limit is not None:
            params["limit"] = limit

        return self._client._make_request(
            method="GET",
            url=f"/use_cases/{self._use_case_id}/vendors",
            params=params if params else None,
            response_model=PaginatedResponse[VendorResponse],
        )

    def add(self, vendor: "Union[str, VendorResponse]") -> "VendorResponse":
        """Add a vendor to this use_case.

        Args:
            vendor: The vendor ID as a string, or a VendorResponse object

        Returns:
            VendorResponse: The added vendor

        Examples:
            >>> # Using ID directly
            >>> use_case.vendors.add("vendor-123")
            >>> # Using a fetched/created response object
            >>> created = client.vendors.create(...)
            >>> use_case.vendors.add(created)
        """
        vendor_id = vendor if isinstance(vendor, str) else vendor.id

        return self._client._make_request(
            method="POST",
            url=f"/use_cases/{self._use_case_id}/vendors",
            data={"id": vendor_id},
            response_model=VendorResponse,
        )

    def remove(self, vendor_id: str) -> None:
        """Remove a vendor from this use_case.

        Args:
            vendor_id: The ID of the vendor to remove
        """
        self._client._make_request(
            method="DELETE",
            url=f"/use_cases/{self._use_case_id}/vendors/{vendor_id}",
        )


class UseCase:
    """Fluent accessor for a specific use_case.

    Provides access to related resources through property accessors that enable
    intuitive chaining.

    Example:
        >>> use_case = client.use_case("use_case-id")
        >>> use_case.questionnaires.list()
        >>> use_case.questionnaires.add(QuestionnaireAttachment(key="...", version=1))
        >>> use_case.models.list()
        >>> use_case.models.add("model-id")
        >>> use_case.vendors.list()
        >>> use_case.vendors.add("vendor-id")
    """

    def __init__(self, client: "CredoAI", use_case_id: str):
        """Initialize the use_case accessor.

        Args:
            client: The CredoAI client instance
            use_case_id: The ID of the use_case
        """
        self._client = client
        self._use_case_id = use_case_id

    @property
    def questionnaires(self) -> "UseCaseQuestionnairesAccessor":
        """Access questionnaires associated with this use_case.

        Returns:
            UseCaseQuestionnairesAccessor: Accessor for questionnaires operations
        """
        return UseCaseQuestionnairesAccessor(self._client, self._use_case_id)

    @property
    def models(self) -> "UseCaseModelsAccessor":
        """Access models associated with this use_case.

        Returns:
            UseCaseModelsAccessor: Accessor for models operations
        """
        return UseCaseModelsAccessor(self._client, self._use_case_id)

    @property
    def vendors(self) -> "UseCaseVendorsAccessor":
        """Access vendors associated with this use_case.

        Returns:
            UseCaseVendorsAccessor: Accessor for vendors operations
        """
        return UseCaseVendorsAccessor(self._client, self._use_case_id)


# =============================================================================
# UseCase Fluent Accessors (Async)
# =============================================================================


class AsyncUseCaseQuestionnairesAccessor:
    """Async manage questionnaires for a specific use_case.

    This accessor provides async methods to add, list, patch, remove
    questionnaires associated with a use_case.

    Example:
        >>> await client.use_case("use_case-id").questionnaires.list()
        >>> await client.use_case("use_case-id").questionnaires.add(QuestionnaireAttachment(key="...", version=1))
        >>> await client.use_case("use_case-id").questionnaires.remove("questionnaire-id")
    """

    def __init__(self, client: "AsyncCredoAI", use_case_id: str):
        """Initialize the async questionnaires accessor.

        Args:
            client: The AsyncCredoAI client instance
            use_case_id: The ID of the parent use_case
        """
        self._client = client
        self._use_case_id = use_case_id

    async def list(
        self,
        cursor: Optional[str] = None,
        limit: Optional[int] = None,
    ) -> "PaginatedResponse[QuestionnaireAttachmentResponse]":
        """List questionnaires associated with this use_case.

        Args:
            cursor: Pagination cursor for next page
            limit: Maximum number of results to return

        Returns:
            PaginatedResponse containing QuestionnaireAttachmentResponse items
        """
        params: Dict[str, Any] = {}
        if cursor is not None:
            params["cursor"] = cursor
        if limit is not None:
            params["limit"] = limit

        return await self._client._make_request_async(
            method="GET",
            url=f"/use_cases/{self._use_case_id}/questionnaires",
            params=params if params else None,
            response_model=PaginatedResponse[QuestionnaireAttachmentResponse],
        )

    async def add(
        self,
        questionnaire: "Union[QuestionnaireAttachment, QuestionnaireAttachmentResponse]",
    ) -> "QuestionnaireAttachmentResponse":
        """Add a questionnaire to this use_case.

        Args:
            questionnaire: A QuestionnaireAttachment object, or a QuestionnaireAttachmentResponse to extract fields from

        Returns:
            QuestionnaireAttachmentResponse: The added questionnaire

        Examples:
            >>> # Using request model directly
            >>> use_case.questionnaires.add(QuestionnaireAttachment(...))
            >>> # Using a fetched response object (extracts matching fields)
            >>> fetched = client.questionnaires.get("id")
            >>> use_case.questionnaires.add(fetched)
        """
        if isinstance(questionnaire, QuestionnaireAttachment):
            data = questionnaire
        else:
            # Extract fields from response object to create request model
            field_values = {
                field: getattr(questionnaire, field)
                for field in QuestionnaireAttachment.model_fields
                if hasattr(questionnaire, field)
            }
            data = QuestionnaireAttachment(**field_values)

        return await self._client._make_request_async(
            method="POST",
            url=f"/use_cases/{self._use_case_id}/questionnaires",
            data=data,
            response_model=QuestionnaireAttachmentResponse,
        )

    async def remove(self, questionnaire_id: str) -> None:
        """Remove a questionnaire from this use_case.

        Args:
            questionnaire_id: The ID of the questionnaire to remove
        """
        await self._client._make_request_async(
            method="DELETE",
            url=f"/use_cases/{self._use_case_id}/questionnaires/{questionnaire_id}",
        )


class AsyncUseCaseModelsAccessor:
    """Async manage models for a specific use_case.

    This accessor provides async methods to add, list, remove
    models associated with a use_case.

    Example:
        >>> await client.use_case("use_case-id").models.list()
        >>> await client.use_case("use_case-id").models.add("model-id")
        >>> await client.use_case("use_case-id").models.remove("model-id")
    """

    def __init__(self, client: "AsyncCredoAI", use_case_id: str):
        """Initialize the async models accessor.

        Args:
            client: The AsyncCredoAI client instance
            use_case_id: The ID of the parent use_case
        """
        self._client = client
        self._use_case_id = use_case_id

    async def list(
        self,
        cursor: Optional[str] = None,
        limit: Optional[int] = None,
    ) -> "PaginatedResponse[ModelResponse]":
        """List models associated with this use_case.

        Args:
            cursor: Pagination cursor for next page
            limit: Maximum number of results to return

        Returns:
            PaginatedResponse containing ModelResponse items
        """
        params: Dict[str, Any] = {}
        if cursor is not None:
            params["cursor"] = cursor
        if limit is not None:
            params["limit"] = limit

        return await self._client._make_request_async(
            method="GET",
            url=f"/use_cases/{self._use_case_id}/models",
            params=params if params else None,
            response_model=PaginatedResponse[ModelResponse],
        )

    async def add(self, model: "Union[str, ModelResponse]") -> "ModelResponse":
        """Add a model to this use_case.

        Args:
            model: The model ID as a string, or a ModelResponse object

        Returns:
            ModelResponse: The added model

        Examples:
            >>> # Using ID directly
            >>> use_case.models.add("model-123")
            >>> # Using a fetched/created response object
            >>> created = client.models.create(...)
            >>> use_case.models.add(created)
        """
        model_id = model if isinstance(model, str) else model.id

        return await self._client._make_request_async(
            method="POST",
            url=f"/use_cases/{self._use_case_id}/models",
            data={"id": model_id},
            response_model=ModelResponse,
        )

    async def remove(self, model_id: str) -> None:
        """Remove a model from this use_case.

        Args:
            model_id: The ID of the model to remove
        """
        await self._client._make_request_async(
            method="DELETE",
            url=f"/use_cases/{self._use_case_id}/models/{model_id}",
        )


class AsyncUseCaseVendorsAccessor:
    """Async manage vendors for a specific use_case.

    This accessor provides async methods to add, list, remove
    vendors associated with a use_case.

    Example:
        >>> await client.use_case("use_case-id").vendors.list()
        >>> await client.use_case("use_case-id").vendors.add("vendor-id")
        >>> await client.use_case("use_case-id").vendors.remove("vendor-id")
    """

    def __init__(self, client: "AsyncCredoAI", use_case_id: str):
        """Initialize the async vendors accessor.

        Args:
            client: The AsyncCredoAI client instance
            use_case_id: The ID of the parent use_case
        """
        self._client = client
        self._use_case_id = use_case_id

    async def list(
        self,
        cursor: Optional[str] = None,
        limit: Optional[int] = None,
    ) -> "PaginatedResponse[VendorResponse]":
        """List vendors associated with this use_case.

        Args:
            cursor: Pagination cursor for next page
            limit: Maximum number of results to return

        Returns:
            PaginatedResponse containing VendorResponse items
        """
        params: Dict[str, Any] = {}
        if cursor is not None:
            params["cursor"] = cursor
        if limit is not None:
            params["limit"] = limit

        return await self._client._make_request_async(
            method="GET",
            url=f"/use_cases/{self._use_case_id}/vendors",
            params=params if params else None,
            response_model=PaginatedResponse[VendorResponse],
        )

    async def add(self, vendor: "Union[str, VendorResponse]") -> "VendorResponse":
        """Add a vendor to this use_case.

        Args:
            vendor: The vendor ID as a string, or a VendorResponse object

        Returns:
            VendorResponse: The added vendor

        Examples:
            >>> # Using ID directly
            >>> use_case.vendors.add("vendor-123")
            >>> # Using a fetched/created response object
            >>> created = client.vendors.create(...)
            >>> use_case.vendors.add(created)
        """
        vendor_id = vendor if isinstance(vendor, str) else vendor.id

        return await self._client._make_request_async(
            method="POST",
            url=f"/use_cases/{self._use_case_id}/vendors",
            data={"id": vendor_id},
            response_model=VendorResponse,
        )

    async def remove(self, vendor_id: str) -> None:
        """Remove a vendor from this use_case.

        Args:
            vendor_id: The ID of the vendor to remove
        """
        await self._client._make_request_async(
            method="DELETE",
            url=f"/use_cases/{self._use_case_id}/vendors/{vendor_id}",
        )


class AsyncUseCase:
    """Async fluent accessor for a specific use_case.

    Provides access to related resources through property accessors that enable
    intuitive chaining with async/await.

    Example:
        >>> use_case = client.use_case("use_case-id")
        >>> await use_case.questionnaires.list()
        >>> await use_case.questionnaires.add(QuestionnaireAttachment(key="...", version=1))
        >>> await use_case.models.list()
        >>> await use_case.models.add("model-id")
        >>> await use_case.vendors.list()
        >>> await use_case.vendors.add("vendor-id")
    """

    def __init__(self, client: "AsyncCredoAI", use_case_id: str):
        """Initialize the async use_case accessor.

        Args:
            client: The AsyncCredoAI client instance
            use_case_id: The ID of the use_case
        """
        self._client = client
        self._use_case_id = use_case_id

    @property
    def questionnaires(self) -> "AsyncUseCaseQuestionnairesAccessor":
        """Access questionnaires associated with this use_case.

        Returns:
            AsyncUseCaseQuestionnairesAccessor: Async accessor for questionnaires operations
        """
        return AsyncUseCaseQuestionnairesAccessor(self._client, self._use_case_id)

    @property
    def models(self) -> "AsyncUseCaseModelsAccessor":
        """Access models associated with this use_case.

        Returns:
            AsyncUseCaseModelsAccessor: Async accessor for models operations
        """
        return AsyncUseCaseModelsAccessor(self._client, self._use_case_id)

    @property
    def vendors(self) -> "AsyncUseCaseVendorsAccessor":
        """Access vendors associated with this use_case.

        Returns:
            AsyncUseCaseVendorsAccessor: Async accessor for vendors operations
        """
        return AsyncUseCaseVendorsAccessor(self._client, self._use_case_id)


# =============================================================================
# Export list
# =============================================================================

__all__ = [
    "UseCase",
    "AsyncUseCase",
    "UseCaseQuestionnairesAccessor",
    "AsyncUseCaseQuestionnairesAccessor",
    "UseCaseModelsAccessor",
    "AsyncUseCaseModelsAccessor",
    "UseCaseVendorsAccessor",
    "AsyncUseCaseVendorsAccessor",
]
