import { useLingui } from '../../../../../../node_modules/@lingui/react/dist/index.mjs';
import React__default, { useEffect, useMemo } from 'react';
import { getTranslatedError } from '../../../utils/getTranslatedError.mjs';
import { formatNumber } from '../../../utils/handleParsePhoneNumber.mjs';
import { readB2BInternals } from '../../../utils/internal.mjs';
import Button from '../../components/atoms/Button.mjs';
import Column from '../../components/atoms/Column.mjs';
import { useCountdown } from '../../components/atoms/Countdown.mjs';
import { errorToast } from '../../components/atoms/Toast.mjs';
import ButtonColumn from '../../components/molecules/ButtonColumn.mjs';
import { LoadingScreen } from '../../components/molecules/Loading.mjs';
import { ResendOTPButton } from '../../components/organisms/ResendOTPButton.mjs';
import { SentOTPEntry } from '../../components/organisms/SentOTPEntry.mjs';
import { useStytch, useConfig, useGlobalReducer } from '../GlobalContextProvider.mjs';
import { AppScreens } from '../types/AppScreens.mjs';
import { useMutate } from '../utils.mjs';
import { B2BMFAProducts } from '../../../../../core/src/public/b2b/ui.mjs';

const SMSOTPEntryScreen = ()=>{
    const stytchClient = useStytch();
    const { sessionOptions: { sessionDurationMinutes }, smsOtpOptions } = useConfig();
    const { i18n: $__i18n, _: $__ } = useLingui();
    const [state, dispatch] = useGlobalReducer();
    const { mfa: { isEnrolling, smsOtp, primaryInfo } } = state;
    const { codeExpiration, formattedDestination } = smsOtp;
    // This screen should only be shown if primary info is available
    const { enrolledMfaMethods, memberId, memberPhoneNumber, organizationId, organizationMfaOptionsSupported } = primaryInfo;
    const resendCountdown = useCountdown();
    const { trigger: sendSms, isMutating: isSending, error: sendError } = useMutate('stytch.otps.sms.send', (_, { arg: { memberId, organizationId, locale } })=>{
        dispatch({
            type: 'sms_otp/send'
        });
        return stytchClient.otps.sms.send({
            member_id: memberId,
            organization_id: organizationId,
            locale
        });
    }, {
        onSuccess: (response)=>{
            dispatch({
                type: 'sms_otp/send_success',
                response
            });
        },
        onError: (error)=>{
            const message = getTranslatedError(error, $__);
            if (message) {
                errorToast({
                    message
                });
            }
            dispatch({
                type: 'sms_otp/send_error',
                error: message
            });
        },
        // Throw on error to ensure promise is rejected
        throwOnError: true
    });
    const { trigger: authenticate, isMutating: isAuthenticating, error: authenticateError } = useMutate('stytch.otps.sms.authenticate', (_, { arg: { otp, memberId, organizationId, sessionDurationMinutes } })=>stytchClient.otps.sms.authenticate({
            code: otp,
            member_id: memberId,
            organization_id: organizationId,
            session_duration_minutes: sessionDurationMinutes
        }), {
        onSuccess: ()=>{
            dispatch({
                type: 'sms_otp/authenticate_success'
            });
        },
        onError: ()=>{
            resendCountdown.clear();
        }
    });
    const shouldCreate = codeExpiration === null && !isSending && !sendError;
    useEffect(()=>{
        if (shouldCreate) {
            sendSms({
                memberId,
                organizationId,
                locale: smsOtpOptions?.locale
            }).catch(()=>{
            // error in the UI is handled through the error object so we just swallow it here when auto-sending
            });
        }
    }, [
        memberId,
        organizationId,
        sendSms,
        shouldCreate,
        smsOtpOptions?.locale
    ]);
    useEffect(()=>{
        if (!formattedDestination && memberPhoneNumber) {
            const handleFormatNumber = async ()=>{
                const parsePhoneNumber = (phoneNumber)=>readB2BInternals(stytchClient).clientsideServices.parsedPhoneNumber({
                        phoneNumber
                    });
                const national = await formatNumber({
                    parsePhoneNumber,
                    phoneNumber: memberPhoneNumber
                });
                dispatch({
                    type: 'sms_otp/format_destination',
                    formattedPhoneNumber: national
                });
            };
            handleFormatNumber();
        }
    }, [
        dispatch,
        formattedDestination,
        stytchClient,
        memberPhoneNumber
    ]);
    const isTotpAvailable = useMemo(()=>!isEnrolling && enrolledMfaMethods.includes(B2BMFAProducts.totp) && (organizationMfaOptionsSupported.length === 0 || organizationMfaOptionsSupported.includes(B2BMFAProducts.totp)), [
        enrolledMfaMethods,
        isEnrolling,
        organizationMfaOptionsSupported
    ]);
    const errorMessage = authenticateError ? $__i18n._({
        id: "error.passcodeInvalid",
        message: "Invalid passcode, please try again."
    }) : undefined;
    // The user can go back to change their phone number if either:
    // - we are in an enrollment flow
    // - they are not enrolled in any MFA methods at all
    // - they are not enrolled in any of the limited MFA methods supported by the organization
    const canGoBack = useMemo(()=>isEnrolling || enrolledMfaMethods.length === 0 || organizationMfaOptionsSupported.length > 0 && !enrolledMfaMethods.some((enrolledMethod)=>organizationMfaOptionsSupported.includes(enrolledMethod)), [
        enrolledMfaMethods,
        isEnrolling,
        organizationMfaOptionsSupported
    ]);
    const handleSubmit = (otp)=>{
        authenticate({
            otp,
            memberId,
            organizationId,
            sessionDurationMinutes
        });
    };
    const handleSwitchToTotp = ()=>{
        dispatch({
            type: 'transition',
            history: 'push',
            screen: AppScreens.TOTPEntry
        });
    };
    const handleResendOTP = async ()=>{
        await sendSms({
            memberId,
            organizationId,
            locale: smsOtpOptions?.locale
        });
    };
    const handleBack = ()=>{
        dispatch({
            type: 'navigate_back'
        });
    };
    const resendButton = /*#__PURE__*/ React__default.createElement(ResendOTPButton, {
        countdown: resendCountdown,
        isSubmitting: isAuthenticating,
        resendOTP: handleResendOTP
    });
    const switchToTotpButton = isTotpAvailable && /*#__PURE__*/ React__default.createElement(Button, {
        variant: "ghost",
        onClick: handleSwitchToTotp
    }, $__i18n._({
        id: "mfa.methods.authenticatorApp",
        message: "Use an authenticator app"
    }));
    const backButton = canGoBack && /*#__PURE__*/ React__default.createElement(Button, {
        variant: "ghost",
        onClick: handleBack
    }, $__i18n._({
        id: "button.goBack",
        message: "Go back"
    }));
    return /*#__PURE__*/ React__default.createElement(Column, {
        gap: 6
    }, codeExpiration !== null ? /*#__PURE__*/ React__default.createElement(SentOTPEntry, {
        isSubmitting: isAuthenticating,
        onSubmit: handleSubmit,
        errorMessage: errorMessage,
        expiration: codeExpiration.getTime(),
        formattedDestination: formattedDestination ?? memberPhoneNumber ?? ''
    }) : /*#__PURE__*/ React__default.createElement(LoadingScreen, null), switchToTotpButton && backButton ? /*#__PURE__*/ React__default.createElement(ButtonColumn, {
        top: resendButton,
        bottom: /*#__PURE__*/ React__default.createElement(React__default.Fragment, null, switchToTotpButton, backButton)
    }) : /*#__PURE__*/ React__default.createElement(ButtonColumn, null, resendButton, switchToTotpButton, backButton));
};

export { SMSOTPEntryScreen };
//# sourceMappingURL=SMSOTPEntryScreen.mjs.map
