# !!!
# 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.api.magic_links_email import Email
from stytch.core.api_base import ApiBase
from stytch.core.http.client import AsyncClient, SyncClient
from stytch.models.magic_links import AuthenticateResponse, CreateResponse


class MagicLinks:
    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
        self.email = Email(api_base, sync_client, async_client)

    @property
    def sub_url(self) -> str:
        return "magic_links"

    def create(
        self,
        user_id: str,
        expiration_minutes: Optional[int] = None,
        attributes: Optional[Dict[str, str]] = None,
    ) -> CreateResponse:
        """[Stytch docs](https://stytch.com/docs/api/create-magic-link)

        Create a magic link token for a user. Access to this endpoint is restricted, to be enabled for it, please send us a note at support@stytch.com.

        Parameters:

        - `user_id`: The user ID for the magic link token.

        - `expiration_minutes`: Set the expiration for the magic token, in minutes. By default, it expires in 1 hour. The minimum expiration is 5 minutes and the maximum is 7 days (10080 mins).

        - `attributes`: Provided attributes help with fraud detection. When authenticating a user's magic link token, you can require the IP address and/or the user agent to match that user's attributes when they originated the initial authentication request. To enable this functionality, you can use the options parameter in [AuthenticateMagic](https://stytch.com/docs/api/authenticate-magic-link).
        """  # noqa

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

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

        url = self.api_base.route_with_sub_url(self.sub_url, None)

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

    async def create_async(
        self,
        user_id: str,
        expiration_minutes: Optional[int] = None,
        attributes: Optional[Dict[str, str]] = None,
    ) -> CreateResponse:
        """[Stytch docs](https://stytch.com/docs/api/create-magic-link)

        Create a magic link token for a user. Access to this endpoint is restricted, to be enabled for it, please send us a note at support@stytch.com.

        Parameters:

        - `user_id`: The user ID for the magic link token.

        - `expiration_minutes`: Set the expiration for the magic token, in minutes. By default, it expires in 1 hour. The minimum expiration is 5 minutes and the maximum is 7 days (10080 mins).

        - `attributes`: Provided attributes help with fraud detection. When authenticating a user's magic link token, you can require the IP address and/or the user agent to match that user's attributes when they originated the initial authentication request. To enable this functionality, you can use the options parameter in [AuthenticateMagic](https://stytch.com/docs/api/authenticate-magic-link).
        """  # noqa

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

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

        url = self.api_base.route_with_sub_url(self.sub_url, None)

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

    def authenticate(
        self,
        token: str,
        attributes: Optional[Dict[str, str]] = None,
        options: Optional[Dict[str, str]] = None,
        session_token: Optional[str] = None,
        session_jwt: Optional[str] = None,
        session_duration_minutes: Optional[int] = None,
        session_custom_claims: Optional[Dict[str, Any]] = None,
        code_verifier: Optional[str] = None,
    ) -> AuthenticateResponse:
        """[Stytch docs](https://stytch.com/docs/api/authenticate-magic-link)

        Authenticate a user given a magic link. This endpoint verifies that the magic link `token` is valid, hasn't expired or been previously used, and any optional security settings such as IP match or user agent match are satisfied.

        Parameters:

        - `token`: The token to authenticate.

        - `options`: Specify optional security settings

        - `attributes`: Provided attributes help with fraud detection. You can require the IP address and/or the user agent to match the request used to send the magic link using the options parameter.

        - `session_duration_minutes`: Set the session lifetime to be this many minutes from now. This will start a new session if one doesn't already exist, returning both an opaque `session_token` and `session_jwt` for this session. Remember that the `session_jwt` will have a fixed lifetime of five minutes regardless of the underlying session duration, and will need to be refreshed over time.

          This value must be a minimum of 5 and a maximum of 129600 minutes (90 days).

          If a `session_token` or `session_jwt` is provided then a successful authentication will continue to extend the session this many minutes.

          If the `session_duration_minutes` parameter is not specified, a Stytch session will not be created.

        - `session_custom_claims`: Add a custom claims map to the session being authenticated. Claims are only created if a session is initialized by providing a value in `session_duration_minutes`. Claims will be included on the session object and in the JWT. To update a key in an existing session, supply a new value. To delete a key, supply a null value

          Custom claims made with reserved claims ("iss", "sub", "aud", "exp", "nbf", "iat", "jti") will be ignored. Total custom claims size cannot exceed four kilobytes

        - `session_jwt`: Reuse an existing session instead of creating a new one. If you provide us with a `session_jwt`, then we'll update the session represented by this JWT with this magic link factor. If this `session_jwt` belongs to a different user than the magic token, the `session_jwt` will be ignored. This endpoint will error if both `session_token` and `session_jwt` are provided.

        - `session_token`: Reuse an existing session instead of creating a new one. If you provide us with a `session_token`, then we'll update the session represented by this session token with this magic link factor. If this `session_token` belongs to a different user than the magic token, the `session_token` will be ignored. This endpoint will error if both `session_token` and `session_jwt` are provided.

        - `code_verifier`: A base64url encoded one time secret used to validate that the request starts and ends on the same device.
        """  # noqa

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

        if attributes is not None:
            payload["attributes"] = attributes
        if options is not None:
            payload["options"] = options
        if session_token is not None:
            payload["session_token"] = session_token
        if session_jwt is not None:
            payload["session_jwt"] = session_jwt
        if session_duration_minutes is not None:
            payload["session_duration_minutes"] = session_duration_minutes
        if session_custom_claims is not None:
            payload["session_custom_claims"] = session_custom_claims
        if code_verifier is not None:
            payload["code_verifier"] = code_verifier

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

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

    async def authenticate_async(
        self,
        token: str,
        attributes: Optional[Dict[str, str]] = None,
        options: Optional[Dict[str, str]] = None,
        session_token: Optional[str] = None,
        session_jwt: Optional[str] = None,
        session_duration_minutes: Optional[int] = None,
        session_custom_claims: Optional[Dict[str, Any]] = None,
        code_verifier: Optional[str] = None,
    ) -> AuthenticateResponse:
        """[Stytch docs](https://stytch.com/docs/api/authenticate-magic-link)

        Authenticate a user given a magic link. This endpoint verifies that the magic link `token` is valid, hasn't expired or been previously used, and any optional security settings such as IP match or user agent match are satisfied.

        Parameters:

        - `token`: The token to authenticate.

        - `options`: Specify optional security settings

        - `attributes`: Provided attributes help with fraud detection. You can require the IP address and/or the user agent to match the request used to send the magic link using the options parameter.

        - `session_duration_minutes`: Set the session lifetime to be this many minutes from now. This will start a new session if one doesn't already exist, returning both an opaque `session_token` and `session_jwt` for this session. Remember that the `session_jwt` will have a fixed lifetime of five minutes regardless of the underlying session duration, and will need to be refreshed over time.

          This value must be a minimum of 5 and a maximum of 129600 minutes (90 days).

          If a `session_token` or `session_jwt` is provided then a successful authentication will continue to extend the session this many minutes.

          If the `session_duration_minutes` parameter is not specified, a Stytch session will not be created.

        - `session_custom_claims`: Add a custom claims map to the session being authenticated. Claims are only created if a session is initialized by providing a value in `session_duration_minutes`. Claims will be included on the session object and in the JWT. To update a key in an existing session, supply a new value. To delete a key, supply a null value

          Custom claims made with reserved claims ("iss", "sub", "aud", "exp", "nbf", "iat", "jti") will be ignored. Total custom claims size cannot exceed four kilobytes

        - `session_jwt`: Reuse an existing session instead of creating a new one. If you provide us with a `session_jwt`, then we'll update the session represented by this JWT with this magic link factor. If this `session_jwt` belongs to a different user than the magic token, the `session_jwt` will be ignored. This endpoint will error if both `session_token` and `session_jwt` are provided.

        - `session_token`: Reuse an existing session instead of creating a new one. If you provide us with a `session_token`, then we'll update the session represented by this session token with this magic link factor. If this `session_token` belongs to a different user than the magic token, the `session_token` will be ignored. This endpoint will error if both `session_token` and `session_jwt` are provided.

        - `code_verifier`: A base64url encoded one time secret used to validate that the request starts and ends on the same device.
        """  # noqa

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

        if attributes is not None:
            payload["attributes"] = attributes
        if options is not None:
            payload["options"] = options
        if session_token is not None:
            payload["session_token"] = session_token
        if session_jwt is not None:
            payload["session_jwt"] = session_jwt
        if session_duration_minutes is not None:
            payload["session_duration_minutes"] = session_duration_minutes
        if session_custom_claims is not None:
            payload["session_custom_claims"] = session_custom_claims
        if code_verifier is not None:
            payload["code_verifier"] = code_verifier

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

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