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

import typing

from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.request_options import RequestOptions
from ..types.device_information import DeviceInformation
from ..types.email_validation_response import EmailValidationResponse
from ..types.google_authorize_response import GoogleAuthorizeResponse
from ..types.login_response import LoginResponse
from ..types.login_verification_response import LoginVerificationResponse
from ..types.logout_response import LogoutResponse
from ..types.password_reset_response import PasswordResetResponse
from ..types.password_reset_verify_response import PasswordResetVerifyResponse
from ..types.password_update_response import PasswordUpdateResponse
from ..types.refresh_token_response import RefreshTokenResponse
from ..types.register_response import RegisterResponse
from ..types.resend_code_response import ResendCodeResponse
from ..types.token_validation_response import TokenValidationResponse
from .raw_client import AsyncRawAuthenticationClient, RawAuthenticationClient

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


class AuthenticationClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawAuthenticationClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> RawAuthenticationClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawAuthenticationClient
        """
        return self._raw_client

    def register(
        self,
        *,
        email: str,
        password: str,
        full_name: str,
        user_name: typing.Optional[str] = OMIT,
        organization_id: typing.Optional[str] = OMIT,
        device_information: typing.Optional[DeviceInformation] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RegisterResponse:
        """
        Register a new user account with email verification.

        Creates a new user account, sends a 4-digit verification code via email,
        and creates an EmailVerification record. User must verify their email
        using the /verify endpoint to complete registration.

        Parameters
        ----------
        email : str
            User email address (primary identifier)

        password : str
            Password (min 8 chars with complexity, max 72 chars due to bcrypt limit)

        full_name : str
            User's full name

        user_name : typing.Optional[str]
            Preferred username (defaults to email prefix if omitted, min 3 chars)

        organization_id : typing.Optional[str]
            Organization UID to associate the user with

        device_information : typing.Optional[DeviceInformation]
            Device tracking information

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

        Returns
        -------
        RegisterResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos, DeviceInformation

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.register(
            email="user@company.com",
            password="SecurePassword123!",
            full_name="John Doe",
            user_name="johndoe",
            organization_id="org_12345678901234567890123456789012",
            device_information=DeviceInformation(
                device="Chrome Browser",
                device_id="device-123",
                platform="web",
            ),
        )
        """
        _response = self._raw_client.register(
            email=email,
            password=password,
            full_name=full_name,
            user_name=user_name,
            organization_id=organization_id,
            device_information=device_information,
            request_options=request_options,
        )
        return _response.data

    def login(
        self,
        *,
        email_or_username: str,
        password: str,
        device_information: typing.Optional[DeviceInformation] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> LoginResponse:
        """
        Authenticate user credentials and initiate two-factor authentication (2FA) via email verification.

        Parameters
        ----------
        email_or_username : str
            Email address or username

        password : str
            User password

        device_information : typing.Optional[DeviceInformation]
            Device tracking information

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

        Returns
        -------
        LoginResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos, DeviceInformation

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.login(
            email_or_username="user@example.com",
            password="SecurePassword123!",
            device_information=DeviceInformation(
                device="Chrome Browser",
                device_id="device-123",
                operating_system="macOS",
                platform="web",
            ),
        )
        """
        _response = self._raw_client.login(
            email_or_username=email_or_username,
            password=password,
            device_information=device_information,
            request_options=request_options,
        )
        return _response.data

    def verify_email(
        self,
        *,
        email_key: str,
        verification_code: int,
        device_information: typing.Optional[DeviceInformation] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> LoginVerificationResponse:
        """
        Verify email verification code and return JWT tokens.

        Parameters
        ----------
        email_key : str
            Email verification key

        verification_code : int
            4-digit verification code

        device_information : typing.Optional[DeviceInformation]
            Device tracking information

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

        Returns
        -------
        LoginVerificationResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos, DeviceInformation

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.verify_email(
            email_key="uuid-12345678-1234-1234-1234-123456789abc",
            verification_code=1234,
            device_information=DeviceInformation(
                device_id="device-123",
                platform="web",
            ),
        )
        """
        _response = self._raw_client.verify_email(
            email_key=email_key,
            verification_code=verification_code,
            device_information=device_information,
            request_options=request_options,
        )
        return _response.data

    def refresh_token(
        self, *, refresh_token: str, request_options: typing.Optional[RequestOptions] = None
    ) -> RefreshTokenResponse:
        """
        Refresh an expired access token using a valid refresh token.

        Parameters
        ----------
        refresh_token : str
            Refresh token

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

        Returns
        -------
        RefreshTokenResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.refresh_token(
            refresh_token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
        )
        """
        _response = self._raw_client.refresh_token(refresh_token=refresh_token, request_options=request_options)
        return _response.data

    def logout(
        self, *, refresh_token: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None
    ) -> LogoutResponse:
        """
        Logout the current user and invalidate their authentication tokens.

        Parameters
        ----------
        refresh_token : typing.Optional[str]
            Refresh token to invalidate

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

        Returns
        -------
        LogoutResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.logout(
            refresh_token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
        )
        """
        _response = self._raw_client.logout(refresh_token=refresh_token, request_options=request_options)
        return _response.data

    def request_password_reset(
        self, *, email: str, request_options: typing.Optional[RequestOptions] = None
    ) -> PasswordResetResponse:
        """
        Request a password reset for a user account.

        Sends a 4-digit verification code to the user's email if the account exists.
        For security, always returns success regardless of whether the email exists.

        **Security Features:**
        - Generic response (prevents email enumeration)
        - Rate limiting (1 request per minute per email)
        - Time-limited codes (5 minutes expiry)
        - Automatic cleanup of expired codes

        **Flow:**
        1. User requests password reset with email
        2. If account exists, receives 4-digit code via email
        3. User submits code + new password to /password/reset/verify
        4. All existing sessions are revoked on successful reset

        Parameters
        ----------
        email : str
            User email address

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

        Returns
        -------
        PasswordResetResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.request_password_reset(
            email="user@example.com",
        )
        """
        _response = self._raw_client.request_password_reset(email=email, request_options=request_options)
        return _response.data

    def verify_password_reset(
        self,
        *,
        email: str,
        verification_code: int,
        new_password: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PasswordResetVerifyResponse:
        """
        Verify password reset code and set new password.

        Validates the 4-digit code and updates the user's password.
        All existing refresh tokens are revoked, forcing re-authentication.

        **Security Features:**
        - Code expires after 5 minutes
        - One-time use codes (marked as used after verification)
        - Password strength validation
        - All sessions revoked on success

        **Errors:**
        - 404: User not found
        - 422: Invalid/expired code or weak password

        Parameters
        ----------
        email : str
            User email address

        verification_code : int
            4-digit verification code

        new_password : str
            New password (min 8 chars with complexity, max 72 chars due to bcrypt limit)

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

        Returns
        -------
        PasswordResetVerifyResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.verify_password_reset(
            email="user@example.com",
            verification_code=1234,
            new_password="NewSecurePassword123!",
        )
        """
        _response = self._raw_client.verify_password_reset(
            email=email, verification_code=verification_code, new_password=new_password, request_options=request_options
        )
        return _response.data

    def update_password(
        self,
        *,
        current_password: str,
        new_password: str,
        confirm_password: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PasswordUpdateResponse:
        """
        Update password for authenticated user.

        Requires current password verification and enforces password strength requirements.
        All other device sessions are revoked while keeping the current session active.

        **Security Features:**
        - Requires authentication (Bearer token)
        - Verifies current password before allowing change
        - Password strength validation
        - Keeps current session active
        - Revokes all other device sessions
        - Logs password change for audit

        **Password Requirements:**
        - Minimum 8 characters
        - At least one special character
        - Not in common weak passwords list

        **Errors:**
        - 401: Current password is incorrect
        - 404: User not found
        - 422: Passwords don't match or new password is weak

        Parameters
        ----------
        current_password : str
            Current password for verification

        new_password : str
            New password (min 8 chars with complexity, max 72 chars due to bcrypt limit)

        confirm_password : str
            Confirmation of new password (must match new_password)

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

        Returns
        -------
        PasswordUpdateResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.update_password(
            current_password="CurrentPassword123!",
            new_password="NewSecurePassword456!",
            confirm_password="NewSecurePassword456!",
        )
        """
        _response = self._raw_client.update_password(
            current_password=current_password,
            new_password=new_password,
            confirm_password=confirm_password,
            request_options=request_options,
        )
        return _response.data

    def validate_email(
        self, *, email: str, request_options: typing.Optional[RequestOptions] = None
    ) -> EmailValidationResponse:
        """
        Validate email for registration.

        Checks if email is:
        - Valid format
        - Not already registered
        - Associated with an organization domain

        This endpoint is used during registration to provide real-time feedback
        about email validity and availability.

        **Returns:**
        - valid: Whether email format is valid
        - available: Whether email is available for registration
        - organization_id: Organization ID if email domain matches (optional)
        - organization_name: Organization name if email domain matches (optional)

        Parameters
        ----------
        email : str
            Email address to validate for signup eligibility

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

        Returns
        -------
        EmailValidationResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.validate_email(
            email="user@aitronos.com",
        )
        """
        _response = self._raw_client.validate_email(email=email, request_options=request_options)
        return _response.data

    def resend_verification_code(
        self, *, email_key: str, request_options: typing.Optional[RequestOptions] = None
    ) -> ResendCodeResponse:
        """
        Resend verification code.

        Generates and sends a new 4-digit verification code to the user's email.
        Works for login, registration, and password reset verifications.

        **Security Features:**
        - Validates verification record exists
        - Checks if verification already used
        - Generates new random code
        - Updates expiry time

        **Errors:**
        - 404: Verification record not found
        - 422: Verification already used
        - 500: Email sending failed

        Parameters
        ----------
        email_key : str
            Email verification key

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

        Returns
        -------
        ResendCodeResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.resend_verification_code(
            email_key="uuid-12345678-1234-1234-1234-123456789abc",
        )
        """
        _response = self._raw_client.resend_verification_code(email_key=email_key, request_options=request_options)
        return _response.data

    def forgot_password(
        self, *, email: str, request_options: typing.Optional[RequestOptions] = None
    ) -> PasswordResetResponse:
        """
        Request a password reset (alias for /password/reset).

        Sends a 4-digit verification code to the user's email if the account exists.
        For security, always returns success regardless of whether the email exists.

        **Security Features:**
        - Generic response (prevents email enumeration)
        - Rate limiting (1 request per minute per email)
        - Time-limited codes (5 minutes expiry)
        - Automatic cleanup of expired codes

        **Flow:**
        1. User requests password reset with email
        2. If account exists, receives 4-digit code via email
        3. User submits code + new password to /password/reset
        4. All existing sessions are revoked on successful reset

        Parameters
        ----------
        email : str
            User email address

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

        Returns
        -------
        PasswordResetResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.forgot_password(
            email="user@example.com",
        )
        """
        _response = self._raw_client.forgot_password(email=email, request_options=request_options)
        return _response.data

    def validate_token(self, *, request_options: typing.Optional[RequestOptions] = None) -> TokenValidationResponse:
        """
        Validate current authentication token.

        Used by frontend to check if the session is still valid.
        If the request reaches this endpoint (passes AuthContext dependency),
        the token is valid.

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

        Returns
        -------
        TokenValidationResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.validate_token()
        """
        _response = self._raw_client.validate_token(request_options=request_options)
        return _response.data

    def dev_login(
        self,
        *,
        email_or_username: str,
        password: str,
        device_information: typing.Optional[DeviceInformation] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> LoginVerificationResponse:
        """
        Development login (bypass email verification).

        **WARNING:** This endpoint is only available in non-production environments
        or when explicitly enabled via configuration.

        It validates credentials and immediately returns authentication tokens
        without sending a verification code.

        Parameters
        ----------
        email_or_username : str
            Email address or username

        password : str
            User password

        device_information : typing.Optional[DeviceInformation]
            Device tracking information

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

        Returns
        -------
        LoginVerificationResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos, DeviceInformation

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.dev_login(
            email_or_username="user@example.com",
            password="SecurePassword123!",
            device_information=DeviceInformation(
                device="Chrome Browser",
                device_id="device-123",
                operating_system="macOS",
                platform="web",
            ),
        )
        """
        _response = self._raw_client.dev_login(
            email_or_username=email_or_username,
            password=password,
            device_information=device_information,
            request_options=request_options,
        )
        return _response.data

    def google_authorize(
        self,
        *,
        redirect_uri: str,
        organization_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GoogleAuthorizeResponse:
        """
        Generate Google OAuth authorization URL for Sign-In.

        Parameters
        ----------
        redirect_uri : str
            Frontend URL to redirect to after authentication

        organization_id : typing.Optional[str]
            Optional organization ID to associate user with

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

        Returns
        -------
        GoogleAuthorizeResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.google_authorize(
            redirect_uri="https://app.aitronos.com/auth/callback",
        )
        """
        _response = self._raw_client.google_authorize(
            redirect_uri=redirect_uri, organization_id=organization_id, request_options=request_options
        )
        return _response.data

    def google_callback(
        self,
        *,
        code: str,
        state: str,
        error: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Handle Google OAuth callback and show success/error page.

        Parameters
        ----------
        code : str
            Authorization code from Google

        state : str
            CSRF state token

        error : typing.Optional[str]
            Error from Google

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

        Returns
        -------
        None

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.authentication.google_callback(
            code="code",
            state="state",
        )
        """
        _response = self._raw_client.google_callback(
            code=code, state=state, error=error, request_options=request_options
        )
        return _response.data


class AsyncAuthenticationClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawAuthenticationClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> AsyncRawAuthenticationClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawAuthenticationClient
        """
        return self._raw_client

    async def register(
        self,
        *,
        email: str,
        password: str,
        full_name: str,
        user_name: typing.Optional[str] = OMIT,
        organization_id: typing.Optional[str] = OMIT,
        device_information: typing.Optional[DeviceInformation] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RegisterResponse:
        """
        Register a new user account with email verification.

        Creates a new user account, sends a 4-digit verification code via email,
        and creates an EmailVerification record. User must verify their email
        using the /verify endpoint to complete registration.

        Parameters
        ----------
        email : str
            User email address (primary identifier)

        password : str
            Password (min 8 chars with complexity, max 72 chars due to bcrypt limit)

        full_name : str
            User's full name

        user_name : typing.Optional[str]
            Preferred username (defaults to email prefix if omitted, min 3 chars)

        organization_id : typing.Optional[str]
            Organization UID to associate the user with

        device_information : typing.Optional[DeviceInformation]
            Device tracking information

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

        Returns
        -------
        RegisterResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos, DeviceInformation

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.register(
                email="user@company.com",
                password="SecurePassword123!",
                full_name="John Doe",
                user_name="johndoe",
                organization_id="org_12345678901234567890123456789012",
                device_information=DeviceInformation(
                    device="Chrome Browser",
                    device_id="device-123",
                    platform="web",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.register(
            email=email,
            password=password,
            full_name=full_name,
            user_name=user_name,
            organization_id=organization_id,
            device_information=device_information,
            request_options=request_options,
        )
        return _response.data

    async def login(
        self,
        *,
        email_or_username: str,
        password: str,
        device_information: typing.Optional[DeviceInformation] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> LoginResponse:
        """
        Authenticate user credentials and initiate two-factor authentication (2FA) via email verification.

        Parameters
        ----------
        email_or_username : str
            Email address or username

        password : str
            User password

        device_information : typing.Optional[DeviceInformation]
            Device tracking information

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

        Returns
        -------
        LoginResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos, DeviceInformation

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.login(
                email_or_username="user@example.com",
                password="SecurePassword123!",
                device_information=DeviceInformation(
                    device="Chrome Browser",
                    device_id="device-123",
                    operating_system="macOS",
                    platform="web",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.login(
            email_or_username=email_or_username,
            password=password,
            device_information=device_information,
            request_options=request_options,
        )
        return _response.data

    async def verify_email(
        self,
        *,
        email_key: str,
        verification_code: int,
        device_information: typing.Optional[DeviceInformation] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> LoginVerificationResponse:
        """
        Verify email verification code and return JWT tokens.

        Parameters
        ----------
        email_key : str
            Email verification key

        verification_code : int
            4-digit verification code

        device_information : typing.Optional[DeviceInformation]
            Device tracking information

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

        Returns
        -------
        LoginVerificationResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos, DeviceInformation

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.verify_email(
                email_key="uuid-12345678-1234-1234-1234-123456789abc",
                verification_code=1234,
                device_information=DeviceInformation(
                    device_id="device-123",
                    platform="web",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.verify_email(
            email_key=email_key,
            verification_code=verification_code,
            device_information=device_information,
            request_options=request_options,
        )
        return _response.data

    async def refresh_token(
        self, *, refresh_token: str, request_options: typing.Optional[RequestOptions] = None
    ) -> RefreshTokenResponse:
        """
        Refresh an expired access token using a valid refresh token.

        Parameters
        ----------
        refresh_token : str
            Refresh token

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

        Returns
        -------
        RefreshTokenResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.refresh_token(
                refresh_token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.refresh_token(refresh_token=refresh_token, request_options=request_options)
        return _response.data

    async def logout(
        self, *, refresh_token: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None
    ) -> LogoutResponse:
        """
        Logout the current user and invalidate their authentication tokens.

        Parameters
        ----------
        refresh_token : typing.Optional[str]
            Refresh token to invalidate

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

        Returns
        -------
        LogoutResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.logout(
                refresh_token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.logout(refresh_token=refresh_token, request_options=request_options)
        return _response.data

    async def request_password_reset(
        self, *, email: str, request_options: typing.Optional[RequestOptions] = None
    ) -> PasswordResetResponse:
        """
        Request a password reset for a user account.

        Sends a 4-digit verification code to the user's email if the account exists.
        For security, always returns success regardless of whether the email exists.

        **Security Features:**
        - Generic response (prevents email enumeration)
        - Rate limiting (1 request per minute per email)
        - Time-limited codes (5 minutes expiry)
        - Automatic cleanup of expired codes

        **Flow:**
        1. User requests password reset with email
        2. If account exists, receives 4-digit code via email
        3. User submits code + new password to /password/reset/verify
        4. All existing sessions are revoked on successful reset

        Parameters
        ----------
        email : str
            User email address

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

        Returns
        -------
        PasswordResetResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.request_password_reset(
                email="user@example.com",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.request_password_reset(email=email, request_options=request_options)
        return _response.data

    async def verify_password_reset(
        self,
        *,
        email: str,
        verification_code: int,
        new_password: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PasswordResetVerifyResponse:
        """
        Verify password reset code and set new password.

        Validates the 4-digit code and updates the user's password.
        All existing refresh tokens are revoked, forcing re-authentication.

        **Security Features:**
        - Code expires after 5 minutes
        - One-time use codes (marked as used after verification)
        - Password strength validation
        - All sessions revoked on success

        **Errors:**
        - 404: User not found
        - 422: Invalid/expired code or weak password

        Parameters
        ----------
        email : str
            User email address

        verification_code : int
            4-digit verification code

        new_password : str
            New password (min 8 chars with complexity, max 72 chars due to bcrypt limit)

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

        Returns
        -------
        PasswordResetVerifyResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.verify_password_reset(
                email="user@example.com",
                verification_code=1234,
                new_password="NewSecurePassword123!",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.verify_password_reset(
            email=email, verification_code=verification_code, new_password=new_password, request_options=request_options
        )
        return _response.data

    async def update_password(
        self,
        *,
        current_password: str,
        new_password: str,
        confirm_password: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PasswordUpdateResponse:
        """
        Update password for authenticated user.

        Requires current password verification and enforces password strength requirements.
        All other device sessions are revoked while keeping the current session active.

        **Security Features:**
        - Requires authentication (Bearer token)
        - Verifies current password before allowing change
        - Password strength validation
        - Keeps current session active
        - Revokes all other device sessions
        - Logs password change for audit

        **Password Requirements:**
        - Minimum 8 characters
        - At least one special character
        - Not in common weak passwords list

        **Errors:**
        - 401: Current password is incorrect
        - 404: User not found
        - 422: Passwords don't match or new password is weak

        Parameters
        ----------
        current_password : str
            Current password for verification

        new_password : str
            New password (min 8 chars with complexity, max 72 chars due to bcrypt limit)

        confirm_password : str
            Confirmation of new password (must match new_password)

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

        Returns
        -------
        PasswordUpdateResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.update_password(
                current_password="CurrentPassword123!",
                new_password="NewSecurePassword456!",
                confirm_password="NewSecurePassword456!",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.update_password(
            current_password=current_password,
            new_password=new_password,
            confirm_password=confirm_password,
            request_options=request_options,
        )
        return _response.data

    async def validate_email(
        self, *, email: str, request_options: typing.Optional[RequestOptions] = None
    ) -> EmailValidationResponse:
        """
        Validate email for registration.

        Checks if email is:
        - Valid format
        - Not already registered
        - Associated with an organization domain

        This endpoint is used during registration to provide real-time feedback
        about email validity and availability.

        **Returns:**
        - valid: Whether email format is valid
        - available: Whether email is available for registration
        - organization_id: Organization ID if email domain matches (optional)
        - organization_name: Organization name if email domain matches (optional)

        Parameters
        ----------
        email : str
            Email address to validate for signup eligibility

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

        Returns
        -------
        EmailValidationResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.validate_email(
                email="user@aitronos.com",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.validate_email(email=email, request_options=request_options)
        return _response.data

    async def resend_verification_code(
        self, *, email_key: str, request_options: typing.Optional[RequestOptions] = None
    ) -> ResendCodeResponse:
        """
        Resend verification code.

        Generates and sends a new 4-digit verification code to the user's email.
        Works for login, registration, and password reset verifications.

        **Security Features:**
        - Validates verification record exists
        - Checks if verification already used
        - Generates new random code
        - Updates expiry time

        **Errors:**
        - 404: Verification record not found
        - 422: Verification already used
        - 500: Email sending failed

        Parameters
        ----------
        email_key : str
            Email verification key

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

        Returns
        -------
        ResendCodeResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.resend_verification_code(
                email_key="uuid-12345678-1234-1234-1234-123456789abc",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.resend_verification_code(
            email_key=email_key, request_options=request_options
        )
        return _response.data

    async def forgot_password(
        self, *, email: str, request_options: typing.Optional[RequestOptions] = None
    ) -> PasswordResetResponse:
        """
        Request a password reset (alias for /password/reset).

        Sends a 4-digit verification code to the user's email if the account exists.
        For security, always returns success regardless of whether the email exists.

        **Security Features:**
        - Generic response (prevents email enumeration)
        - Rate limiting (1 request per minute per email)
        - Time-limited codes (5 minutes expiry)
        - Automatic cleanup of expired codes

        **Flow:**
        1. User requests password reset with email
        2. If account exists, receives 4-digit code via email
        3. User submits code + new password to /password/reset
        4. All existing sessions are revoked on successful reset

        Parameters
        ----------
        email : str
            User email address

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

        Returns
        -------
        PasswordResetResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.forgot_password(
                email="user@example.com",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.forgot_password(email=email, request_options=request_options)
        return _response.data

    async def validate_token(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> TokenValidationResponse:
        """
        Validate current authentication token.

        Used by frontend to check if the session is still valid.
        If the request reaches this endpoint (passes AuthContext dependency),
        the token is valid.

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

        Returns
        -------
        TokenValidationResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.validate_token()


        asyncio.run(main())
        """
        _response = await self._raw_client.validate_token(request_options=request_options)
        return _response.data

    async def dev_login(
        self,
        *,
        email_or_username: str,
        password: str,
        device_information: typing.Optional[DeviceInformation] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> LoginVerificationResponse:
        """
        Development login (bypass email verification).

        **WARNING:** This endpoint is only available in non-production environments
        or when explicitly enabled via configuration.

        It validates credentials and immediately returns authentication tokens
        without sending a verification code.

        Parameters
        ----------
        email_or_username : str
            Email address or username

        password : str
            User password

        device_information : typing.Optional[DeviceInformation]
            Device tracking information

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

        Returns
        -------
        LoginVerificationResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos, DeviceInformation

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.dev_login(
                email_or_username="user@example.com",
                password="SecurePassword123!",
                device_information=DeviceInformation(
                    device="Chrome Browser",
                    device_id="device-123",
                    operating_system="macOS",
                    platform="web",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.dev_login(
            email_or_username=email_or_username,
            password=password,
            device_information=device_information,
            request_options=request_options,
        )
        return _response.data

    async def google_authorize(
        self,
        *,
        redirect_uri: str,
        organization_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GoogleAuthorizeResponse:
        """
        Generate Google OAuth authorization URL for Sign-In.

        Parameters
        ----------
        redirect_uri : str
            Frontend URL to redirect to after authentication

        organization_id : typing.Optional[str]
            Optional organization ID to associate user with

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

        Returns
        -------
        GoogleAuthorizeResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.google_authorize(
                redirect_uri="https://app.aitronos.com/auth/callback",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.google_authorize(
            redirect_uri=redirect_uri, organization_id=organization_id, request_options=request_options
        )
        return _response.data

    async def google_callback(
        self,
        *,
        code: str,
        state: str,
        error: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Handle Google OAuth callback and show success/error page.

        Parameters
        ----------
        code : str
            Authorization code from Google

        state : str
            CSRF state token

        error : typing.Optional[str]
            Error from Google

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

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.authentication.google_callback(
                code="code",
                state="state",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.google_callback(
            code=code, state=state, error=error, request_options=request_options
        )
        return _response.data
