# !!!
# WARNING: This file is autogenerated
# Only modify code within MANUAL() sections
# or your changes may be overwritten later!
# !!!

from typing import Any, Dict, Optional

from stytch.core.api_base import ApiBase
from stytch.core.http.client import AsyncClient, SyncClient
from stytch.models.otp_whatsapp import LoginOrCreateResponse, SendResponse


class Whatsapp:
    def __init__(
        self,
        api_base: ApiBase,
        sync_client: SyncClient,
        async_client: AsyncClient,
    ) -> None:
        self.api_base = api_base
        self.sync_client = sync_client
        self.async_client = async_client

    @property
    def sub_url(self) -> str:
        return "otps/whatsapp"

    def send(
        self,
        phone_number: str,
        expiration_minutes: Optional[int] = None,
        attributes: Optional[Dict[str, str]] = None,
        locale: Optional[str] = None,
        user_id: Optional[str] = None,
        session_token: Optional[str] = None,
        session_jwt: Optional[str] = None,
    ) -> SendResponse:
        """[Stytch docs](https://stytch.com/docs/api/whatsapp-send)

        Send a one-time passcode to a user's WhatsApp using their phone number. If you'd like to create a user and send them a passcode with one request, use our [log in or create endpoint](https://stytch.com/docs/api/whatsapp-login-or-create).

        Note that sending another OTP code before the first has expired will invalidate the first code.

        ## Add a phone number to an existing user

        This endpoint also allows you to add a new phone number to an existing Stytch User. Including a `user_id`, `session_token`, or `session_jwt` in the request will add the phone number to the pre-existing Stytch User upon successful authentication.

        Adding a new phone number to an existing Stytch User requires the user to be present and validate the phone number via OTP. This requirement is in place to prevent account takeover attacks.
        """  # noqa

        payload: Dict[str, Any] = {
            "phone_number": phone_number,
        }

        if expiration_minutes is not None:
            payload["expiration_minutes"] = expiration_minutes
        if attributes is not None:
            payload["attributes"] = attributes
        if locale is not None:
            payload["locale"] = locale
        if user_id is not None:
            payload["user_id"] = user_id
        if session_token is not None:
            payload["session_token"] = session_token
        if session_jwt is not None:
            payload["session_jwt"] = session_jwt

        url = self.api_base.route_with_sub_url(self.sub_url, "send")

        res = self.sync_client.post(url, json=payload)
        return SendResponse.from_json(res.response.status_code, res.json)

    async def send_async(
        self,
        phone_number: str,
        expiration_minutes: Optional[int] = None,
        attributes: Optional[Dict[str, str]] = None,
        locale: Optional[str] = None,
        user_id: Optional[str] = None,
        session_token: Optional[str] = None,
        session_jwt: Optional[str] = None,
    ) -> SendResponse:
        """[Stytch docs](https://stytch.com/docs/api/whatsapp-send)

        Send a one-time passcode to a user's WhatsApp using their phone number. If you'd like to create a user and send them a passcode with one request, use our [log in or create endpoint](https://stytch.com/docs/api/whatsapp-login-or-create).

        Note that sending another OTP code before the first has expired will invalidate the first code.

        ## Add a phone number to an existing user

        This endpoint also allows you to add a new phone number to an existing Stytch User. Including a `user_id`, `session_token`, or `session_jwt` in the request will add the phone number to the pre-existing Stytch User upon successful authentication.

        Adding a new phone number to an existing Stytch User requires the user to be present and validate the phone number via OTP. This requirement is in place to prevent account takeover attacks.
        """  # noqa

        payload: Dict[str, Any] = {
            "phone_number": phone_number,
        }

        if expiration_minutes is not None:
            payload["expiration_minutes"] = expiration_minutes
        if attributes is not None:
            payload["attributes"] = attributes
        if locale is not None:
            payload["locale"] = locale
        if user_id is not None:
            payload["user_id"] = user_id
        if session_token is not None:
            payload["session_token"] = session_token
        if session_jwt is not None:
            payload["session_jwt"] = session_jwt

        url = self.api_base.route_with_sub_url(self.sub_url, "send")

        res = await self.async_client.post(url, json=payload)
        return SendResponse.from_json(res.response.status, res.json)

    def login_or_create(
        self,
        phone_number: str,
        expiration_minutes: Optional[int] = None,
        attributes: Optional[Dict[str, str]] = None,
        create_user_as_pending: bool = False,
        locale: Optional[str] = None,
    ) -> LoginOrCreateResponse:
        """[Stytch docs](https://stytch.com/docs/api/whatsapp-login-or-create)

        Send a one-time passcode to a user's WhatsApp using their phone number. If the phone number is not associated with a user already, a user will be created.
        """  # noqa

        payload: Dict[str, Any] = {
            "phone_number": phone_number,
            "create_user_as_pending": create_user_as_pending,
        }

        if expiration_minutes is not None:
            payload["expiration_minutes"] = expiration_minutes
        if attributes is not None:
            payload["attributes"] = attributes
        if locale is not None:
            payload["locale"] = locale

        url = self.api_base.route_with_sub_url(self.sub_url, "login_or_create")

        res = self.sync_client.post(url, json=payload)
        return LoginOrCreateResponse.from_json(res.response.status_code, res.json)

    async def login_or_create_async(
        self,
        phone_number: str,
        expiration_minutes: Optional[int] = None,
        attributes: Optional[Dict[str, str]] = None,
        create_user_as_pending: bool = False,
        locale: Optional[str] = None,
    ) -> LoginOrCreateResponse:
        """[Stytch docs](https://stytch.com/docs/api/whatsapp-login-or-create)

        Send a one-time passcode to a user's WhatsApp using their phone number. If the phone number is not associated with a user already, a user will be created.
        """  # noqa

        payload: Dict[str, Any] = {
            "phone_number": phone_number,
            "create_user_as_pending": create_user_as_pending,
        }

        if expiration_minutes is not None:
            payload["expiration_minutes"] = expiration_minutes
        if attributes is not None:
            payload["attributes"] = attributes
        if locale is not None:
            payload["locale"] = locale

        url = self.api_base.route_with_sub_url(self.sub_url, "login_or_create")

        res = await self.async_client.post(url, json=payload)
        return LoginOrCreateResponse.from_json(res.response.status, res.json)
