"""
Fluent accessor classes for Vendor resources.

Auto-generated from OpenAPI specification.
"""

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

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

if TYPE_CHECKING:
    from ..client import AsyncCredoAI, CredoAI


# =============================================================================
# Vendor Fluent Accessors (Sync)
# =============================================================================


class VendorQuestionnairesAccessor:
    """Manage questionnaires for a specific vendor.

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

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

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

        Args:
            client: The CredoAI client instance
            vendor_id: The ID of the parent vendor
        """
        self._client = client
        self._vendor_id = vendor_id

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

        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"/vendors/{self._vendor_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 vendor.

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

        Returns:
            QuestionnaireAttachmentResponse: The added questionnaire

        Examples:
            >>> # Using request model directly
            >>> vendor.questionnaires.add(QuestionnaireAttachment(...))
            >>> # Using a fetched response object (extracts matching fields)
            >>> fetched = client.questionnaires.get("id")
            >>> vendor.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"/vendors/{self._vendor_id}/questionnaires",
            data=data,
            response_model=QuestionnaireAttachmentResponse,
        )

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

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


class VendorUseCasesAccessor:
    """Manage use_cases for a specific vendor.

    This accessor provides methods to add, list, remove
    use_cases associated with a vendor.

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

    def __init__(self, client: "CredoAI", vendor_id: str):
        """Initialize the use_cases accessor.

        Args:
            client: The CredoAI client instance
            vendor_id: The ID of the parent vendor
        """
        self._client = client
        self._vendor_id = vendor_id

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

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

        Returns:
            PaginatedResponse containing UseCaseResponse 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"/vendors/{self._vendor_id}/use_cases",
            params=params if params else None,
            response_model=PaginatedResponse[UseCaseResponse],
        )

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

        Args:
            use_case: The use_case ID as a string, or a UseCaseResponse object

        Returns:
            UseCaseResponse: The added use_case

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

        return self._client._make_request(
            method="POST",
            url=f"/vendors/{self._vendor_id}/use_cases",
            data={"id": use_case_id},
            response_model=UseCaseResponse,
        )

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

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


class VendorModelsAccessor:
    """Manage models for a specific vendor.

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

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

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

        Args:
            client: The CredoAI client instance
            vendor_id: The ID of the parent vendor
        """
        self._client = client
        self._vendor_id = vendor_id

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

        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"/vendors/{self._vendor_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 vendor.

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

        Returns:
            ModelResponse: The added model

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

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

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

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


class Vendor:
    """Fluent accessor for a specific vendor.

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

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

    def __init__(self, client: "CredoAI", vendor_id: str):
        """Initialize the vendor accessor.

        Args:
            client: The CredoAI client instance
            vendor_id: The ID of the vendor
        """
        self._client = client
        self._vendor_id = vendor_id

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

        Returns:
            VendorQuestionnairesAccessor: Accessor for questionnaires operations
        """
        return VendorQuestionnairesAccessor(self._client, self._vendor_id)

    @property
    def use_cases(self) -> "VendorUseCasesAccessor":
        """Access use_cases associated with this vendor.

        Returns:
            VendorUseCasesAccessor: Accessor for use_cases operations
        """
        return VendorUseCasesAccessor(self._client, self._vendor_id)

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

        Returns:
            VendorModelsAccessor: Accessor for models operations
        """
        return VendorModelsAccessor(self._client, self._vendor_id)


# =============================================================================
# Vendor Fluent Accessors (Async)
# =============================================================================


class AsyncVendorQuestionnairesAccessor:
    """Async manage questionnaires for a specific vendor.

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

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

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

        Args:
            client: The AsyncCredoAI client instance
            vendor_id: The ID of the parent vendor
        """
        self._client = client
        self._vendor_id = vendor_id

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

        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"/vendors/{self._vendor_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 vendor.

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

        Returns:
            QuestionnaireAttachmentResponse: The added questionnaire

        Examples:
            >>> # Using request model directly
            >>> vendor.questionnaires.add(QuestionnaireAttachment(...))
            >>> # Using a fetched response object (extracts matching fields)
            >>> fetched = client.questionnaires.get("id")
            >>> vendor.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"/vendors/{self._vendor_id}/questionnaires",
            data=data,
            response_model=QuestionnaireAttachmentResponse,
        )

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

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


class AsyncVendorUseCasesAccessor:
    """Async manage use_cases for a specific vendor.

    This accessor provides async methods to add, list, remove
    use_cases associated with a vendor.

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

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

        Args:
            client: The AsyncCredoAI client instance
            vendor_id: The ID of the parent vendor
        """
        self._client = client
        self._vendor_id = vendor_id

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

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

        Returns:
            PaginatedResponse containing UseCaseResponse 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"/vendors/{self._vendor_id}/use_cases",
            params=params if params else None,
            response_model=PaginatedResponse[UseCaseResponse],
        )

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

        Args:
            use_case: The use_case ID as a string, or a UseCaseResponse object

        Returns:
            UseCaseResponse: The added use_case

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

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

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

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


class AsyncVendorModelsAccessor:
    """Async manage models for a specific vendor.

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

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

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

        Args:
            client: The AsyncCredoAI client instance
            vendor_id: The ID of the parent vendor
        """
        self._client = client
        self._vendor_id = vendor_id

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

        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"/vendors/{self._vendor_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 vendor.

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

        Returns:
            ModelResponse: The added model

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

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

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

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


class AsyncVendor:
    """Async fluent accessor for a specific vendor.

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

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

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

        Args:
            client: The AsyncCredoAI client instance
            vendor_id: The ID of the vendor
        """
        self._client = client
        self._vendor_id = vendor_id

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

        Returns:
            AsyncVendorQuestionnairesAccessor: Async accessor for questionnaires operations
        """
        return AsyncVendorQuestionnairesAccessor(self._client, self._vendor_id)

    @property
    def use_cases(self) -> "AsyncVendorUseCasesAccessor":
        """Access use_cases associated with this vendor.

        Returns:
            AsyncVendorUseCasesAccessor: Async accessor for use_cases operations
        """
        return AsyncVendorUseCasesAccessor(self._client, self._vendor_id)

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

        Returns:
            AsyncVendorModelsAccessor: Async accessor for models operations
        """
        return AsyncVendorModelsAccessor(self._client, self._vendor_id)


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

__all__ = [
    "Vendor",
    "AsyncVendor",
    "VendorQuestionnairesAccessor",
    "AsyncVendorQuestionnairesAccessor",
    "VendorUseCasesAccessor",
    "AsyncVendorUseCasesAccessor",
    "VendorModelsAccessor",
    "AsyncVendorModelsAccessor",
]
