"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 system_1 = require("@mui/system");
const styles_1 = require("@mui/material/styles");
const material_1 = require("@mui/material");
const react_intl_1 = require("react-intl");
const react_core_1 = require("@selfcommunity/react-core");
const classnames_1 = tslib_1.__importDefault(require("classnames"));
const constants_1 = require("./constants");
const BaseDialog_1 = tslib_1.__importDefault(require("../../shared/BaseDialog"));
const lab_1 = require("@mui/lab");
const ChangeGroupPicture_1 = tslib_1.__importDefault(require("../ChangeGroupPicture"));
const ChangeGroupCover_1 = tslib_1.__importDefault(require("../ChangeGroupCover"));
const Group_1 = require("../../constants/Group");
const GroupInviteButton_1 = tslib_1.__importDefault(require("../GroupInviteButton"));
const pubsub_js_1 = tslib_1.__importDefault(require("pubsub-js"));
const types_1 = require("@selfcommunity/types");
const Errors_1 = require("../../constants/Errors");
const api_services_1 = require("@selfcommunity/api-services");
const utils_1 = require("@selfcommunity/utils");
const PubSub_1 = require("../../constants/PubSub");
const messages = (0, react_intl_1.defineMessages)({
    name: {
        id: 'ui.groupForm.name.placeholder',
        defaultMessage: 'ui.groupForm.name.placeholder'
    },
    description: {
        id: 'ui.groupForm.description.placeholder',
        defaultMessage: 'ui.groupForm.description.placeholder'
    }
});
const classes = {
    root: `${constants_1.PREFIX}-root`,
    active: `${constants_1.PREFIX}-active`,
    title: `${constants_1.PREFIX}-title`,
    header: `${constants_1.PREFIX}-header`,
    cover: `${constants_1.PREFIX}-cover`,
    avatar: `${constants_1.PREFIX}-avatar`,
    form: `${constants_1.PREFIX}-form`,
    switch: `${constants_1.PREFIX}-switch`,
    switchLabel: `${constants_1.PREFIX}-switch-label`,
    name: `${constants_1.PREFIX}-name`,
    description: `${constants_1.PREFIX}-description`,
    content: `${constants_1.PREFIX}-content`,
    privacySection: `${constants_1.PREFIX}-privacy-section`,
    privacySectionInfo: `${constants_1.PREFIX}-privacy-section-info`,
    visibilitySection: `${constants_1.PREFIX}-visibility-section`,
    visibilitySectionInfo: `${constants_1.PREFIX}-visibility-section-info`,
    inviteSection: `${constants_1.PREFIX}-invite-section`,
    error: `${constants_1.PREFIX}-error`
};
const Root = (0, styles_1.styled)(BaseDialog_1.default, {
    name: constants_1.PREFIX,
    slot: 'Root'
})(() => ({}));
/**
 *> API documentation for the Community-JS  Group Form component. Learn about the available props and the CSS API.
 *
 #### Import
 ```jsx
 import {GroupForm} from '@selfcommunity/react-ui';
 ```

 #### Component Name
 The name `SCGroupForm` can be used when providing style overrides in the theme.

 #### CSS

 |Rule Name|Global class|Description|
 |---|---|---|
 |root|.SCGroupForm-root|Styles applied to the root element.|
 |active|.SCGroupForm-active|Styles applied to the  active element.|
 |title|.SCGroupForm-title|Styles applied to the title element.|
 |header|.SCGroupForm-header|Styles applied to the header element.|
 |cover|.SCGroupForm-cover|Styles applied to the cover field.|
 |avatar|.SCGroupForm-avatar|Styles applied to the avatar field.|
 |form|.SCGroupForm-form|Styles applied to the form element.|
 |switch|.SCGroupForm-switch|Styles applied to the switch element.|
 |switchLabel|.SCGroupForm-switch-label|Styles applied to the switchLabel element.|
 |name|.SCGroupForm-name|Styles applied to the name field.|
 |description|.SCGroupForm-description|Styles applied to the description field.|
 |content|.SCGroupForm-content|Styles applied to the  element.|
 |privacySection|.SCGroupForm-privacy-section|Styles applied to the privacy section.|
 |privacySectionInfo|.SCGroupForm-privacy-section-info|Styles applied to the privacy info section.|
 |visibilitySection|.SCGroupForm-visibility-section|Styles applied to the visibility section.|
 |visibilitySectionInfo|.SCGroupForm-visibility-section-info|Styles applied to the visibility section info.|
 |inviteSection|.SCGroupForm-invite-section|Styles applied to the invite section.|
 |error|.SCGroupForm-error|Styles applied to the error elements.|

 * @param inProps
 */
function GroupForm(inProps) {
    var _a, _b, _c, _d, _e;
    //PROPS
    const props = (0, system_1.useThemeProps)({
        props: inProps,
        name: constants_1.PREFIX
    });
    const { className, open = true, onClose, onSuccess, group = null } = props, rest = tslib_1.__rest(props, ["className", "open", "onClose", "onSuccess", "group"]);
    const initialFieldState = {
        imageOriginal: group ? group.image_medium : '',
        imageOriginalFile: '',
        emotionalImageOriginal: group ? group.emotional_image : '',
        emotionalImageOriginalFile: '',
        name: group ? group.name : '',
        description: group ? group.description : '',
        isPublic: group && group.privacy === types_1.SCGroupPrivacyType.PUBLIC,
        isVisible: group ? group.visible : true,
        invitedUsers: null,
        isSubmitting: false
    };
    // STATE
    const [field, setField] = (0, react_1.useState)(initialFieldState);
    const [error, setError] = (0, react_1.useState)({});
    // INTL
    const intl = (0, react_intl_1.useIntl)();
    // PREFERENCES
    const scPreferences = (0, react_core_1.useSCPreferences)();
    const visibilityEnabled = (0, react_1.useMemo)(() => scPreferences.preferences[react_core_1.SCPreferences.CONFIGURATIONS_GROUPS_VISIBILITY_ENABLED].value, [scPreferences.preferences]);
    const privateEnabled = (0, react_1.useMemo)(() => scPreferences.preferences[react_core_1.SCPreferences.CONFIGURATIONS_GROUPS_PRIVATE_ENABLED].value, [scPreferences.preferences]);
    const _backgroundCover = Object.assign({}, (field.emotionalImageOriginal
        ? { background: `url('${field.emotionalImageOriginal}') center / cover` }
        : { background: `url('${scPreferences.preferences[react_core_1.SCPreferences.IMAGES_USER_DEFAULT_COVER].value}') center / cover` }));
    function handleChangeAvatar(avatar) {
        setField((prev) => (Object.assign(Object.assign({}, prev), { ['imageOriginalFile']: avatar })));
        const reader = new FileReader();
        reader.onloadend = () => {
            setField((prev) => (Object.assign(Object.assign({}, prev), { ['imageOriginal']: reader.result })));
        };
        reader.readAsDataURL(avatar);
        if (error.imageOriginalError) {
            delete error.imageOriginalError;
            setError(error);
        }
    }
    function handleChangeCover(cover) {
        setField((prev) => (Object.assign(Object.assign({}, prev), { ['emotionalImageOriginalFile']: cover })));
        const reader = new FileReader();
        reader.onloadend = () => {
            setField((prev) => (Object.assign(Object.assign({}, prev), { ['emotionalImageOriginal']: reader.result })));
        };
        reader.readAsDataURL(cover);
        if (error.emotionalImageOriginalError) {
            delete error.emotionalImageOriginalError;
            setError(error);
        }
    }
    /**
     * Notify when a group info changed
     * @param data
     */
    function notifyChanges(data) {
        if (data) {
            if (group) {
                // Edit group
                pubsub_js_1.default.publish(`${PubSub_1.SCTopicType.GROUP}.${PubSub_1.SCGroupEventType.EDIT}`, data);
            }
            else {
                // Create group
                pubsub_js_1.default.publish(`${PubSub_1.SCTopicType.GROUP}.${PubSub_1.SCGroupEventType.CREATE}`, data);
            }
        }
    }
    const handleSubmit = () => {
        setField((prev) => (Object.assign(Object.assign({}, prev), { ['isSubmitting']: true })));
        const formData = new FormData();
        formData.append('name', field.name);
        formData.append('description', field.description);
        if (privateEnabled) {
            formData.append('privacy', field.isPublic ? types_1.SCGroupPrivacyType.PUBLIC : types_1.SCGroupPrivacyType.PRIVATE);
        }
        if (visibilityEnabled) {
            formData.append('visible', field.isVisible);
        }
        if (field.imageOriginalFile) {
            formData.append('image_original', field.imageOriginalFile);
        }
        if (field.emotionalImageOriginalFile) {
            formData.append('emotional_image_original', field.emotionalImageOriginalFile);
        }
        if (!group) {
            for (const key in field.invitedUsers) {
                formData.append(key, field.invitedUsers[key]);
            }
        }
        let groupService;
        if (group) {
            groupService = api_services_1.GroupService.updateGroup(group.id, formData, { headers: { 'Content-Type': 'multipart/form-data' } });
        }
        else {
            groupService = api_services_1.GroupService.createGroup(formData, { headers: { 'Content-Type': 'multipart/form-data' } });
        }
        groupService
            .then((data) => {
            onSuccess && onSuccess(data);
            notifyChanges(data);
            onClose && onClose();
            setField((prev) => (Object.assign(Object.assign({}, prev), { ['isSubmitting']: false })));
        })
            .catch((e) => {
            setError(Object.assign(Object.assign({}, error), (0, api_services_1.formatHttpErrorCode)(e)));
            setField((prev) => (Object.assign(Object.assign({}, prev), { ['isSubmitting']: false })));
            utils_1.Logger.error(Errors_1.SCOPE_SC_UI, e);
        });
    };
    const handleInviteSection = (data) => {
        setField((prev) => (Object.assign(Object.assign({}, prev), { ['invitedUsers']: data })));
    };
    const handleChange = (event) => {
        const { name, value } = event.target;
        setField((prev) => (Object.assign(Object.assign({}, prev), { [name]: value })));
        if (error[`${name}Error`]) {
            delete error[`${name}Error`];
            setError(error);
        }
    };
    /**
     * Renders root object
     */
    return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ DialogContentProps: { dividers: false }, title: group ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.title.edit", defaultMessage: "ui.groupForm.title.edit" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.title", defaultMessage: "ui.groupForm.title" })), open: open, onClose: onClose, className: (0, classnames_1.default)(classes.root, className), actions: (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, Object.assign({ loading: field.isSubmitting, disabled: !field.name ||
                Object.keys(error).length !== 0 ||
                field.name.length > Group_1.GROUP_TITLE_MAX_LENGTH ||
                field.name.description > Group_1.GROUP_DESCRIPTION_MAX_LENGTH, variant: "contained", onClick: handleSubmit, color: "secondary" }, { children: group ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.button.edit", defaultMessage: "ui.groupForm.button.edit" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.button.create", defaultMessage: "ui.groupForm.button.create" })) })) }, rest, { children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(material_1.Paper, Object.assign({ style: _backgroundCover, classes: { root: classes.cover } }, { children: [(0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.avatar }, { children: (0, jsx_runtime_1.jsx)(material_1.Avatar, { children: field.imageOriginal ? (0, jsx_runtime_1.jsx)("img", { src: field.imageOriginal, alt: "avatar" }) : (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "icon_image" }) }) })), (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ChangeGroupPicture_1.default, { isCreationMode: true, onChange: handleChangeAvatar }), (0, jsx_runtime_1.jsx)(ChangeGroupCover_1.default, { isCreationMode: true, onChange: handleChangeCover })] })] })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ className: (0, classnames_1.default)(classes.header, { [classes.error]: error.emotionalImageOriginalError || error.imageOriginalError }), align: "center" }, { children: error.emotionalImageOriginalError || error.imageOriginalError ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.header.error", defaultMessage: "ui.groupForm.header.error" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.header", defaultMessage: "ui.groupForm.header" })) }))] }), (0, jsx_runtime_1.jsxs)(material_1.FormGroup, Object.assign({ className: classes.form }, { children: [(0, jsx_runtime_1.jsx)(material_1.TextField, { required: true, className: classes.name, placeholder: `${intl.formatMessage(messages.name)}`, margin: "normal", value: field.name, name: "name", onChange: handleChange, InputProps: {
                                endAdornment: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: Group_1.GROUP_TITLE_MAX_LENGTH - field.name.length }))
                            }, error: Boolean(((_a = field === null || field === void 0 ? void 0 : field.name) === null || _a === void 0 ? void 0 : _a.length) > Group_1.GROUP_TITLE_MAX_LENGTH), helperText: ((_b = field === null || field === void 0 ? void 0 : field.name) === null || _b === void 0 ? void 0 : _b.length) > Group_1.GROUP_TITLE_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.name.error.maxLength", defaultMessage: "ui.groupForm.name.error.maxLength" })) : null }), (0, jsx_runtime_1.jsx)(material_1.TextField, { multiline: true, className: classes.description, placeholder: `${intl.formatMessage(messages.description)}`, margin: "normal", value: field.description, name: "description", onChange: handleChange, InputProps: {
                                endAdornment: ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2" }, { children: ((_c = field.description) === null || _c === void 0 ? void 0 : _c.length) ? Group_1.GROUP_DESCRIPTION_MAX_LENGTH - field.description.length : Group_1.GROUP_DESCRIPTION_MAX_LENGTH })))
                            }, error: Boolean(((_d = field.description) === null || _d === void 0 ? void 0 : _d.length) > Group_1.GROUP_DESCRIPTION_MAX_LENGTH), helperText: ((_e = field.description) === null || _e === void 0 ? void 0 : _e.length) > Group_1.GROUP_DESCRIPTION_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.description.error.maxLength", defaultMessage: "ui.groupForm.description.error.maxLength" })) : null }), privateEnabled && ((0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.privacySection }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h4" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.privacy.title", defaultMessage: "ui.groupForm.privacy.title", values: {
                                            // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                                            // @ts-ignore
                                            b: (chunks) => (0, jsx_runtime_1.jsx)("strong", { children: chunks })
                                        } }) })), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ direction: "row", spacing: 1, alignItems: "center" }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ className: (0, classnames_1.default)(classes.switchLabel, { [classes.active]: !field.isPublic }) }, { children: [(0, jsx_runtime_1.jsx)(material_1.Icon, { children: "private" }), (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.privacy.private", defaultMessage: "ui.groupForm.privacy.private" })] })), (0, jsx_runtime_1.jsx)(material_1.Switch, { className: classes.switch, checked: field.isPublic, onChange: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['isPublic']: !field.isPublic }))), disabled: group && group.privacy === types_1.SCGroupPrivacyType.PRIVATE }), (0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ className: (0, classnames_1.default)(classes.switchLabel, { [classes.active]: field.isPublic }) }, { children: [(0, jsx_runtime_1.jsx)(material_1.Icon, { children: "public" }), (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.privacy.public", defaultMessage: "ui.groupForm.privacy.public" })] }))] })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2", className: classes.privacySectionInfo }, { children: field.isPublic ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.privacy.public.info", defaultMessage: "ui.groupForm.privacy.public.info", values: {
                                            // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                                            // @ts-ignore
                                            b: (chunks) => (0, jsx_runtime_1.jsx)("strong", { children: chunks })
                                        } })) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: group && group.privacy === types_1.SCGroupPrivacyType.PRIVATE ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.privacy.private.info.edit", defaultMessage: "ui.groupForm.private.public.info.edit", values: {
                                                // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                                                // @ts-ignore
                                                b: (chunks) => (0, jsx_runtime_1.jsx)("strong", { children: chunks })
                                            } })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.privacy.private.info", defaultMessage: "ui.groupForm.private.public.info", values: {
                                                // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                                                // @ts-ignore
                                                b: (chunks) => (0, jsx_runtime_1.jsx)("strong", { children: chunks })
                                            } })) })) }))] }))), privateEnabled && visibilityEnabled && ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.visibilitySection }, { children: ((!field.isPublic && !group) || (group && !field.isPublic)) && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h4" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.visibility.title", defaultMessage: "ui.groupForm.visibility.title", values: {
                                                // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                                                // @ts-ignore
                                                b: (chunks) => (0, jsx_runtime_1.jsx)("strong", { children: chunks })
                                            } }) })), (0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ direction: "row", spacing: 1, alignItems: "center" }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ className: (0, classnames_1.default)(classes.switchLabel, { [classes.active]: !field.isVisible }) }, { children: [(0, jsx_runtime_1.jsx)(material_1.Icon, { children: "visibility_off" }), (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.visibility.hidden", defaultMessage: "ui.groupForm.visibility.hidden" })] })), (0, jsx_runtime_1.jsx)(material_1.Switch, { className: classes.switch, checked: field.isVisible, onChange: () => setField((prev) => (Object.assign(Object.assign({}, prev), { ['isVisible']: !field.isVisible }))) }), (0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ className: (0, classnames_1.default)(classes.switchLabel, { [classes.active]: field.isVisible }) }, { children: [(0, jsx_runtime_1.jsx)(material_1.Icon, { children: "visibility" }), (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.visibility.visible", defaultMessage: "ui.groupForm.visibility.visible" })] }))] })), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2", className: classes.visibilitySectionInfo }, { children: !field.isVisible ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.visibility.hidden.info", defaultMessage: "ui.groupForm.visibility.hidden.info", values: {
                                                // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                                                // @ts-ignore
                                                b: (chunks) => (0, jsx_runtime_1.jsx)("strong", { children: chunks })
                                            } })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.groupForm.visibility.visible.info", defaultMessage: "ui.groupForm.visibility.visible.info", values: {
                                                // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                                                // @ts-ignore
                                                b: (chunks) => (0, jsx_runtime_1.jsx)("strong", { children: chunks })
                                            } })) }))] })) })))] })), !group && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Divider, {}), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.inviteSection }, { children: (0, jsx_runtime_1.jsx)(GroupInviteButton_1.default, { handleInvitations: handleInviteSection }) }))] }))] }) })));
}
exports.default = GroupForm;
