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

import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..errors.bad_request_error import BadRequestError
from ..errors.internal_server_error import InternalServerError
from ..errors.not_found_error import NotFoundError
from ..errors.not_implemented_error import NotImplementedError
from ..errors.unauthorized_error import UnauthorizedError
from ..types.error import Error
from ..types.rcs_capabilities_result import RcsCapabilitiesResult
from ..types.rcs_link_result import RcsLinkResult
from ..types.rcs_whitelist_response import RcsWhitelistResponse

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


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

    def get_capabilities(
        self, *, phone_numbers: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[RcsCapabilitiesResult]:
        """
        Check RCS capabilities for one or more phone numbers.

        This endpoint allows you to verify which RCS features (cards, buttons, etc.) are supported
        on specific phone numbers before sending RCS messages to them.

        Parameters
        ----------
        phone_numbers : typing.Sequence[str]
            List of phone numbers to check RCS capabilities for (E.164 format)

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

        Returns
        -------
        HttpResponse[RcsCapabilitiesResult]
            Returns RCS capabilities for each requested phone number.

            The response is a map where keys are phone numbers and values are either:
            - `null` if the number doesn't support RCS
            - An object containing supported cards and actions if RCS is supported
        """
        _response = self._client_wrapper.httpx_client.request(
            "rcs/capabilities",
            method="POST",
            json={
                "phoneNumbers": phone_numbers,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RcsCapabilitiesResult,
                    parse_obj_as(
                        type_=RcsCapabilitiesResult,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def whitelist(
        self, *, agent_id: str, phone_number: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[RcsWhitelistResponse]:
        """
        Whitelist a phone number for testing with your test RCS agent.

        ## Overview
        During development and testing, RCS agents can only send messages to whitelisted phone numbers.
        Use this endpoint to add test devices to your agent's whitelist before sending test messages.

        ## Verification Process
        After whitelisting a number, you'll need to complete verification:

        1. Check the test device for an "RBM Tester Management" request
        2. Accept the request on the device
        3. Enter the 4-digit verification code in the Pinnacle dashboard at:
           ```
           https://app.pinnacle.sh/dashboard/brands/{brandId}?campaignId={campaignId}&campaignType=RCS
           ```

        > **Important Notes**
        >
        > - **Testing only:** This is only required for test agents. Production agents can message any RCS-enabled number
        > - **AT&T limitation:** Whitelisting may currently fail for AT&T numbers
        > - **Verification required:** The whitelist request isn't complete until you verify the device.

        Parameters
        ----------
        agent_id : str
            The RCS agent ID (must be prefixed with 'agent_')

        phone_number : str
            Phone number to whitelist for testing (E.164 format)

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

        Returns
        -------
        HttpResponse[RcsWhitelistResponse]
            Phone number successfully whitelisted
        """
        _response = self._client_wrapper.httpx_client.request(
            "rcs/whitelist",
            method="POST",
            json={
                "agentId": agent_id,
                "phoneNumber": phone_number,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RcsWhitelistResponse,
                    parse_obj_as(
                        type_=RcsWhitelistResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_link(
        self,
        *,
        agent_id: str,
        test_mode: typing.Optional[bool] = OMIT,
        phone_number: typing.Optional[str] = OMIT,
        body: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[RcsLinkResult]:
        """
        Generate a link for initiating an RCS conversation with your agent.

        Users can click these links to start conversations with your RCS agent directly
        from websites, emails, or other applications.

        Parameters
        ----------
        agent_id : str
            The RCS agent ID (must be prefixed with 'agent_')

        test_mode : typing.Optional[bool]
            Link to the test agent or the production agent if false

        phone_number : typing.Optional[str]
            Fallback phone number (E.164 format) to use if the phone number does not support RCS. If not provided, no url will be generated.

        body : typing.Optional[str]
            Optional message body to pre-fill after the user clicks the link

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

        Returns
        -------
        HttpResponse[RcsLinkResult]
            Response containing the generated RCS service id and/or url.

            You can always create a link with the service id that is returned using the format:
            ```
            sms://{PHONE_NUMBER}?service_id={SERVICE_ID}&body={URL_ENCODED_BODY}
            ```
        """
        _response = self._client_wrapper.httpx_client.request(
            "rcs/link",
            method="POST",
            json={
                "agentId": agent_id,
                "testMode": test_mode,
                "phoneNumber": phone_number,
                "body": body,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RcsLinkResult,
                    parse_obj_as(
                        type_=RcsLinkResult,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


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

    async def get_capabilities(
        self, *, phone_numbers: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[RcsCapabilitiesResult]:
        """
        Check RCS capabilities for one or more phone numbers.

        This endpoint allows you to verify which RCS features (cards, buttons, etc.) are supported
        on specific phone numbers before sending RCS messages to them.

        Parameters
        ----------
        phone_numbers : typing.Sequence[str]
            List of phone numbers to check RCS capabilities for (E.164 format)

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

        Returns
        -------
        AsyncHttpResponse[RcsCapabilitiesResult]
            Returns RCS capabilities for each requested phone number.

            The response is a map where keys are phone numbers and values are either:
            - `null` if the number doesn't support RCS
            - An object containing supported cards and actions if RCS is supported
        """
        _response = await self._client_wrapper.httpx_client.request(
            "rcs/capabilities",
            method="POST",
            json={
                "phoneNumbers": phone_numbers,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RcsCapabilitiesResult,
                    parse_obj_as(
                        type_=RcsCapabilitiesResult,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def whitelist(
        self, *, agent_id: str, phone_number: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[RcsWhitelistResponse]:
        """
        Whitelist a phone number for testing with your test RCS agent.

        ## Overview
        During development and testing, RCS agents can only send messages to whitelisted phone numbers.
        Use this endpoint to add test devices to your agent's whitelist before sending test messages.

        ## Verification Process
        After whitelisting a number, you'll need to complete verification:

        1. Check the test device for an "RBM Tester Management" request
        2. Accept the request on the device
        3. Enter the 4-digit verification code in the Pinnacle dashboard at:
           ```
           https://app.pinnacle.sh/dashboard/brands/{brandId}?campaignId={campaignId}&campaignType=RCS
           ```

        > **Important Notes**
        >
        > - **Testing only:** This is only required for test agents. Production agents can message any RCS-enabled number
        > - **AT&T limitation:** Whitelisting may currently fail for AT&T numbers
        > - **Verification required:** The whitelist request isn't complete until you verify the device.

        Parameters
        ----------
        agent_id : str
            The RCS agent ID (must be prefixed with 'agent_')

        phone_number : str
            Phone number to whitelist for testing (E.164 format)

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

        Returns
        -------
        AsyncHttpResponse[RcsWhitelistResponse]
            Phone number successfully whitelisted
        """
        _response = await self._client_wrapper.httpx_client.request(
            "rcs/whitelist",
            method="POST",
            json={
                "agentId": agent_id,
                "phoneNumber": phone_number,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RcsWhitelistResponse,
                    parse_obj_as(
                        type_=RcsWhitelistResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_link(
        self,
        *,
        agent_id: str,
        test_mode: typing.Optional[bool] = OMIT,
        phone_number: typing.Optional[str] = OMIT,
        body: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[RcsLinkResult]:
        """
        Generate a link for initiating an RCS conversation with your agent.

        Users can click these links to start conversations with your RCS agent directly
        from websites, emails, or other applications.

        Parameters
        ----------
        agent_id : str
            The RCS agent ID (must be prefixed with 'agent_')

        test_mode : typing.Optional[bool]
            Link to the test agent or the production agent if false

        phone_number : typing.Optional[str]
            Fallback phone number (E.164 format) to use if the phone number does not support RCS. If not provided, no url will be generated.

        body : typing.Optional[str]
            Optional message body to pre-fill after the user clicks the link

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

        Returns
        -------
        AsyncHttpResponse[RcsLinkResult]
            Response containing the generated RCS service id and/or url.

            You can always create a link with the service id that is returned using the format:
            ```
            sms://{PHONE_NUMBER}?service_id={SERVICE_ID}&body={URL_ENCODED_BODY}
            ```
        """
        _response = await self._client_wrapper.httpx_client.request(
            "rcs/link",
            method="POST",
            json={
                "agentId": agent_id,
                "testMode": test_mode,
                "phoneNumber": phone_number,
                "body": body,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RcsLinkResult,
                    parse_obj_as(
                        type_=RcsLinkResult,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
