import { makeStyles } from '@material-ui/core';
import { Skeleton } from '@material-ui/lab';
import { useSnackbar } from 'notistack';
import PropTypes from 'prop-types';
import React, { lazy, Suspense, useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ActionSplitScreen } from './ActionSplitScreen';
import { ActionPanelPlacement } from './ActionPanelPlacement';
// Lazy-load action overlays (modal/sidesheet) — they only render when their
// corresponding action is invoked, so they shouldn't sit in the Shell entry chunk.
// Conditional render gates the chunk fetch on actual open state.
const ActionModal = lazy(() => import('./ActionModal').then((m) => ({ default: m.ActionModal })));
const ActionSideSheet = lazy(() => import('./ActionSideSheet').then((m) => ({ default: m.ActionSideSheet })));
import { apiMutate } from '../utilities/useAxiosMutate';
import { getPathObject, getPrimaryKeyValues, } from '../utilities/maintenanceEngine/CrudBrowserUtilities';
import { getSuccessAction } from '../UI/SuccessAction';
import { LayoutUnit } from '../layout/LayoutUnit';
import { toLowerFirstChar } from '../utilities/input/StringUtilities';
import { useAxiosGet } from '../utilities/useAxiosGet';
import { useCrudForeignKeyData } from '../hooks/crudForeignKeyData';
import { useActionStore } from '../stores/actionStore';
import { useShellStore } from '../stores/shellStore';
import { usePromotedMethodEntity } from '../hooks/usePromotedMethodEntity';
import { getSanitizedName } from '../utilities/entities/entityUtilities';
import { getSearchObject } from '../utilities/search/SearchUtilities';
import { executeQueryAdHoc } from '../udp/utilities/methodUtils';
import { ConfigService } from '../configService';
const useStyles = makeStyles((theme) => ({}));
const FIELD_NUMBER = 10;
export const ActionWrapper = (props) => {
    var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
    const { actionState, actionPanel, dispatch, apiCatalogId, executeAction, splitScreenBody, entityAttributes, foreignKeyData, setForeignKeyData, crudTableEditionData, crudTableFormData, globalActions, } = props;
    const classes = useStyles();
    const { getFKData } = useCrudForeignKeyData();
    const { enqueueSnackbar, closeSnackbar } = useSnackbar();
    const successAction = getSuccessAction(closeSnackbar);
    const { t } = useTranslation();
    const [fkMethodEntities, setFKMethodEntities] = useState([]);
    const [loadingContent, setLoadingContent] = useState(true);
    const [udpFieldInfos, setUdpFieldInfos] = useState([]);
    const selectedNode = useActionStore((state) => state.selectedNode);
    const currentContainerId = useShellStore((state) => state.currentContainerId);
    const { data: udpOjectFieldInfo } = usePromotedMethodEntity('UdpObjectFieldInfo', true);
    const entityName = useMemo(() => {
        var _a, _b, _c;
        return actionPanel
            ? actionPanel.entityName
            : (_c = (_b = (_a = actionState === null || actionState === void 0 ? void 0 : actionState.inquiryParams[currentContainerId || 0]) === null || _a === void 0 ? void 0 : _a.selectedNode) === null || _b === void 0 ? void 0 : _b.properties) === null || _c === void 0 ? void 0 : _c.catalogReturnObject;
    }, [actionPanel, actionState, currentContainerId]);
    const [{ data: selectedEntity }] = useAxiosGet(ConfigService.integrationV1ApiUrl, `apicatalog/${apiCatalogId}/promotedMethodEntities/${entityName}/product/${ConfigService.config.UNITY_PRODUCT_ID}`, {}, !!!apiCatalogId || !!!entityName, false);
    const getMetaDataForUdpField = useCallback(async (entityName) => {
        var _a;
        let fieldInfos = [];
        if ((_a = udpOjectFieldInfo === null || udpOjectFieldInfo === void 0 ? void 0 : udpOjectFieldInfo.unityBaseSearchMethod) === null || _a === void 0 ? void 0 : _a.apiMethodId) {
            const filterElements = [
                {
                    searchField: 'ObjectInfo.SanitizedName',
                    searchOperator: '=',
                    searchValue: getSanitizedName(entityName),
                },
            ];
            const requestObj = getSearchObject(filterElements, 1, 50, true);
            await executeQueryAdHoc({ data: requestObj }, udpOjectFieldInfo.unityBaseSearchMethod.apiMethodId).then((resp) => {
                var _a;
                fieldInfos = (_a = resp.data) === null || _a === void 0 ? void 0 : _a.pageList;
            });
        }
        return fieldInfos;
    }, [udpOjectFieldInfo]);
    const fetchEntityData = useCallback(async (data) => {
        if (selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseGetAllMethod)
            return await executeAction(data, selectedEntity.unityBaseGetAllMethod.apiMethodId);
    }, [executeAction, selectedEntity]);
    const showError = useCallback(() => {
        enqueueSnackbar(t(`Invalid action value.`), {
            variant: 'error',
            anchorOrigin: {
                vertical: 'top',
                horizontal: 'center',
            },
        });
    }, [enqueueSnackbar, t]);
    const getFKMethodEntities = useCallback(async (attributes) => {
        var _a;
        if (!attributes || !apiCatalogId) {
            return [];
        }
        let fkData = [];
        for (const attr of attributes) {
            // check if there is a property with this childEntity
            if ((_a = attr === null || attr === void 0 ? void 0 : attr.extendedProperties) === null || _a === void 0 ? void 0 : _a.childEntity) {
                // get the list of child entity field names from the Keys array
                const ceFieldsArr = [];
                if (Object.keys(attr.extendedProperties.childEntityAssoc || {}).length &&
                    !attr.extendedProperties.childEntityAssoc.UdpType) {
                    attr.extendedProperties.childEntityAssoc.Keys.forEach((value, i) => {
                        const name = value.split(',')[0];
                        if (name) {
                            // check name string: if 1 word, lowercase. if 2 words, lower first char
                            ceFieldsArr.push({
                                idx: i,
                                name: /^[A-Z]*$/.test(name) ? name.toLowerCase() : toLowerFirstChar(name),
                            });
                        }
                    });
                }
                // find the child entity attribute
                const ceAttr = attributes.find((p) => ceFieldsArr.find((cef) => {
                    var _a;
                    return cef.name === p.name && !((_a = p === null || p === void 0 ? void 0 : p.extendedProperties) === null || _a === void 0 ? void 0 : _a.identifier);
                }));
                if (ceAttr) {
                    // get list of entity if ceProp exists
                    await apiMutate(ConfigService.integrationV1ApiUrl, `apicatalog/${apiCatalogId}/promotedMethodEntities/${attr.reference}/product/${ConfigService.config.UNITY_PRODUCT_ID}`, {
                        method: 'get',
                    }, {}).then((resp) => {
                        if (resp && resp.data) {
                            fkData.push({ fkName: ceAttr.name, entity: resp.data });
                        }
                    });
                }
            }
        }
        setFKMethodEntities(fkData);
    }, [apiCatalogId]);
    const handleOnClose = useCallback((type, entity) => {
        dispatch({ type: type, entity });
    }, [dispatch]);
    const onDelete = useCallback(async (data) => {
        var _a, _b, _c, _d;
        if (selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseDeleteMethod) {
            if (selectedEntity.unityBaseDeleteMethod.apiMethodId === ((_b = (_a = actionState === null || actionState === void 0 ? void 0 : actionState.modal) === null || _a === void 0 ? void 0 : _a.action) === null || _b === void 0 ? void 0 : _b.value)) {
                return await executeAction(data, (_d = (_c = actionState === null || actionState === void 0 ? void 0 : actionState.modal) === null || _c === void 0 ? void 0 : _c.action) === null || _d === void 0 ? void 0 : _d.value);
            }
            else {
                showError();
            }
        }
    }, [actionState, executeAction, selectedEntity, showError]);
    const handleOnDelete = useCallback(async (value) => {
        var _a, _b, _c;
        if (selectedEntity) {
            const entityName = selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.entityName;
            // Get primary key value object using path parameters and merge with data
            const primaryKeyValues = getPrimaryKeyValues(entityAttributes, value);
            const pathObject = getPathObject(selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseDeleteMethod.pathParameters, primaryKeyValues);
            if (selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseDeleteMethod) {
                const data = Object.assign({}, pathObject);
                const response = await onDelete({ data }).catch((res) => {
                    enqueueSnackbar(res.message, {
                        variant: 'error',
                        anchorOrigin: {
                            vertical: 'top',
                            horizontal: 'center',
                        },
                    });
                });
                if ((response === null || response === void 0 ? void 0 : response.status) === 200) {
                    enqueueSnackbar(entityName ? t(`${entityName} has been deleted`) : t(`Entity has been deleted`), {
                        anchorOrigin: {
                            vertical: 'top',
                            horizontal: 'center',
                        },
                        action: successAction,
                    });
                    if ((actionState === null || actionState === void 0 ? void 0 : actionState.menuListState) && ((_a = actionState === null || actionState === void 0 ? void 0 : actionState.menuListState) === null || _a === void 0 ? void 0 : _a.menuList.length) > 0) {
                        const handleRemoveMenuItem = (_b = actionState === null || actionState === void 0 ? void 0 : actionState.menuListState) === null || _b === void 0 ? void 0 : _b.handleRemoveMenuItem;
                        if (handleRemoveMenuItem) {
                            handleRemoveMenuItem((_c = actionState === null || actionState === void 0 ? void 0 : actionState.menuListState) === null || _c === void 0 ? void 0 : _c.menuList);
                        }
                    }
                    fetchEntityData({ data: {} });
                }
            }
        }
    }, [
        actionState,
        enqueueSnackbar,
        entityAttributes,
        fetchEntityData,
        onDelete,
        selectedEntity,
        successAction,
        t,
    ]);
    const skeleton = useMemo(() => {
        const skeletonArr = [];
        for (let i = 0; i < FIELD_NUMBER; i++) {
            skeletonArr.push(React.createElement(React.Fragment, null, React.createElement(Skeleton, { key: i, variant: "rect", className: classes.skeleton }), React.createElement(LayoutUnit, { unit: "xxs" })));
        }
        return skeletonArr;
    }, [classes]);
    useEffect(() => {
        if (entityAttributes) {
            getFKMethodEntities(entityAttributes);
            setLoadingContent(false);
        }
    }, [entityAttributes, getFKMethodEntities]);
    useEffect(() => {
        if (entityAttributes && fkMethodEntities && fkMethodEntities.length > 0) {
            getFKData(fkMethodEntities, setForeignKeyData, enqueueSnackbar);
        }
    }, [enqueueSnackbar, entityAttributes, fkMethodEntities, getFKData, setForeignKeyData]);
    useEffect(() => {
        var _a;
        const setFieldInfos = async () => {
            if (!entityName)
                return;
            let response = await getMetaDataForUdpField(entityName);
            setUdpFieldInfos(response);
        };
        if ((_a = udpOjectFieldInfo === null || udpOjectFieldInfo === void 0 ? void 0 : udpOjectFieldInfo.unityBaseSearchMethod) === null || _a === void 0 ? void 0 : _a.apiMethodId) {
            setFieldInfos();
        }
    }, [getMetaDataForUdpField, udpOjectFieldInfo, entityName]);
    return (React.createElement(React.Fragment, null, React.createElement(ActionSplitScreen, { body: React.createElement(React.Fragment, null, splitScreenBody, React.createElement(ActionPanelPlacement, { actionPanels: actionState === null || actionState === void 0 ? void 0 : actionState.actionPanels[currentContainerId || 0], showInquiryHeaderActions: actionState === null || actionState === void 0 ? void 0 : actionState.showInquiryHeaderActions, selectedNode: (_a = actionState === null || actionState === void 0 ? void 0 : actionState.inquiryParams[currentContainerId || 0]) === null || _a === void 0 ? void 0 : _a.selectedNode, globalActions: globalActions })), open: (_b = actionState === null || actionState === void 0 ? void 0 : actionState.splitScreen) === null || _b === void 0 ? void 0 : _b.open, action: (_c = actionState === null || actionState === void 0 ? void 0 : actionState.splitScreen) === null || _c === void 0 ? void 0 : _c.action, type: (_d = actionState === null || actionState === void 0 ? void 0 : actionState.splitScreen) === null || _d === void 0 ? void 0 : _d.type, params: (_e = actionState === null || actionState === void 0 ? void 0 : actionState.splitScreen) === null || _e === void 0 ? void 0 : _e.params, executeAction: executeAction, actionPanel: actionPanel, selectedNodeObj: selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.nodeObj, menuNodeList: (_f = actionState === null || actionState === void 0 ? void 0 : actionState.menuListState) === null || _f === void 0 ? void 0 : _f.menuList, sidebarEntity: selectedEntity, selectedNode: (_g = actionState === null || actionState === void 0 ? void 0 : actionState.inquiryParams[currentContainerId || 0]) === null || _g === void 0 ? void 0 : _g.selectedNode, selectedNodeParent: (_h = actionState === null || actionState === void 0 ? void 0 : actionState.inquiryParams[currentContainerId || 0]) === null || _h === void 0 ? void 0 : _h.selectedNodeParent, refreshTree: (_j = actionState === null || actionState === void 0 ? void 0 : actionState.inquiryParams[currentContainerId || 0]) === null || _j === void 0 ? void 0 : _j.refreshTree }), ((_k = actionState === null || actionState === void 0 ? void 0 : actionState.sideSheet) === null || _k === void 0 ? void 0 : _k.open) && (React.createElement(Suspense, { fallback: null }, React.createElement(ActionSideSheet, { key: (_m = (_l = actionState === null || actionState === void 0 ? void 0 : actionState.sideSheet) === null || _l === void 0 ? void 0 : _l.action) === null || _m === void 0 ? void 0 : _m.actionId, open: (_o = actionState === null || actionState === void 0 ? void 0 : actionState.sideSheet) === null || _o === void 0 ? void 0 : _o.open, dispatch: dispatch, action: (_p = actionState === null || actionState === void 0 ? void 0 : actionState.sideSheet) === null || _p === void 0 ? void 0 : _p.action, actionPanel: actionPanel, selectedNodeObj: selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.nodeObj, executeAction: executeAction, selectedEntity: selectedEntity, handleOnClose: () => {
            const sideSheet = { open: false, action: null };
            handleOnClose('OPEN_SIDESHEET', sideSheet);
        }, entityAttributes: entityAttributes, foreignKeyData: foreignKeyData, loadingContent: loadingContent, fetchEntityData: fetchEntityData, skeleton: skeleton, showError: showError, crudTableEditionData: crudTableEditionData, crudTableFormData: crudTableFormData, selectedNode: (_q = actionState === null || actionState === void 0 ? void 0 : actionState.inquiryParams[currentContainerId || 0]) === null || _q === void 0 ? void 0 : _q.selectedNode, selectedNodeParent: (_r = actionState === null || actionState === void 0 ? void 0 : actionState.inquiryParams[currentContainerId || 0]) === null || _r === void 0 ? void 0 : _r.selectedNodeParent, refreshTree: (_s = actionState === null || actionState === void 0 ? void 0 : actionState.inquiryParams[currentContainerId || 0]) === null || _s === void 0 ? void 0 : _s.refreshTree, udpFieldInfos: udpFieldInfos }))), ((_t = actionState === null || actionState === void 0 ? void 0 : actionState.modal) === null || _t === void 0 ? void 0 : _t.open) && (React.createElement(Suspense, { fallback: null }, React.createElement(ActionModal, { open: (_u = actionState === null || actionState === void 0 ? void 0 : actionState.modal) === null || _u === void 0 ? void 0 : _u.open, action: (_v = actionState === null || actionState === void 0 ? void 0 : actionState.modal) === null || _v === void 0 ? void 0 : _v.action, title: ((_w = actionState === null || actionState === void 0 ? void 0 : actionState.modal) === null || _w === void 0 ? void 0 : _w.title) + (selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.entityName), message: t(`Are you sure you want to delete this ${selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.entityName}?`), confirmAction: () => handleOnDelete(selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.nodeObj), handleOnClose: () => {
            const modal = { open: false, action: null };
            handleOnClose('OPEN_MODAL', modal);
        }, showError: showError })))));
};
ActionWrapper.propTypes = {
    actionState: PropTypes.object,
    actionPanel: PropTypes.object,
    dispatch: PropTypes.func,
    catalog: PropTypes.object,
    executeAction: PropTypes.func,
    user: PropTypes.object,
    splitScreenBody: PropTypes.object,
};
//# sourceMappingURL=ActionWrapper.js.map