# !!!
# 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.passwords_email import Email
from stytch.api.passwords_existing_password import ExistingPassword
from stytch.api.passwords_session import Session
from stytch.core.api_base import ApiBase
from stytch.core.http.client import AsyncClient, SyncClient
from stytch.models.passwords import (
    AuthenticateResponse,
    CreateResponse,
    MigrateResponse,
    StrengthCheckResponse,
)


class Passwords:
    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)
        self.existing_password = ExistingPassword(api_base, sync_client, async_client)
        self.session = Session(api_base, sync_client, async_client)

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

    def create(
        self,
        email: str,
        password: str,
        session_duration_minutes: Optional[int] = None,
        session_custom_claims: Optional[Dict[str, Any]] = None,
    ) -> CreateResponse:
        payload: Dict[str, Any] = {
            "email": email,
            "password": password,
        }

        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

        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,
        email: str,
        password: str,
        session_duration_minutes: Optional[int] = None,
        session_custom_claims: Optional[Dict[str, Any]] = None,
    ) -> CreateResponse:
        payload: Dict[str, Any] = {
            "email": email,
            "password": password,
        }

        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

        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,
        email: str,
        password: str,
        session_token: Optional[str] = None,
        session_jwt: Optional[str] = None,
        session_duration_minutes: Optional[int] = None,
        session_custom_claims: Optional[Dict[str, Any]] = None,
    ) -> AuthenticateResponse:
        payload: Dict[str, Any] = {
            "email": email,
            "password": password,
        }

        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

        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,
        email: str,
        password: str,
        session_token: Optional[str] = None,
        session_jwt: Optional[str] = None,
        session_duration_minutes: Optional[int] = None,
        session_custom_claims: Optional[Dict[str, Any]] = None,
    ) -> AuthenticateResponse:
        payload: Dict[str, Any] = {
            "email": email,
            "password": password,
        }

        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

        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)

    def strength_check(
        self,
        password: str,
        email: Optional[str] = None,
    ) -> StrengthCheckResponse:
        payload: Dict[str, Any] = {
            "password": password,
        }

        if email is not None:
            payload["email"] = email

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

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

    async def strength_check_async(
        self,
        password: str,
        email: Optional[str] = None,
    ) -> StrengthCheckResponse:
        payload: Dict[str, Any] = {
            "password": password,
        }

        if email is not None:
            payload["email"] = email

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

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

    def migrate(
        self,
        email: str,
        hash: str,
        hash_type: str,
        md_5_config: Optional[Dict[str, Any]] = None,
        argon_2_config: Optional[Dict[str, Any]] = None,
        sha_1_config: Optional[Dict[str, Any]] = None,
        scrypt_config: Optional[Dict[str, Any]] = None,
    ) -> MigrateResponse:
        payload: Dict[str, Any] = {
            "email": email,
            "hash": hash,
            "hash_type": hash_type,
        }

        if md_5_config is not None:
            payload["md_5_config"] = md_5_config
        if argon_2_config is not None:
            payload["argon_2_config"] = argon_2_config
        if sha_1_config is not None:
            payload["sha_1_config"] = sha_1_config
        if scrypt_config is not None:
            payload["scrypt_config"] = scrypt_config

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

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

    async def migrate_async(
        self,
        email: str,
        hash: str,
        hash_type: str,
        md_5_config: Optional[Dict[str, Any]] = None,
        argon_2_config: Optional[Dict[str, Any]] = None,
        sha_1_config: Optional[Dict[str, Any]] = None,
        scrypt_config: Optional[Dict[str, Any]] = None,
    ) -> MigrateResponse:
        payload: Dict[str, Any] = {
            "email": email,
            "hash": hash,
            "hash_type": hash_type,
        }

        if md_5_config is not None:
            payload["md_5_config"] = md_5_config
        if argon_2_config is not None:
            payload["argon_2_config"] = argon_2_config
        if sha_1_config is not None:
            payload["sha_1_config"] = sha_1_config
        if scrypt_config is not None:
            payload["scrypt_config"] = scrypt_config

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

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