# This file was auto-generated by Fern from our API Definition.

import typing
import urllib.parse
import uuid
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import pydantic_v1
from ..core.query_encoder import encode_query
from ..core.remove_none_from_dict import remove_none_from_dict
from ..core.request_options import RequestOptions
from .types.create_conversation_response import CreateConversationResponse
from .types.send_agent_message_response import SendAgentMessageResponse

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class CopilotsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def create_conversation(
        self, *, user_email: str, request_options: typing.Optional[RequestOptions] = None
    ) -> CreateConversationResponse:
        """
        OPTIONAL. Create a new conversation with the Copilot. The conversation ID can be used in the sendMessage endpoint. The sendMessage endpoint automatically creates new conversations upon first request, but calling this endpoint can simplify certain use cases where it is helpful for the application to have the conversation ID before the first message is sent.

        Parameters
        ----------
        user_email : str
            End-user for the conversation.


        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        CreateConversationResponse

        Examples
        --------
        from credal.client import CredalApi

        client = CredalApi(
            api_key="YOUR_API_KEY",
        )
        client.copilots.create_conversation(
            user_email="ravin@credal.ai",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            method="POST",
            url=urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v0/copilots/createConversation"),
            params=encode_query(
                jsonable_encoder(
                    request_options.get("additional_query_parameters") if request_options is not None else None
                )
            ),
            json=jsonable_encoder({"userEmail": user_email})
            if request_options is None or request_options.get("additional_body_parameters") is None
            else {
                **jsonable_encoder({"userEmail": user_email}),
                **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))),
            },
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(CreateConversationResponse, _response.json())  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def send_message(
        self,
        *,
        message: str,
        user_email: str,
        conversation_id: typing.Optional[uuid.UUID] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SendAgentMessageResponse:
        """
        Parameters
        ----------
        message : str
            The message you want to send to your copilot.


        user_email : str
            The user profile you want to use when sending the message.


        conversation_id : typing.Optional[uuid.UUID]
            Credal-generated conversation ID for sending follow up messages. Conversation ID is returned after initial message. Optional, to be left off for first messages on new conversations.


        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        SendAgentMessageResponse

        Examples
        --------
        from credal.client import CredalApi

        client = CredalApi(
            api_key="YOUR_API_KEY",
        )
        client.copilots.send_message(
            message="Is Credal SOC 2 compliant?",
            user_email="ravin@credal.ai",
        )
        """
        _request: typing.Dict[str, typing.Any] = {"message": message, "userEmail": user_email}
        if conversation_id is not OMIT:
            _request["conversationId"] = conversation_id
        _response = self._client_wrapper.httpx_client.request(
            method="POST",
            url=urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v0/copilots/sendMessage"),
            params=encode_query(
                jsonable_encoder(
                    request_options.get("additional_query_parameters") if request_options is not None else None
                )
            ),
            json=jsonable_encoder(_request)
            if request_options is None or request_options.get("additional_body_parameters") is None
            else {
                **jsonable_encoder(_request),
                **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))),
            },
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(SendAgentMessageResponse, _response.json())  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncCopilotsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create_conversation(
        self, *, user_email: str, request_options: typing.Optional[RequestOptions] = None
    ) -> CreateConversationResponse:
        """
        OPTIONAL. Create a new conversation with the Copilot. The conversation ID can be used in the sendMessage endpoint. The sendMessage endpoint automatically creates new conversations upon first request, but calling this endpoint can simplify certain use cases where it is helpful for the application to have the conversation ID before the first message is sent.

        Parameters
        ----------
        user_email : str
            End-user for the conversation.


        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        CreateConversationResponse

        Examples
        --------
        from credal.client import AsyncCredalApi

        client = AsyncCredalApi(
            api_key="YOUR_API_KEY",
        )
        await client.copilots.create_conversation(
            user_email="ravin@credal.ai",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            method="POST",
            url=urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v0/copilots/createConversation"),
            params=encode_query(
                jsonable_encoder(
                    request_options.get("additional_query_parameters") if request_options is not None else None
                )
            ),
            json=jsonable_encoder({"userEmail": user_email})
            if request_options is None or request_options.get("additional_body_parameters") is None
            else {
                **jsonable_encoder({"userEmail": user_email}),
                **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))),
            },
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(CreateConversationResponse, _response.json())  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def send_message(
        self,
        *,
        message: str,
        user_email: str,
        conversation_id: typing.Optional[uuid.UUID] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SendAgentMessageResponse:
        """
        Parameters
        ----------
        message : str
            The message you want to send to your copilot.


        user_email : str
            The user profile you want to use when sending the message.


        conversation_id : typing.Optional[uuid.UUID]
            Credal-generated conversation ID for sending follow up messages. Conversation ID is returned after initial message. Optional, to be left off for first messages on new conversations.


        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        SendAgentMessageResponse

        Examples
        --------
        from credal.client import AsyncCredalApi

        client = AsyncCredalApi(
            api_key="YOUR_API_KEY",
        )
        await client.copilots.send_message(
            message="Is Credal SOC 2 compliant?",
            user_email="ravin@credal.ai",
        )
        """
        _request: typing.Dict[str, typing.Any] = {"message": message, "userEmail": user_email}
        if conversation_id is not OMIT:
            _request["conversationId"] = conversation_id
        _response = await self._client_wrapper.httpx_client.request(
            method="POST",
            url=urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v0/copilots/sendMessage"),
            params=encode_query(
                jsonable_encoder(
                    request_options.get("additional_query_parameters") if request_options is not None else None
                )
            ),
            json=jsonable_encoder(_request)
            if request_options is None or request_options.get("additional_body_parameters") is None
            else {
                **jsonable_encoder(_request),
                **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))),
            },
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(SendAgentMessageResponse, _response.json())  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
