"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const styles_1 = require("@mui/material/styles");
const material_1 = require("@mui/material");
const Icon_1 = tslib_1.__importDefault(require("@mui/material/Icon"));
const react_intl_1 = require("react-intl");
const api_services_1 = require("@selfcommunity/api-services");
const utils_1 = require("@selfcommunity/utils");
const react_core_1 = require("@selfcommunity/react-core");
const UserProfile_1 = require("../../../constants/UserProfile");
const classnames_1 = tslib_1.__importDefault(require("classnames"));
const x_date_pickers_1 = require("@mui/x-date-pickers");
const AdapterDateFns_1 = require("@mui/x-date-pickers/AdapterDateFns");
const UsernameTextField_1 = tslib_1.__importDefault(require("../../../shared/UsernameTextField"));
const use_deep_compare_effect_1 = require("use-deep-compare-effect");
const types_1 = require("../../../types");
const MetadataField_1 = tslib_1.__importDefault(require("../../../shared/MetadataField"));
const Errors_1 = require("../../../constants/Errors");
const date_fns_1 = require("date-fns");
const it_1 = tslib_1.__importDefault(require("date-fns/locale/it"));
const en_US_1 = tslib_1.__importDefault(require("date-fns/locale/en-US"));
const lab_1 = require("@mui/lab");
const notistack_1 = require("notistack");
const constants_1 = require("../constants");
const messages = (0, react_intl_1.defineMessages)({
    genderMale: {
        id: 'ui.userProfileEditPublicInfo.genderMale',
        defaultMessage: 'ui.userProfileEditPublicInfo.genderMale'
    },
    genderFemale: {
        id: 'ui.userProfileEditPublicInfo.genderFemale',
        defaultMessage: 'ui.userProfileEditPublicInfo.genderFemale'
    },
    genderUnspecified: {
        id: 'ui.userProfileEditPublicInfo.genderUnspecified',
        defaultMessage: 'ui.userProfileEditPublicInfo.genderUnspecified'
    }
});
const classes = {
    root: `${constants_1.PREFIX}-public-info-root`,
    field: `${constants_1.PREFIX}-field`,
    btnSave: `${constants_1.PREFIX}-btn-save`
};
const Root = (0, styles_1.styled)(material_1.Box, {
    name: constants_1.PREFIX,
    slot: 'PublicInfoRoot'
})(() => ({}));
const GENDERS = ['Male', 'Female', 'Unspecified'];
const DATEPICKER_MINDATE = new Date(1000, 1, 1);
function PublicInfo(props) {
    // PROPS
    const { id = null, className = null, fields = [...UserProfile_1.DEFAULT_FIELDS], onEditSuccess = null, onEditFailure = null, startActions = null, endActions = null } = props, rest = tslib_1.__rest(props, ["id", "className", "fields", "onEditSuccess", "onEditFailure", "startActions", "endActions"]);
    // CONTEXT
    const scContext = (0, react_core_1.useSCContext)();
    const scUserContext = (0, react_core_1.useSCUser)();
    const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
    // PREFERENCES
    const scPreferences = (0, react_core_1.useSCPreferences)();
    const metadataDefinitions = (0, react_1.useMemo)(() => {
        if (scPreferences.preferences && react_core_1.SCPreferences.CONFIGURATIONS_USER_METADATA_DEFINITIONS in scPreferences.preferences) {
            try {
                return JSON.parse(scPreferences.preferences[react_core_1.SCPreferences.CONFIGURATIONS_USER_METADATA_DEFINITIONS].value);
            }
            catch (e) {
                utils_1.Logger.error(Errors_1.SCOPE_SC_UI, 'Error on parse user metadata.');
                return {};
            }
        }
        return null;
    }, [scPreferences.preferences]);
    // STATE
    const theme = (0, material_1.useTheme)();
    const isMobile = (0, material_1.useMediaQuery)(theme.breakpoints.down('md'));
    const [user, setUser] = (0, react_1.useState)();
    const [error, setError] = (0, react_1.useState)({});
    const [editing, setEditing] = (0, react_1.useState)([]);
    const [saving, setSaving] = (0, react_1.useState)([]);
    // INTL
    const intl = (0, react_intl_1.useIntl)();
    // EFFECTS
    (0, use_deep_compare_effect_1.useDeepCompareEffectNoCheck)(() => {
        if (scUserContext.user) {
            setUser(Object.assign({}, scUserContext.user));
            // eslint-disable-next-line @typescript-eslint/no-empty-function
            return () => { };
        }
    }, [scUserContext.user]);
    // HANDLERS
    const handleSave = () => {
        setSaving([...editing]);
        setError({});
        const data = {};
        editing.map((f) => {
            data[f] = f === types_1.SCUserProfileFields.DATE_OF_BIRTH && user[f] ? (0, date_fns_1.format)(user[f], 'yyyy-MM-dd') : user[f];
        });
        api_services_1.http
            .request({
            url: api_services_1.Endpoints.UserPatch.url({ id: user.id }),
            method: api_services_1.Endpoints.UserPatch.method,
            data
        })
            .then((res) => {
            scUserContext.updateUser(res.data);
            setEditing([]);
            setSaving([]);
            enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.userInfo.save.success", defaultMessage: "ui.userInfo.save.success" }), {
                variant: 'success',
                autoHideDuration: 3000
            });
            onEditSuccess && onEditSuccess();
        })
            .catch((e) => {
            setError(Object.assign(Object.assign({}, error), (0, api_services_1.formatHttpErrorCode)(e)));
            setSaving([]);
            enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), {
                variant: 'error',
                autoHideDuration: 3000
            });
            onEditFailure && onEditFailure();
        });
    };
    const handleChange = (field) => {
        return (event) => {
            setUser(Object.assign(Object.assign({}, user), { [event.target.name]: event.target.value }));
            setEditing([...editing, field]);
            if (!event.target.value && event.target.name in metadataDefinitions && metadataDefinitions[event.target.name].mandatory) {
                setError(Object.assign(Object.assign({}, error), { [`${(0, utils_1.camelCase)(event.target.name)}Error`]: { error: 'invalid' } }));
            }
            else if (error[`${(0, utils_1.camelCase)(event.target.name)}Error`]) {
                delete error[`${(0, utils_1.camelCase)(event.target.name)}Error`];
                setError(error);
            }
        };
    };
    // RENDER
    const renderField = (field) => {
        const isEditing = editing.includes(field);
        const isSaving = saving.includes(field);
        const camelField = (0, utils_1.camelCase)(field);
        const _error = error !== null && error[`${camelField}Error`] && error[`${camelField}Error`].error;
        const component = { element: material_1.TextField };
        let label = metadataDefinitions[field]
            ? metadataDefinitions[field].label
            : intl.formatMessage({
                id: `ui.userInfo.${camelField}`,
                defaultMessage: `ui.userInfo.${camelField}`
            });
        let props = {
            InputProps: {
                endAdornment: (0, jsx_runtime_1.jsx)(material_1.InputAdornment, Object.assign({ position: "end" }, { children: isSaving && (0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 10 }) }))
            }
        };
        let content = null;
        switch (field) {
            case types_1.SCUserProfileFields.USERNAME:
                component.element = UsernameTextField_1.default;
                break;
            case types_1.SCUserProfileFields.DATE_JOINED:
                return null;
            case types_1.SCUserProfileFields.DATE_OF_BIRTH:
                return ((0, jsx_runtime_1.jsx)(x_date_pickers_1.LocalizationProvider, Object.assign({ dateAdapter: AdapterDateFns_1.AdapterDateFns, adapterLocale: scContext.settings.locale.default === 'it' ? it_1.default : en_US_1.default }, { children: (0, jsx_runtime_1.jsx)(x_date_pickers_1.DatePicker, { label: intl.formatMessage({
                            id: `ui.userInfo.${(0, utils_1.camelCase)(field)}`,
                            defaultMessage: `ui.userInfo.${field}`
                        }), defaultValue: user[field] ? (0, date_fns_1.parseISO)(user[field]) : null, minDate: DATEPICKER_MINDATE, onChange: (newValue) => {
                            const u = user;
                            const field = types_1.SCUserProfileFields.DATE_OF_BIRTH;
                            const camelField = (0, utils_1.camelCase)(field);
                            if (((0, date_fns_1.isValid)(newValue) && (0, date_fns_1.isBefore)((0, date_fns_1.startOfHour)(DATEPICKER_MINDATE), newValue) && (0, date_fns_1.isBefore)(newValue, new Date())) || !newValue) {
                                if (error[`${camelField}Error`]) {
                                    const _error = Object.assign({}, error);
                                    delete _error[`${camelField}Error`];
                                    setError(_error);
                                }
                                u[field] = newValue;
                            }
                            else {
                                u[field] = null;
                                setError({
                                    [`${camelField}Error`]: {
                                        error: intl.formatMessage({ id: 'ui.publicInfo.dateOfBirth.error', defaultMessage: 'ui.publicInfo.dateOfBirth.error' })
                                    }
                                });
                            }
                            setUser(u);
                            setEditing([...editing, field]);
                        }, disableFuture: true, disabled: isSaving, slots: {
                            inputAdornment: (params) => {
                                // eslint-disable-next-line @typescript-eslint/ban-ts-ignore,@typescript-eslint/ban-ts-comment
                                // @ts-ignore
                                const _a = params.children.props, { children } = _a, rest = tslib_1.__rest(_a, ["children"]);
                                return ((0, jsx_runtime_1.jsxs)(material_1.InputAdornment, Object.assign({ position: 'end' }, { children: [(0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({}, rest, { children: children })), isSaving && (0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 10 })] })));
                            }
                        }, 
                        // onAccept={isMobile ? handleSave(SCUserProfileFields.DATE_OF_BIRTH) : null}
                        slotProps: {
                            textField: {
                                className: classes.field,
                                fullWidth: true,
                                variant: 'outlined',
                                helperText: _error || null,
                                InputProps: {
                                    endAdornment: isMobile && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ disabled: !isEditing }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "CalendarIcon" }) })), isSaving ? (0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 10 }) : null] }))
                                }
                            }
                        } }) }), field));
            case types_1.SCUserProfileFields.BIO:
                props.multiline = true;
                break;
            case types_1.SCUserProfileFields.WEBSITE:
                props.type = 'url';
                props.pattern = 'https://.*';
                props.size = '30';
                break;
            case types_1.SCUserProfileFields.GENDER:
                props.select = true;
                content = GENDERS.map((gender) => ((0, jsx_runtime_1.jsx)(material_1.MenuItem, Object.assign({ value: gender }, { children: intl.formatMessage(messages[`gender${gender}`]) }), gender)));
                break;
            case types_1.SCUserProfileFields.TAGS:
                return null;
            default:
                if (metadataDefinitions && metadataDefinitions[field]) {
                    return ((0, jsx_runtime_1.jsx)(MetadataField_1.default, Object.assign({ id: field, className: classes.field, name: field, fullWidth: true, label: label, value: user[field] || '', onChange: handleChange(field), disabled: isSaving || (user[field] && 'editable' in metadataDefinitions[field] && !metadataDefinitions[field].editable && !isEditing), error: Boolean(_error), helperText: _error && (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.userInfo.metadata.error.${_error}`, defaultMessage: `ui.userInfo.metadata.error.${_error}` }), metadata: metadataDefinitions[field] }, props), field));
                }
                break;
        }
        return ((0, jsx_runtime_1.jsx)(component.element, Object.assign({ id: field }, props, { className: classes.field, name: field, fullWidth: true, label: label, value: user[field] || '', onChange: handleChange(field), disabled: isSaving, error: Boolean(_error), helperText: _error && (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: `ui.userInfo.${camelField}.error.${_error}`, defaultMessage: `ui.userInfo.${camelField}.error.${_error}` }) }, { children: content }), field));
    };
    // FIELDS
    const _fields = [...fields, ...Object.keys(metadataDefinitions)];
    if (_fields.length === 0 || !user) {
        return null;
    }
    return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className) }, rest, { children: [startActions, _fields.map((field) => {
                return renderField(field);
            }), (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ className: classes.btnSave, fullWidth: true, variant: "contained", color: "secondary", onClick: handleSave, loading: saving.length > 0, disabled: saving.length > 0 || !editing.length || Object.keys(error).length > 0 }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: 'ui.userInfo.button.save', defaultMessage: 'ui.userInfo.button.save' }) })), endActions] })));
}
exports.default = PublicInfo;
