import React, { forwardRef, useCallback, useImperativeHandle, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { FormControlLabel, makeStyles, Switch } from '@material-ui/core';
import { arrayMutators, Field, Form } from '../../../../utilities/form';
import { AmbientAutoComplete, FluentTextField } from '../../../../UI/inputs/textField';
import { LayoutUnit } from '../../../../layout';
import { FluentButton } from '../../../../UI/inputs/buttons';
import { FieldArray } from 'react-final-form-arrays';
import { StatusCircleErrorXIcon } from '@fluentui/react-icons';
import UdpTransactionTypePageConfigurationSidesheet from '../sidesheets/UdpTransactionTypePageConfigurationSidesheet';
import UdpTransactionTypeCalendarViewConfigurationSidesheet from '../sidesheets/UdpTransactionTypeCalendarViewConfigurationSidesheet';
import { DISABLE_ORDERING_FOR_FIELDS, REQUIRED_COLUMN_DEF_FIELDS, REQUIRED_COLUMN_DEF_MAPPING } from '../UdpTransactionTypesPage';
import { UdpSearchEnums } from '../../../../enums';
const useStyles = makeStyles((theme) => ({
    domainFields: {
        display: 'flex',
        flexDirection: 'row',
        alignItems: 'flex-end',
        justifyContent: 'flex-start',
        '& > *': {
            marginRight: theme.spacing(2)
        }
    },
    domainValueField: {
        minWidth: '150px'
    },
    addRemoveButtons: {
        display: 'flex',
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'flex-start',
        margin: `${theme.spacing(2)}px  0  0 ${-theme.spacing(2)}px`,
        '& > *': {
            margin: `0 ${theme.spacing(2)}px`
        }
    },
    deleteActionSlot: {
        width: theme.spacing(3.5),
        display: 'flex',
        justifyContent: 'center',
        flexShrink: 0
    },
    switchColumn: {
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        width: theme.spacing(6),
        flexShrink: 0
    },
    removeIcon: {
        fontSize: theme.spacing(3.5),
        cursor: 'pointer',
        color: theme.palette.text.secondary,
        '&:hover': {
            color: theme.palette.error.main
        }
    }
}));
const buildRequiredColumnDefFields = () => REQUIRED_COLUMN_DEF_FIELDS.map((key) => {
    var _a;
    return [
        key,
        {
            displayName: ((_a = REQUIRED_COLUMN_DEF_MAPPING[key]) === null || _a === void 0 ? void 0 : _a.displayName) || key,
            order: 0,
            hide: false
        }
    ];
});
/**
 * Checks for the UDP prefix, strips it if present, and returns the result.
 * @param {string} value - The string to process.
 * @returns {string} The shortened string or the original if no prefix found.
 */
const stripUdpPrefix = (value) => {
    if (typeof value !== 'string')
        return value;
    if (value.startsWith(UdpSearchEnums.UdpBusinessDomainPrefix)) {
        return value.slice(UdpSearchEnums.UdpBusinessDomainPrefix.length + 1); // + 1 to skip the underscore that follows the prefix
    }
    return value;
};
const computeInitialValues = (initialData, domainNameOptions, domainFieldOptions, selectedDomainName) => {
    var _a, _b;
    let formattedData;
    const requiredFields = buildRequiredColumnDefFields();
    // Add required Transaction fields when creating a new TransactionType
    if (!initialData) {
        return {
            domainFields: requiredFields
        };
    }
    // Map existing DomainFields from initialData
    // Pull the data from the TransactionType.PageConfiguration, if it exists, otherwise pull the data from TransactionType.DomainFields
    let domainFieldsDatasource = ((_a = initialData === null || initialData === void 0 ? void 0 : initialData.pageConfiguration) === null || _a === void 0 ? void 0 : _a.columnDefProperties)
        ? (_b = initialData === null || initialData === void 0 ? void 0 : initialData.pageConfiguration) === null || _b === void 0 ? void 0 : _b.columnDefProperties
        : initialData === null || initialData === void 0 ? void 0 : initialData.domainFields;
    const existingDomainFields = selectedDomainName === (initialData === null || initialData === void 0 ? void 0 : initialData.domainName) && domainFieldsDatasource
        ? Object.entries(domainFieldsDatasource).map(([fieldKey, fieldConfig]) => {
            const fieldKeyWithoutPrefix = stripUdpPrefix(fieldKey);
            const normalizedFieldConfig = fieldConfig && typeof fieldConfig === 'object'
                ? fieldConfig
                : { value: fieldConfig };
            return [
                fieldKeyWithoutPrefix,
                Object.assign({}, normalizedFieldConfig)
            ];
        })
        : [[]];
    // Find which required Transaction fields are missing from the existing DomainFields
    const existingKeys = existingDomainFields.map((field) => field[0]);
    const missingTransactionFields = REQUIRED_COLUMN_DEF_FIELDS.filter((key) => !existingKeys.includes(key)).map((key) => {
        var _a;
        return [
            key,
            {
                displayName: ((_a = REQUIRED_COLUMN_DEF_MAPPING[key]) === null || _a === void 0 ? void 0 : _a.displayName) || key,
                order: 0,
                hide: false
            }
        ];
    });
    formattedData = Object.assign(Object.assign({}, initialData), { domainName: domainNameOptions === null || domainNameOptions === void 0 ? void 0 : domainNameOptions.find((domainName) => domainName === selectedDomainName || ''), domainFieldType: domainFieldOptions === null || domainFieldOptions === void 0 ? void 0 : domainFieldOptions.find((domainField) => domainField === (initialData === null || initialData === void 0 ? void 0 : initialData.domainFieldType)), domainFieldLabel: (domainFieldOptions === null || domainFieldOptions === void 0 ? void 0 : domainFieldOptions.find((domainField) => domainField === (initialData === null || initialData === void 0 ? void 0 : initialData.domainFieldLabel))) || (initialData === null || initialData === void 0 ? void 0 : initialData.domainFieldLabel), revisionField: domainFieldOptions === null || domainFieldOptions === void 0 ? void 0 : domainFieldOptions.find((domainField) => domainField === (initialData === null || initialData === void 0 ? void 0 : initialData.revisionField)), 
        // Transaction fields are added here first in order to ensure they render first in the form
        domainFields: [...missingTransactionFields, ...existingDomainFields] });
    return formattedData;
};
const UdpTransactionTypeForm = (props, ref) => {
    const { onSubmit, initialData, disableSubTypeFields, domainNameOptions, onSelectDomainName, domainFieldOptions, dateDomainFieldOptions, selectedDomainName, isPageConfigOpen, setIsPageConfigOpen, isCalendarViewConfigOpen, setIsCalendarViewConfigOpen } = props;
    const handleSubmitRef = useRef();
    const { t } = useTranslation();
    const classes = useStyles();
    const [formInitialValues] = useState(() => {
        return computeInitialValues(initialData, domainNameOptions, domainFieldOptions, selectedDomainName);
    });
    useImperativeHandle(ref, () => ({
        submit: () => {
            // eslint-disable-next-line no-unused-expressions
            handleSubmitRef === null || handleSubmitRef === void 0 ? void 0 : handleSubmitRef.current();
        }
    }));
    const handleSubmit = useCallback((formData) => {
        onSubmit(formData, initialData);
    }, [initialData, onSubmit]);
    return (React.createElement(Form, { onSubmit: handleSubmit, mutators: Object.assign({}, arrayMutators), initialValues: Object.assign({}, formInitialValues), render: ({ handleSubmit, form }) => {
            var _a, _b, _c, _d;
            var _e;
            handleSubmitRef.current = handleSubmit;
            const push = (_e = (_a = form === null || form === void 0 ? void 0 : form.mutators) === null || _a === void 0 ? void 0 : _a.push) !== null && _e !== void 0 ? _e : (() => { });
            const handleDomainNameChange = (value) => {
                var _a;
                const nextDomainName = value || '';
                const currentDomainName = ((_a = form.getState().values) === null || _a === void 0 ? void 0 : _a.domainName) || '';
                if (currentDomainName !== nextDomainName) {
                    onSelectDomainName === null || onSelectDomainName === void 0 ? void 0 : onSelectDomainName(nextDomainName);
                    form.change('domainFields', [...buildRequiredColumnDefFields()]);
                }
            };
            const handleDomainFieldTypeChange = (value) => {
                if (!value) {
                    form.change('domainFieldValue', '');
                }
            };
            const hasRevision = !!((_b = form.getState().values) === null || _b === void 0 ? void 0 : _b.hasRevision);
            const hasDomainFieldType = !!((_c = form.getState().values) === null || _c === void 0 ? void 0 : _c.domainFieldType);
            const parseHasRevision = (value) => {
                const nextValue = (value === null || value === void 0 ? void 0 : value.target) ? !!value.target.checked : !!value;
                if (!nextValue) {
                    form.change('revisionField', null);
                }
                return nextValue;
            };
            const isCalendarViewEnabled = !!((_d = form.getState().values) === null || _d === void 0 ? void 0 : _d.calendarViewEnabled);
            const handleCalendarViewEnabledChange = (event) => {
                if (!event.target.checked) {
                    form.change('isDefaultView', false);
                    form.change('defaultCalendarViewType', '');
                    form.change('domainStartDateProperty', '');
                    form.change('domainEndDateProperty', '');
                    form.change('domainPropertyToDisplay', '');
                }
            };
            return (React.createElement(React.Fragment, null, React.createElement(Field, { component: FluentTextField, label: t('Name'), id: "name", name: "name", fullWidth: true, variant: "outlined", margin: "normal", size: "small", required: true }), React.createElement(Field, { component: AmbientAutoComplete, label: t('Domain'), id: "domainName", name: "domainName", variant: "outlined", isMultiple: false, disableCloseOnSelect: false, options: domainNameOptions || [], getOptionLabelFunction: (option) => option, additionalOnChangeAction: handleDomainNameChange }), React.createElement(Field, { component: AmbientAutoComplete, label: "Sub-Type", id: "domainFieldType", name: "domainFieldType", variant: "outlined", isMultiple: false, disableCloseOnSelect: false, options: domainFieldOptions || [], getOptionLabelFunction: (option) => option, additionalOnChangeAction: handleDomainFieldTypeChange, disabled: disableSubTypeFields }), hasDomainFieldType && (React.createElement(Field, { component: FluentTextField, label: t('Sub-Type Value'), id: "domainFieldValue", name: "domainFieldValue", fullWidth: true, variant: "outlined", margin: "normal", size: "small", disabled: disableSubTypeFields })), React.createElement(Field, { component: AmbientAutoComplete, label: t('Field Label'), id: "domainFieldLabel", name: "domainFieldLabel", variant: "outlined", isMultiple: false, disableCloseOnSelect: false, options: domainFieldOptions || [], getOptionLabelFunction: (option) => option, helperText: t('Field property to be used in transaction page labels'), freeSolo: true }), React.createElement(LayoutUnit, { unit: "nudge" }), React.createElement(FormControlLabel, { control: React.createElement(Field, { component: Switch, id: "archiveOnCancel", name: "archiveOnCancel", type: "checkbox" }), label: t('Archive on Cancel') }), React.createElement(LayoutUnit, { unit: "nudge" }), React.createElement(FormControlLabel, { control: React.createElement(Field, { component: Switch, id: "enabled", name: "enabled", type: "checkbox" }), label: t('Enabled') }), React.createElement(LayoutUnit, { unit: "nudge" }), React.createElement(FormControlLabel, { control: React.createElement(Field, { component: Switch, id: "hasRevision", name: "hasRevision", type: "checkbox", parse: parseHasRevision }), label: t('Allow Revisions') }), hasRevision && (React.createElement(Field, { component: AmbientAutoComplete, label: "Revision Field", id: "revisionField", name: "revisionField", variant: "outlined", isMultiple: false, disableCloseOnSelect: false, options: domainFieldOptions || [], getOptionLabelFunction: (option) => option })), React.createElement("div", { className: classes.addRemoveButtons }, React.createElement(FluentButton, { variant: "contained", color: "primary", onClick: () => setIsPageConfigOpen(true) }, t('Additional Configuration')), React.createElement(FluentButton, { variant: "contained", color: "primary", onClick: () => setIsCalendarViewConfigOpen(true) }, t('Calendar View Configuration'))), React.createElement(UdpTransactionTypePageConfigurationSidesheet, { initialData: initialData, isSidesheetOpen: isPageConfigOpen, setIsSidesheetOpen: setIsPageConfigOpen }), React.createElement(UdpTransactionTypeCalendarViewConfigurationSidesheet, { initialData: initialData, isSidesheetOpen: isCalendarViewConfigOpen, setIsSidesheetOpen: setIsCalendarViewConfigOpen, domainFieldOptions: domainFieldOptions, dateDomainFieldOptions: dateDomainFieldOptions, isCalendarViewEnabled: isCalendarViewEnabled, handleCalendarViewEnabledChange: handleCalendarViewEnabledChange }), React.createElement(React.Fragment, null, React.createElement("div", { className: classes.addRemoveButtons }, React.createElement(FluentButton, { variant: "contained", color: "primary", onClick: () => push('domainFields', undefined) }, t('Add a Domain Field'))), React.createElement(FieldArray, { name: "domainFields" }, ({ fields }) => fields.map((name, index) => {
                var _a, _b;
                const fieldKey = (_b = (_a = fields === null || fields === void 0 ? void 0 : fields.value) === null || _a === void 0 ? void 0 : _a[index]) === null || _b === void 0 ? void 0 : _b[0];
                const isRequired = REQUIRED_COLUMN_DEF_FIELDS.includes(fieldKey);
                const disableOrderField = DISABLE_ORDERING_FOR_FIELDS.includes(fieldKey);
                return (React.createElement("div", { key: `${name}${index}`, className: classes.domainFields }, React.createElement(Field, { component: AmbientAutoComplete, label: index === 0 && t('Field'), name: `${name}[0]`, variant: "outlined", disabled: isRequired, options: domainFieldOptions || [], freeSolo: true }), React.createElement(Field, { component: FluentTextField, label: index === 0 && t('Display Name'), name: `${name}[1].displayName`, fullWidth: true, variant: "outlined", margin: "normal", size: "small", onChange: () => { }, className: classes.domainValueField }), React.createElement(Field, { component: FluentTextField, label: index === 0 && t('Order'), name: `${name}[1].order`, fullWidth: true, variant: "outlined", margin: "normal", size: "small", type: "number", onChange: () => { }, disabled: disableOrderField, className: classes.domainValueField }), React.createElement("div", { className: classes.switchColumn }, index === 0 && (React.createElement("span", { style: {
                        fontSize: '14px',
                        color: 'rgba(0, 0, 0, 0.6)',
                        marginBottom: '-2px',
                        fontWeight: 400
                    } }, t('Hide'))), React.createElement(Field, { component: Switch, name: `${name}[1].hide`, type: "checkbox" })), React.createElement("div", { className: classes.deleteActionSlot }, !isRequired && (React.createElement("span", { onClick: () => fields.remove(index), className: classes.removeIcon }, React.createElement(StatusCircleErrorXIcon, null))))));
            })))));
        } }));
};
export default forwardRef(UdpTransactionTypeForm);
//# sourceMappingURL=UdpTransactionTypeForm.js.map