# 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.parse_error import ParsingError
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..errors.bad_request_error import BadRequestError
from ..errors.forbidden_error import ForbiddenError
from ..errors.not_found_error import NotFoundError
from ..errors.too_many_requests_error import TooManyRequestsError
from ..errors.unauthorized_error import UnauthorizedError
from ..types.change_password_ticket_identity import ChangePasswordTicketIdentity
from ..types.change_password_ticket_response_content import ChangePasswordTicketResponseContent
from ..types.identity import Identity
from ..types.verify_email_ticket_response_content import VerifyEmailTicketResponseContent
from pydantic import ValidationError

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


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

    def verify_email(
        self,
        *,
        user_id: str,
        result_url: typing.Optional[str] = OMIT,
        client_id: typing.Optional[str] = OMIT,
        organization_id: typing.Optional[str] = OMIT,
        ttl_sec: typing.Optional[int] = OMIT,
        include_email_in_redirect: typing.Optional[bool] = OMIT,
        identity: typing.Optional[Identity] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[VerifyEmailTicketResponseContent]:
        """
        Create an email verification ticket for a given user. An email verification ticket is a generated URL that the user can consume to verify their email address.

        Parameters
        ----------
        user_id : str
            user_id of for whom the ticket should be created.

        result_url : typing.Optional[str]
            URL the user will be redirected to in the classic Universal Login experience once the ticket is used. Cannot be specified when using client_id or organization_id.

        client_id : typing.Optional[str]
            ID of the client (application). If provided for tenants using the New Universal Login experience, the email template and UI displays application details, and the user is prompted to redirect to the application's <a target='' href='https://auth0.com/docs/authenticate/login/auth0-universal-login/configure-default-login-routes#completing-the-password-reset-flow'>default login route</a> after the ticket is used. client_id is required to use the <a target='' href='https://auth0.com/docs/customize/actions/flows-and-triggers/post-change-password-flow'>Password Reset Post Challenge</a> trigger.

        organization_id : typing.Optional[str]
            (Optional) Organization ID – the ID of the Organization. If provided, organization parameters will be made available to the email template and organization branding will be applied to the prompt. In addition, the redirect link in the prompt will include organization_id and organization_name query string parameters.

        ttl_sec : typing.Optional[int]
            Number of seconds for which the ticket is valid before expiration. If unspecified or set to 0, this value defaults to 432000 seconds (5 days).

        include_email_in_redirect : typing.Optional[bool]
            Whether to include the email address as part of the returnUrl in the reset_email (true), or not (false).

        identity : typing.Optional[Identity]

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

        Returns
        -------
        HttpResponse[VerifyEmailTicketResponseContent]
            Ticket successfully created.
        """
        _response = self._client_wrapper.httpx_client.request(
            "tickets/email-verification",
            method="POST",
            json={
                "result_url": result_url,
                "user_id": user_id,
                "client_id": client_id,
                "organization_id": organization_id,
                "ttl_sec": ttl_sec,
                "includeEmailInRedirect": include_email_in_redirect,
                "identity": convert_and_respect_annotation_metadata(
                    object_=identity, annotation=Identity, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    VerifyEmailTicketResponseContent,
                    parse_obj_as(
                        type_=VerifyEmailTicketResponseContent,  # 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.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # 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)
        except ValidationError as e:
            raise ParsingError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
            )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def change_password(
        self,
        *,
        result_url: typing.Optional[str] = OMIT,
        user_id: typing.Optional[str] = OMIT,
        client_id: typing.Optional[str] = OMIT,
        organization_id: typing.Optional[str] = OMIT,
        connection_id: typing.Optional[str] = OMIT,
        email: typing.Optional[str] = OMIT,
        ttl_sec: typing.Optional[int] = OMIT,
        mark_email_as_verified: typing.Optional[bool] = OMIT,
        include_email_in_redirect: typing.Optional[bool] = OMIT,
        identity: typing.Optional[ChangePasswordTicketIdentity] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ChangePasswordTicketResponseContent]:
        """
        Create a password change ticket for a given user. A password change ticket is a generated URL that the user can consume to start a reset password flow.

        Note: This endpoint does not verify the given user’s identity. If you call this endpoint within your application, you must design your application to verify the user’s identity.

        Parameters
        ----------
        result_url : typing.Optional[str]
            URL the user will be redirected to in the classic Universal Login experience once the ticket is used. Cannot be specified when using organization_id. May be specified together with client_id when the tenant has a custom password reset page enabled and a password-reset-post-challenge Action bound.

        user_id : typing.Optional[str]
            user_id of for whom the ticket should be created.

        client_id : typing.Optional[str]
            ID of the client (application). If provided for tenants using the New Universal Login experience, the email template and UI displays application details, and the user is prompted to redirect to the application's <a target='' href='https://auth0.com/docs/authenticate/login/auth0-universal-login/configure-default-login-routes#completing-the-password-reset-flow'>default login route</a> after the ticket is used. client_id is required to use the <a target='' href='https://auth0.com/docs/customize/actions/flows-and-triggers/post-change-password-flow'>Password Reset Post Challenge</a> trigger.

        organization_id : typing.Optional[str]
            (Optional) Organization ID – the ID of the Organization. If provided, organization parameters will be made available to the email template and organization branding will be applied to the prompt. In addition, the redirect link in the prompt will include organization_id and organization_name query string parameters.

        connection_id : typing.Optional[str]
            ID of the connection. If provided, allows the user to be specified using email instead of user_id. If you set this value, you must also send the email parameter. You cannot send user_id when specifying a connection_id.

        email : typing.Optional[str]
            Email address of the user for whom the tickets should be created. Requires the connection_id parameter. Cannot be specified when using user_id.

        ttl_sec : typing.Optional[int]
            Number of seconds for which the ticket is valid before expiration. If unspecified or set to 0, this value defaults to 432000 seconds (5 days).

        mark_email_as_verified : typing.Optional[bool]
            Whether to set the email_verified attribute to true (true) or whether it should not be updated (false).

        include_email_in_redirect : typing.Optional[bool]
            Whether to include the email address as part of the returnUrl in the reset_email (true), or not (false).

        identity : typing.Optional[ChangePasswordTicketIdentity]

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

        Returns
        -------
        HttpResponse[ChangePasswordTicketResponseContent]
            Ticket successfully created.
        """
        _response = self._client_wrapper.httpx_client.request(
            "tickets/password-change",
            method="POST",
            json={
                "result_url": result_url,
                "user_id": user_id,
                "client_id": client_id,
                "organization_id": organization_id,
                "connection_id": connection_id,
                "email": email,
                "ttl_sec": ttl_sec,
                "mark_email_as_verified": mark_email_as_verified,
                "includeEmailInRedirect": include_email_in_redirect,
                "identity": convert_and_respect_annotation_metadata(
                    object_=identity, annotation=ChangePasswordTicketIdentity, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ChangePasswordTicketResponseContent,
                    parse_obj_as(
                        type_=ChangePasswordTicketResponseContent,  # 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.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # 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)
        except ValidationError as e:
            raise ParsingError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
            )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


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

    async def verify_email(
        self,
        *,
        user_id: str,
        result_url: typing.Optional[str] = OMIT,
        client_id: typing.Optional[str] = OMIT,
        organization_id: typing.Optional[str] = OMIT,
        ttl_sec: typing.Optional[int] = OMIT,
        include_email_in_redirect: typing.Optional[bool] = OMIT,
        identity: typing.Optional[Identity] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[VerifyEmailTicketResponseContent]:
        """
        Create an email verification ticket for a given user. An email verification ticket is a generated URL that the user can consume to verify their email address.

        Parameters
        ----------
        user_id : str
            user_id of for whom the ticket should be created.

        result_url : typing.Optional[str]
            URL the user will be redirected to in the classic Universal Login experience once the ticket is used. Cannot be specified when using client_id or organization_id.

        client_id : typing.Optional[str]
            ID of the client (application). If provided for tenants using the New Universal Login experience, the email template and UI displays application details, and the user is prompted to redirect to the application's <a target='' href='https://auth0.com/docs/authenticate/login/auth0-universal-login/configure-default-login-routes#completing-the-password-reset-flow'>default login route</a> after the ticket is used. client_id is required to use the <a target='' href='https://auth0.com/docs/customize/actions/flows-and-triggers/post-change-password-flow'>Password Reset Post Challenge</a> trigger.

        organization_id : typing.Optional[str]
            (Optional) Organization ID – the ID of the Organization. If provided, organization parameters will be made available to the email template and organization branding will be applied to the prompt. In addition, the redirect link in the prompt will include organization_id and organization_name query string parameters.

        ttl_sec : typing.Optional[int]
            Number of seconds for which the ticket is valid before expiration. If unspecified or set to 0, this value defaults to 432000 seconds (5 days).

        include_email_in_redirect : typing.Optional[bool]
            Whether to include the email address as part of the returnUrl in the reset_email (true), or not (false).

        identity : typing.Optional[Identity]

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

        Returns
        -------
        AsyncHttpResponse[VerifyEmailTicketResponseContent]
            Ticket successfully created.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "tickets/email-verification",
            method="POST",
            json={
                "result_url": result_url,
                "user_id": user_id,
                "client_id": client_id,
                "organization_id": organization_id,
                "ttl_sec": ttl_sec,
                "includeEmailInRedirect": include_email_in_redirect,
                "identity": convert_and_respect_annotation_metadata(
                    object_=identity, annotation=Identity, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    VerifyEmailTicketResponseContent,
                    parse_obj_as(
                        type_=VerifyEmailTicketResponseContent,  # 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.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # 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)
        except ValidationError as e:
            raise ParsingError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
            )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def change_password(
        self,
        *,
        result_url: typing.Optional[str] = OMIT,
        user_id: typing.Optional[str] = OMIT,
        client_id: typing.Optional[str] = OMIT,
        organization_id: typing.Optional[str] = OMIT,
        connection_id: typing.Optional[str] = OMIT,
        email: typing.Optional[str] = OMIT,
        ttl_sec: typing.Optional[int] = OMIT,
        mark_email_as_verified: typing.Optional[bool] = OMIT,
        include_email_in_redirect: typing.Optional[bool] = OMIT,
        identity: typing.Optional[ChangePasswordTicketIdentity] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ChangePasswordTicketResponseContent]:
        """
        Create a password change ticket for a given user. A password change ticket is a generated URL that the user can consume to start a reset password flow.

        Note: This endpoint does not verify the given user’s identity. If you call this endpoint within your application, you must design your application to verify the user’s identity.

        Parameters
        ----------
        result_url : typing.Optional[str]
            URL the user will be redirected to in the classic Universal Login experience once the ticket is used. Cannot be specified when using organization_id. May be specified together with client_id when the tenant has a custom password reset page enabled and a password-reset-post-challenge Action bound.

        user_id : typing.Optional[str]
            user_id of for whom the ticket should be created.

        client_id : typing.Optional[str]
            ID of the client (application). If provided for tenants using the New Universal Login experience, the email template and UI displays application details, and the user is prompted to redirect to the application's <a target='' href='https://auth0.com/docs/authenticate/login/auth0-universal-login/configure-default-login-routes#completing-the-password-reset-flow'>default login route</a> after the ticket is used. client_id is required to use the <a target='' href='https://auth0.com/docs/customize/actions/flows-and-triggers/post-change-password-flow'>Password Reset Post Challenge</a> trigger.

        organization_id : typing.Optional[str]
            (Optional) Organization ID – the ID of the Organization. If provided, organization parameters will be made available to the email template and organization branding will be applied to the prompt. In addition, the redirect link in the prompt will include organization_id and organization_name query string parameters.

        connection_id : typing.Optional[str]
            ID of the connection. If provided, allows the user to be specified using email instead of user_id. If you set this value, you must also send the email parameter. You cannot send user_id when specifying a connection_id.

        email : typing.Optional[str]
            Email address of the user for whom the tickets should be created. Requires the connection_id parameter. Cannot be specified when using user_id.

        ttl_sec : typing.Optional[int]
            Number of seconds for which the ticket is valid before expiration. If unspecified or set to 0, this value defaults to 432000 seconds (5 days).

        mark_email_as_verified : typing.Optional[bool]
            Whether to set the email_verified attribute to true (true) or whether it should not be updated (false).

        include_email_in_redirect : typing.Optional[bool]
            Whether to include the email address as part of the returnUrl in the reset_email (true), or not (false).

        identity : typing.Optional[ChangePasswordTicketIdentity]

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

        Returns
        -------
        AsyncHttpResponse[ChangePasswordTicketResponseContent]
            Ticket successfully created.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "tickets/password-change",
            method="POST",
            json={
                "result_url": result_url,
                "user_id": user_id,
                "client_id": client_id,
                "organization_id": organization_id,
                "connection_id": connection_id,
                "email": email,
                "ttl_sec": ttl_sec,
                "mark_email_as_verified": mark_email_as_verified,
                "includeEmailInRedirect": include_email_in_redirect,
                "identity": convert_and_respect_annotation_metadata(
                    object_=identity, annotation=ChangePasswordTicketIdentity, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ChangePasswordTicketResponseContent,
                    parse_obj_as(
                        type_=ChangePasswordTicketResponseContent,  # 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.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # 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)
        except ValidationError as e:
            raise ParsingError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
            )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
