var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import React from 'react';
import { View, Alert } from 'react-native';
import LoginForm from '../../login/components/LoginForm';
import { Colors, CrossButton, CrossLabel } from 'react-native-cross-components';
import { OnLogin } from '../../events/OnLogin';
import _ from 'lodash';
import RegisterForm from '../../register/components/RegisterForm';
import { ForgotForm } from '../../forgot/components/ForgotForm';
import { ConfirmForm } from '../../confirm/components/ConfirmForm';
import { OnRegister } from '../../events/OnRegister';
import styles from '../../styles';
import OnConfirmMfaCode from '../../events/OnConfirmMfaCode';
import OnConfirmAccount from '../../events/OnConfirmAccount';
import { OnForgotPassword } from '../../events/OnForgotPassword';
import { OnResendSignup } from '../../events/OnResendSignup';
import { PasswordForm } from '../../new-password/components/PasswordForm';
import { OnConfirmPassword } from '../../events/OnConfirmPassword';
/**
 * A form for logging in to AWS Cognito through Amplify.
 *
 * On successful registration the {@link ICognitoLoginProps.onRegisteredUser} event is triggered.
 *
 * On successful login the {@link ICognitoLoginProps.onLoggedIn} event is triggered.
 *
 * Children can be supplied for the this component as well as child components. See {@link ICognitoLoginProps}.
 *
 * Remarks:
 * * Requires Amplify to be configured:
 *
 * https://aws-amplify.github.io/docs/js/start?ref=amplify-rn-btn&platform=react-native#step-4-integrate-aws-resources
 *
 * Props are {@link ICognitoLoginProps}
 *
 * @example <caption>With custom button props and callback</caption>
 *  <CognitoLogin
 *    onRegisteredUser={(user) => {
 *      Alert.alert('Registration complete', 'Thank you ' + user.getUsername());
 *    }}
 *    onLoggedIn={(user) => {
 *      Alert.alert('Logged in', 'Welcome ' + user.getUsername());
 *    }}
 *    buttonProps={{mode: 'contained'}}>
 *     <Text>Custom layouts here</Text>
 *  </CognitoLogin>
 * @example <caption>With custom children</caption>
 *  <CognitoLogin
 *      registerChildren={
 *        <Text
 *          style={{
 *            color: 'blue',
 *            fontWeight: 'bold',
 *            margin: 10,
 *            fontSize: 16,
 *          }}
 *        >
 *          &lt;ENLIST NOW&gt;
 *      </Text>
 *      }
 *    >
 *      <Text
 *        style={{
 *          color: 'red',
 *          fontWeight: 'bold',
 *          margin: 10,
 *          fontSize: 16,
 *        }}
 *      >
 *        &lt;WARNING: RESTRICTED AREA&gt; :)
 *      </Text>
 *    </CognitoLogin>
 */
export class CognitoLogin extends React.Component {
    constructor(props) {
        super(props);
        /**
         * Determines the currently visible form
         */
        this.onResultChanged = () => {
            let form = this.state.formState;
            const result = this.state.result;
            const authState = _.get(this.state, ['result', 'state']);
            if (!authState) {
                return;
            }
            switch (authState) {
                case 'Authenticated':
                    form = 'Login';
                    if (result && result.user && this.props.onLoggedIn) {
                        this.props.onLoggedIn(result.user);
                    }
                    break;
                case 'ConfirmAccountCodeWaiting':
                    form = 'ConfirmAccount';
                    break;
                case 'ConfirmLoginMFAWaiting':
                    form = 'ConfirmMFALogin';
                    break;
                case 'NEW_PASSWORD_REQUIRED':
                    form = 'NewPassword';
                    break;
                case 'Unauthenticated':
                    form = 'Login';
                    break;
                default:
                    break;
            }
            let { message } = this.state;
            if (authState === 'Authenticated') {
                message = 'Logged in!';
            }
            this.setState({ formState: form, message });
        };
        this.onEmailChanged = (email) => {
            const { userInput } = this.state;
            if (_.isNil(email)) {
                return;
            }
            userInput.email = email;
            this.setState({ userInput });
        };
        this.onPasswordChanged = (password) => {
            const { userInput } = this.state;
            if (_.isNil(password)) {
                return;
            }
            userInput.password = password;
            this.setState({ userInput });
        };
        this.onPhoneChanged = (phone) => {
            const { userInput } = this.state;
            let newPhone = phone;
            if (_.isNil(newPhone)) {
                return;
            }
            newPhone = newPhone.replace(' ', '').trim();
            if (!newPhone.startsWith('+')) {
                newPhone = '+' + newPhone;
            }
            userInput.phone = newPhone;
            this.setState({ userInput });
        };
        this.OnResendSignup = () => {
            const { email } = this.state.userInput;
            if (_.isNil(email)) {
                this.setState({ message: 'Please enter username' });
                return;
            }
            const sendButton = {
                text: 'OK',
                onPress: () => __awaiter(this, void 0, void 0, function* () {
                    if (__DEV__)
                        console.log('***** OnResendSignup ***** ');
                    const result = yield OnResendSignup(email);
                    if (__DEV__)
                        console.log('**** OnResendSignup result: ', result);
                    this.setState({ result }, this.onResultChanged);
                }),
            };
            Alert.alert('Confirm', 'Re-send code?', [sendButton, this.cancelAlertButton], {
                cancelable: true,
            });
        };
        this.ForgotPasswordAsync = (email) => __awaiter(this, void 0, void 0, function* () {
            if (__DEV__)
                console.log('***** OnForgotPassword ***** ');
            const result = yield OnForgotPassword(email);
            if (__DEV__)
                console.log('**** OnForgotPassword result: ', result);
            this.setState({ result }, this.onResultChanged);
        });
        this.OnResetPassword = () => {
            const { email } = this.state.userInput;
            if (_.isNil(email)) {
                this.setState({ message: 'Please enter username' });
                return;
            }
            Alert.alert('Confirm', 'Reset password?', [this.ForgotPasswordAlertButton, this.cancelAlertButton], {
                cancelable: true,
            });
        };
        this.onRegister = () => __awaiter(this, void 0, void 0, function* () {
            if (__DEV__)
                console.log('***** OnRegister ***** ');
            const result = yield OnRegister(this.state.userInput);
            if (__DEV__)
                console.log('**** OnRegister result: ', result);
            if (result.user && this.props.onRegisteredUser) {
                this.props.onRegisteredUser(result.user);
            }
            this.setState({ result }, this.onResultChanged);
        });
        this.onConfirmAccount = () => __awaiter(this, void 0, void 0, function* () {
            if (_.isNil(this.state.code) ||
                this.state.code === '' ||
                _.isNil(this.state.userInput.email)) {
                this.setState({ message: 'Need code and user e-mail' });
                return;
            }
            if (__DEV__)
                console.log('***** onConfirmAccount ***** ');
            const result = yield OnConfirmAccount(this.state.code, this.state.userInput.email);
            if (__DEV__)
                console.log('**** onConfirmAccount result: ', result);
            this.setState({ result, formState: 'Login' }, this.onResultChanged);
        });
        this.onConfirmMFACode = () => __awaiter(this, void 0, void 0, function* () {
            if (_.isNil(this.state.code) ||
                this.state.code === '' ||
                _.isNil(this.state.userInput.email)) {
                this.setState({
                    message: 'Please enter username and the code',
                });
                return;
            }
            if (__DEV__)
                console.log('***** onConfirmMFACode ***** ');
            const result = yield OnConfirmMfaCode(this.state.code, this.state.userInput.email);
            if (__DEV__)
                console.log('**** onConfirmMFACode result: ', result);
            this.setState({ result }, this.onResultChanged);
        });
        this.onSaveNewPassword = () => __awaiter(this, void 0, void 0, function* () {
            if (_.isNil(this.state.code) ||
                this.state.code === '' ||
                _.isNil(this.state.userInput.email) ||
                _.isNil(this.state.userInput.password)) {
                this.setState({
                    message: 'Please enter username, code and new password',
                });
                return;
            }
            if (__DEV__)
                console.log('***** onSaveNewPassword ***** ');
            const result = yield OnConfirmPassword(this.state.code, this.state.userInput.email, this.state.userInput.password);
            if (__DEV__)
                console.log('**** onSaveNewPassword result: ', result);
            this.setState({ result }, this.onResultChanged);
        });
        this.onLogin = () => __awaiter(this, void 0, void 0, function* () {
            if (__DEV__)
                console.log('***** onLogin ***** ');
            const result = yield OnLogin(this.state.userInput);
            if (__DEV__)
                console.log('**** onLogin result: ', result);
            this.setState({ result }, this.onResultChanged);
        });
        this.render = () => {
            // Extract error message. Could be an Error or a string
            const error = _.get(this.state, ['result', 'error', 'message']) ||
                _.get(this.state, ['result', 'error'] || this.state.message);
            console.log('*** CognitioLogin error: ', error || 'none');
            return (React.createElement(View, { style: styles.container },
                this.props.children,
                this.state.formState === 'Login' ? (React.createElement(View, { style: styles.container },
                    React.createElement(LoginForm, Object.assign({ initialEmail: this.state.userInput.email, initialPassword: this.state.userInput.password, onEmailChanged: this.onEmailChanged, onPasswordChanged: this.onPasswordChanged }, this.props), this.props.loginChildren),
                    React.createElement(CrossButton, Object.assign({ style: styles.marginTop10, buttonStyle: styles.buttonStyle, onPress: () => __awaiter(this, void 0, void 0, function* () { return yield this.onLogin(); }), mode: 'contained', title: 'Log in', backgroundColor: Colors.NextButton, iconName: 'sign-in' }, this.props.buttonProps, this.props.loginButtonProps)),
                    React.createElement(CrossButton, Object.assign({ style: styles.marginTop10, buttonStyle: styles.buttonStyle, onPress: () => this.setState({
                            formState: 'Register',
                        }), mode: 'contained', title: 'Register', backgroundColor: Colors.BackButton }, this.props.buttonProps, this.props.registerButtonProps)),
                    React.createElement(CrossButton, Object.assign({ style: styles.marginTop10, buttonStyle: styles.buttonStyle, onPress: () => this.setState({
                            formState: 'Forgot',
                        }), mode: 'text', title: 'Forgot password', backgroundColor: Colors.CancelButton }, this.props.buttonProps, this.props.cancelButtonProps)))) : null,
                this.state.formState === 'Register' ? (React.createElement(View, { style: styles.container },
                    React.createElement(RegisterForm, Object.assign({ initialPhone: this.state.userInput.phone, onPhoneChanged: this.onPhoneChanged, initialEmail: this.state.userInput.email, onEmailChanged: this.onEmailChanged, initialPassword: this.state.userInput.password, onPasswordChanged: this.onPasswordChanged }, this.props), this.props.registerChildren),
                    React.createElement(CrossButton, Object.assign({ style: styles.marginTop10, buttonStyle: styles.buttonStyle, onPress: () => __awaiter(this, void 0, void 0, function* () { return yield this.onRegister(); }), mode: 'contained', title: 'Save', backgroundColor: Colors.NextButton, iconName: 'sign-in' }, this.props.buttonProps, this.props.saveButtonProps)),
                    React.createElement(CrossButton, Object.assign({ style: styles.marginTop10, buttonStyle: styles.buttonStyle, onPress: () => this.setState({
                            formState: 'Login',
                        }), mode: 'contained', title: 'Cancel', backgroundColor: Colors.CancelButton }, this.props.buttonProps, this.props.cancelButtonProps)))) : null,
                this.state.formState === 'NewPassword' ? (React.createElement(View, { style: styles.container },
                    React.createElement(PasswordForm, { testID: 'PasswordForm', onSavePress: () => __awaiter(this, void 0, void 0, function* () { return yield this.onSaveNewPassword(); }), initialPassword: this.state.userInput.password, onPasswordChanged: this.onPasswordChanged, initialEmail: this.state.userInput.email, onEmailChanged: this.onEmailChanged, code: this.state.code, onCodeChanged: (code) => this.setState({ code }) }))) : null,
                this.state.formState === 'Forgot' ? (React.createElement(View, { style: styles.container },
                    React.createElement(ForgotForm, Object.assign({ testID: 'ForgotForm', initialEmail: this.state.userInput.email, onEmailChanged: this.onEmailChanged, onSubmit: this.OnResetPassword, buttonProps: Object.assign({}, this.props.buttonProps, this.props.saveButtonProps) }, this.props), this.props.forgotChildren),
                    React.createElement(CrossButton, Object.assign({ style: styles.marginTop10, buttonStyle: styles.buttonStyle, onPress: () => this.setState({
                            formState: 'Login',
                        }), mode: 'contained', title: 'Cancel', backgroundColor: Colors.BackButton }, this.props.buttonProps, this.props.cancelButtonProps)))) : null,
                this.state.formState === 'ConfirmAccount' ? (React.createElement(View, { style: styles.container },
                    React.createElement(ConfirmForm, Object.assign({ testID: 'ConfirmAccountForm', code: this.state.code, onCodeChanged: (code) => this.setState({ code }), initialEmail: this.state.userInput.email, onEmailChanged: this.onEmailChanged, onConfirmPress: () => __awaiter(this, void 0, void 0, function* () { return yield this.onConfirmAccount(); }) }, this.props, { confirmButtonProps: Object.assign({}, this.props.buttonProps, this.props.saveButtonProps) }), this.props.confirmChildren),
                    React.createElement(CrossButton, Object.assign({ style: styles.marginTop10, buttonStyle: styles.buttonStyle, onPress: () => this.OnResendSignup(), mode: 'contained', title: 'Resend code', backgroundColor: Colors.CancelButton }, this.props.buttonProps, this.props.cancelButtonProps)))) : null,
                this.state.formState === 'ConfirmMFALogin' ? (React.createElement(ConfirmForm, Object.assign({ testID: 'ConfirmMFAForm', code: this.state.code, initialEmail: this.state.userInput.email, onEmailChanged: this.onEmailChanged, onConfirmPress: () => __awaiter(this, void 0, void 0, function* () { return yield this.onConfirmMFACode(); }), onCodeChanged: (code) => this.setState({ code }) }, this.props, { confirmButtonProps: Object.assign({}, this.props.buttonProps, this.props.saveButtonProps) }), this.props.confirmChildren)) : null,
                React.createElement(CrossLabel, { isCaption: true, style: { color: 'red' } }, (error || '').toString())));
        };
        this.ForgotPasswordAlertButton = {
            text: 'OK',
            onPress: () => __awaiter(this, void 0, void 0, function* () { return yield this.ForgotPasswordAsync(this.state.userInput.email || ''); }),
        };
        this.cancelAlertButton = {
            text: 'Cancel',
            onPress: () => console.log('Cancel Pressed'),
            style: 'cancel',
        };
        this.state = {
            result: undefined,
            userInput: { email: undefined, password: undefined },
            formState: 'Login',
            code: undefined,
            message: undefined,
        };
    }
}
export default CognitoLogin;
//# sourceMappingURL=CognitoLogin.js.map