import { useSnackbar } from 'notistack';
import React, { useCallback, useEffect, useRef, useState, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { UserFormFields } from './form/UserFormFields';
import { Field, Form } from '../../../utilities/form';
import { FluentTextField } from '../../../UI/inputs/textField';
import { UdpStepper } from '../../../UI';
const USER_EMAIL_STEP = 0;
const USER_INFO_STEP = 1;
export const AddUser = props => {
    const { getUserByEmail, handleCreateUser, handleUpdateAndAddToTenant, rolesData, setSidesheetLoading, sidesheetLoading, altFieldMapping, } = props;
    const userMapping = useMemo(() => {
        if (altFieldMapping) {
            return altFieldMapping;
        }
        else {
            // Default mapping for code generated User object
            return {
                userId: 'userId',
                firstName: 'firstName',
                lastName: 'lastName',
                email: 'email',
                roles: 'systemWideSecurityRoles',
            };
        }
    }, [altFieldMapping]);
    const { t } = useTranslation();
    const { enqueueSnackbar } = useSnackbar();
    const [activeStep, setActiveStep] = useState(USER_EMAIL_STEP);
    const [completed, setCompleted] = useState({});
    const [existingUser, setExistingUser] = useState(null);
    const [passwordType, setPasswordType] = useState('autoGeneratePassword'); // 'autoGeneratePassword' | 'createPassword'
    const [creationMethod, setCreationMethod] = useState('standard'); // 'standard' | 'invite'
    const handleSubmitRef = useRef(null);
    const emailFieldRef = useRef(null);
    const handlePasswordTypeChange = useCallback(event => {
        setPasswordType(event.target.value);
    }, []);
    const handleCreationMethodChange = useCallback(event => {
        setCreationMethod(event.target.value);
    }, []);
    const [steps, setSteps] = useState([
        {
            stepDisplay: {
                inProcessIcon: '1',
                completeIcon: '✓',
                title: t('Enter Email'),
                subTitle: t('Enter the email you will use to log in'),
            },
            stepTitle: 'Step 1',
            showTitle: 'true',
            buttons: [],
        },
        {
            stepDisplay: {
                inProcessIcon: '2',
                completeIcon: '✓',
                title: t('User Info'),
                subTitle: t('Fill in additional info for the new user'),
            },
            stepTitle: 'Step 2',
            showTitle: 'true',
            buttons: [],
        },
    ]);
    const goToEmailStep = useCallback(() => {
        setExistingUser(null);
        setCompleted(prev => (Object.assign(Object.assign({}, prev), { [USER_INFO_STEP]: false })));
        setActiveStep(USER_EMAIL_STEP);
    }, []);
    const goToInfoStep = useCallback(async () => {
        const email = emailFieldRef.current.value;
        setExistingUser(null);
        setSidesheetLoading(true);
        const existingUserResponse = await getUserByEmail(email);
        const user = existingUserResponse.data;
        if (user) {
            setExistingUser(user);
        }
        setSidesheetLoading(false);
        setCompleted(prev => (Object.assign(Object.assign({}, prev), { [USER_EMAIL_STEP]: true })));
        setActiveStep(USER_INFO_STEP);
    }, [getUserByEmail, setSidesheetLoading]);
    const onSubmit = useCallback(async values => {
        setSidesheetLoading(true);
        if (creationMethod === 'invite') {
            values.isInvite = true;
        }
        else {
            values.isInvite = false;
        }
        if (passwordType === 'autoGeneratePassword') {
            values.passwordProfile = null;
        }
        if (values.email) {
            values.email = values.email.toLowerCase().trim();
        }
        try {
            if (existingUser) {
                // Set the new values onto the existing user values
                // eslint-disable-next-line react-hooks/immutability
                existingUser[userMapping.firstName] = values[userMapping.firstName];
                existingUser[userMapping.lastName] = values[userMapping.lastName];
                existingUser[userMapping.roles] = values[userMapping.roles];
                await handleUpdateAndAddToTenant(existingUser[userMapping.userId], existingUser);
            }
            else {
                await handleCreateUser(values);
            }
        }
        catch (err) {
            enqueueSnackbar(err.message, {
                variant: 'error',
                anchorOrigin: {
                    vertical: 'top',
                    horizontal: 'center',
                },
            });
        }
        setSidesheetLoading(false);
    }, [
        existingUser,
        enqueueSnackbar,
        handleCreateUser,
        handleUpdateAndAddToTenant,
        setSidesheetLoading,
        creationMethod,
        passwordType,
        userMapping
    ]);
    const submitForm = useCallback(() => {
        if (handleSubmitRef.current) {
            handleSubmitRef.current();
        }
    }, []);
    // Inject the button definitions to prevent constant re-creation of customAction callbacks
    useEffect(() => {
        setSteps(prev => {
            const updated = [...prev];
            updated[USER_EMAIL_STEP].buttons = [
                {
                    title: t('Next'),
                    action: 2,
                    variant: 'outline',
                    customAction: goToInfoStep,
                },
            ];
            updated[USER_INFO_STEP].buttons = [
                {
                    title: t('Back'),
                    action: 1,
                    variant: 'outline',
                    customAction: goToEmailStep,
                },
                {
                    title: t('Create user'),
                    action: 3,
                    variant: 'outline',
                    customAction: submitForm,
                    disabled: sidesheetLoading,
                },
            ];
            return updated;
        });
    }, [goToInfoStep, goToEmailStep, submitForm, t, sidesheetLoading]);
    useEffect(() => {
        if (existingUser) {
            setSteps(prev => {
                const updated = [...prev];
                updated[USER_INFO_STEP].stepDisplay.subTitle = t('A user with that email already exists. Edit values before adding to the tenant');
                updated[USER_INFO_STEP].buttons[1].title = t('Add user to tenant');
                return updated;
            });
        }
        else {
            setSteps(prev => {
                const updated = [...prev];
                updated[USER_INFO_STEP].stepDisplay.subTitle = t('Fill in additional info for the new user');
                updated[USER_INFO_STEP].buttons[1].title = t('Create user');
                return updated;
            });
        }
    }, [existingUser, t]);
    return (React.createElement(Form, { onSubmit: onSubmit, render: ({ handleSubmit }) => {
            handleSubmitRef.current = handleSubmit;
            return (React.createElement(UdpStepper, { steps: steps, activeStep: activeStep, completed: completed, orientation: "vertical", labelDisplay: "all", labelPosition: "right" }, activeStep === 0 && (React.createElement(Field, { ref: emailFieldRef, component: FluentTextField, label: t('Email'), id: "email", name: "email", fullWidth: true, variant: "outlined", margin: "normal", size: "small", required: true, validate: value => {
                    if (!/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(value) ||
                        64 < value.split('@')[0].length) {
                        return t('Invalid email address');
                    }
                }, onKeyDown: e => {
                    if (e.key === 'Enter') {
                        e.preventDefault();
                        goToInfoStep();
                    }
                } })), activeStep === 1 && (React.createElement(UserFormFields, { rolesData: rolesData, editedUser: existingUser, handlePasswordTypeChange: handlePasswordTypeChange, passwordType: passwordType, handleCreationMethodChange: handleCreationMethodChange, creationMethod: creationMethod, hideEmailField: true, altFieldMapping: altFieldMapping }))));
        } }));
};
export default AddUser;
//# sourceMappingURL=AddUser.js.map