var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import React, { useMemo, useState, useCallback, useEffect } from 'react';
import PrimaryActionButton from '../../UI/inputs/buttons/PrimaryActionButton';
import { AmbientGridTemplate } from '../../UI/templates/deprecated/AmbientGridTemplate/AmbientGridTemplate';
import { SideSheet } from '../../UI/surfaces/SideSheet';
import { ActionsRenderer } from '../../UI/templates/ui/renderers/ActionsRenderer';
import { VirtualTableColumnDefs } from './VirtualTableColumnDefs';
import { AddIcon, DeleteIcon, EditIcon } from '@fluentui/react-icons';
import { Typography } from '@material-ui/core';
import { DateTime } from 'luxon';
import { getPathObject } from '../../utilities/maintenanceEngine/CrudBrowserUtilities';
import { cloneDeep } from 'lodash-es';
import { useTranslation } from 'react-i18next';
import { executeQueryWithParameters } from '../../udp/utilities/methodUtils';
import { useHandleAxiosSnackbar } from '../../utilities/apiHelpers';
import { useAxiosMutate } from '../../utilities/useAxiosMutate';
import { useLocation } from 'react-router-dom';
import { useUser } from '../../utilities/auth/useUser';
import { useAxiosGet } from '../../utilities/useAxiosGet';
import { VirtualTableSidePanel } from './VirtualTableSidePanel';
import { UdpEnums } from '../../enums/unitySystemEnums';
import { useBuildEnvironment } from '../../shell/ui/useBuildEnvironment';
import { getSanitizedName } from '../../utilities/entities/entityUtilities';
import { useSetLocationState } from '../../hooks/useSetLocationState';
import { ConfigService } from '../../configService';
const useSearchParams = () => {
    const { search } = useLocation();
    return useMemo(() => new URLSearchParams(search), [search]);
};
export const VirtualBrowser = (props) => {
    var _a, _b, _c;
    const other = __rest(props, []);
    const urlSearchParams = useSearchParams();
    const location = useLocation();
    const { value, promotedEntity } = location.state || {};
    const parts = (_a = location === null || location === void 0 ? void 0 : location.pathname) === null || _a === void 0 ? void 0 : _a.split('/');
    const virtualId = value ? value === null || value === void 0 ? void 0 : value.id : '' || parts ? parts[parts.length - 1] : null;
    const user = useUser();
    const buildEnv = useBuildEnvironment();
    const [isSheetOpen, setSheetOpen] = useState(false);
    const [sideSheetWidth, setSideSheetWidth] = useState(600);
    const [sideSheetButtonLabel, setSideSheetButtonLabel] = useState('');
    const [otherSideSheetProps, setOtherSideSheetProps] = useState({});
    const [sideSheetOnSubmit, setSideSheetOnSubmit] = useState(() => () => console.warn('onSubmit not set'));
    const [selectedEntity, setSelectedEntity] = useState(promotedEntity);
    const { t } = useTranslation();
    const { handleErrorSnackbar, handleSuccessSnackbar } = useHandleAxiosSnackbar();
    const setLocationState = useSetLocationState();
    const closeSheet = useCallback(() => {
        setSheetOpen(false);
    }, []);
    const entityName = useMemo(() => {
        if (selectedEntity) {
            return selectedEntity.entityName || '';
        }
        else {
            return urlSearchParams.has('entityName') === true ? urlSearchParams.get('entityName') : '';
        }
    }, [selectedEntity, urlSearchParams]);
    const createApiMethodPageId = useMemo(() => {
        var _a;
        return (_a = selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseCreateMethod) === null || _a === void 0 ? void 0 : _a.pageId;
    }, [selectedEntity]);
    const [{ data: tpacb }] = useAxiosGet(ConfigService.integrationV1ApiUrl, `tenantProductApiCatalogBase/tenant/${user === null || user === void 0 ? void 0 : user.currentTenantId}/product/${ConfigService.config.UNITY_PRODUCT_ID}`, {}, !!!user || !!promotedEntity, false);
    const [{ data: promotedMethodEntities }] = useAxiosGet(ConfigService.integrationV1ApiUrl, `apicatalog/${tpacb === null || tpacb === void 0 ? void 0 : tpacb.apiCatalogId}/promotedMethodEntities/${entityName}/product/${ConfigService.config.UNITY_PRODUCT_ID}`, {}, !!!tpacb || !!!user || !!!entityName, false);
    // Get all rows of an entity
    const [{ data: entityData, loading: isLoading }, fetchEntityData] = useAxiosMutate(ConfigService.integrationV1ApiUrl, `apimethod/executeQueryWithParameters/${(_b = selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseGetDataMethod) === null || _b === void 0 ? void 0 : _b.apiMethodId}`, {
        method: 'post',
    });
    // Get all rows of an entity
    const [{ data: tableDescription }, fetchTableDescription] = useAxiosMutate(ConfigService.integrationV1ApiUrl, `apimethod/executeQueryWithParameters/${(_c = selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseDescribeMethod) === null || _c === void 0 ? void 0 : _c.apiMethodId}`, {
        method: 'post',
    });
    const constructVirtualValuesForRequest = useCallback((values) => {
        if (!tableDescription) {
            return [];
        }
        const bodyArr = [];
        tableDescription.forEach((column) => {
            const valueExist = typeof values[column.name] == 'boolean' || values[column.name];
            if (column.name || valueExist) {
                switch (getSanitizedName(entityName === null || entityName === void 0 ? void 0 : entityName.toLowerCase())) {
                    case UdpEnums.Udp_Lookup.toLowerCase():
                        bodyArr.push({
                            lookupColumnId: column.id,
                            value: values[column.name],
                        });
                        break;
                    default:
                }
            }
        });
        return bodyArr;
    }, [tableDescription, entityName]);
    const handleOnCreate = useCallback(async (values) => {
        if (selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseVirtualCreateMethod) {
            const requestArr = constructVirtualValuesForRequest(values);
            const data = { requestBody: requestArr, id: virtualId };
            const response = await executeQueryWithParameters({ data }, selectedEntity.unityBaseVirtualCreateMethod.apiMethodId).catch((res) => {
                handleErrorSnackbar(res.message);
            });
            if ((response === null || response === void 0 ? void 0 : response.status) === 200) {
                handleSuccessSnackbar(t(`Row has been created`));
                const queryData = { id: virtualId };
                fetchEntityData({ data: queryData });
            }
        }
    }, [
        selectedEntity,
        t,
        fetchEntityData,
        handleErrorSnackbar,
        handleSuccessSnackbar,
        virtualId,
        constructVirtualValuesForRequest,
    ]);
    const handleOnUpdate = useCallback(async (values) => {
        if (selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseVirtualUpdateMethod) {
            // Get primary key value object using path parameters and merge with data
            const primaryKeyValues = [virtualId, values.udpVirtualRowId];
            const pathObject = getPathObject(selectedEntity.unityBaseVirtualUpdateMethod.pathParameters, primaryKeyValues);
            const requestArr = constructVirtualValuesForRequest(values);
            let data = { requestBody: requestArr };
            if (Array.isArray(pathObject)) {
                pathObject.forEach((po) => {
                    data[Object.keys(po)[0]] = po[Object.keys(po)[0]];
                });
            }
            else {
                data = Object.assign(Object.assign({}, pathObject), { requestBody: requestArr });
            }
            const response = await executeQueryWithParameters({ data }, selectedEntity.unityBaseVirtualUpdateMethod.apiMethodId).catch((res) => {
                handleErrorSnackbar(res.message);
            });
            if ((response === null || response === void 0 ? void 0 : response.status) === 200) {
                handleSuccessSnackbar(t(`Row has been updated`));
                const queryData = { id: virtualId };
                fetchEntityData({ data: queryData });
            }
        }
    }, [
        selectedEntity,
        t,
        fetchEntityData,
        handleErrorSnackbar,
        handleSuccessSnackbar,
        virtualId,
        constructVirtualValuesForRequest,
    ]);
    const handleOnDelete = useCallback(async (value) => {
        if (selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseVirtualDeleteMethod) {
            // Get primary key value object using path parameters and merge with data
            const primaryKeyValues = [virtualId, value.udpVirtualRowId];
            const pathObject = getPathObject(selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseVirtualDeleteMethod.pathParameters, primaryKeyValues);
            let data = {};
            if (Array.isArray(pathObject)) {
                pathObject.forEach((po) => {
                    data[Object.keys(po)[0]] = po[Object.keys(po)[0]];
                });
            }
            else {
                data = Object.assign({}, pathObject);
            }
            const response = await executeQueryWithParameters({ data }, selectedEntity.unityBaseVirtualDeleteMethod.apiMethodId).catch((res) => {
                handleErrorSnackbar(res.message);
            });
            if ((response === null || response === void 0 ? void 0 : response.status) === 200) {
                handleSuccessSnackbar(t(`Row has been deleted`));
                const queryData = { id: virtualId };
                fetchEntityData({ data: queryData });
            }
        }
    }, [selectedEntity, t, fetchEntityData, handleErrorSnackbar, handleSuccessSnackbar, virtualId]);
    const actionList = useMemo(() => {
        var _a;
        if (!selectedEntity) {
            return;
        }
        return [
            {
                id: 1, // Must be unique
                title: (selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseVirtualUpdateMethod)
                    ? t('Edit')
                    : t('Edit Method Not Accessible'),
                icon: EditIcon,
                onClick: null,
                opens: 'sideSheet',
                view: {
                    component: VirtualTableSidePanel,
                    properties: {
                        tableDescription: tableDescription,
                        onUpdate: handleOnUpdate,
                        valuePropName: 'value',
                        closeSideSheet: null,
                        closeSideSheetPropName: 'closeSideSheet',
                        pageId: (_a = selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseVirtualUpdateMethod) === null || _a === void 0 ? void 0 : _a.pageId,
                        isNewEntry: false,
                    },
                },
                disabled: !!!(selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseVirtualUpdateMethod),
            },
            {
                id: 2, // Must be unique
                title: (selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseVirtualDeleteMethod)
                    ? t('Delete')
                    : t('Delete Method Not Accessible'),
                icon: DeleteIcon,
                onClick: null,
                opens: 'dialog',
                view: {
                    component: null,
                    properties: {
                        title: t('Delete'),
                        message: t('Are you sure you want to delete this row?'),
                        labelOne: t('Cancel'),
                        actionTwo: handleOnDelete,
                        labelTwo: t('Confirm'),
                    },
                },
                disabled: !!!(selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseVirtualDeleteMethod),
            },
        ];
    }, [selectedEntity, t, handleOnUpdate, handleOnDelete, tableDescription]);
    const columnDefs = useMemo(() => {
        if (tableDescription === null || tableDescription === void 0 ? void 0 : tableDescription.length) {
            return VirtualTableColumnDefs(tableDescription, actionList);
        }
        return [];
    }, [actionList, tableDescription]);
    const groupData = useMemo(() => {
        return columnDefs === null || columnDefs === void 0 ? void 0 : columnDefs.map((item) => {
            return {
                groupItem: item.field,
                label: item.headerName,
                value: item.field,
            };
        });
    }, [columnDefs]);
    useEffect(() => {
        if (promotedMethodEntities) {
            setSelectedEntity(promotedMethodEntities);
        }
    }, [promotedMethodEntities]);
    useEffect(() => {
        var _a, _b;
        if (virtualId) {
            const queryData = { id: virtualId };
            if ((_a = selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseGetDataMethod) === null || _a === void 0 ? void 0 : _a.apiMethodId) {
                fetchEntityData({ data: queryData });
            }
            if ((_b = selectedEntity === null || selectedEntity === void 0 ? void 0 : selectedEntity.unityBaseDescribeMethod) === null || _b === void 0 ? void 0 : _b.apiMethodId) {
                fetchTableDescription({ data: queryData });
            }
        }
    }, [selectedEntity, fetchEntityData, virtualId, fetchTableDescription]);
    // Setting location state label so that if this page was saved to favorites
    // we can determine the bread crumb
    useEffect(() => {
        setLocationState({ label: t(value === null || value === void 0 ? void 0 : value.name) || t('Virtual Lookup') });
    }, [setLocationState, t, value]);
    const pab = (React.createElement(PrimaryActionButton, { onClick: () => setSheetOpen && setSheetOpen(true) }, React.createElement(Typography, { style: { marginRight: 5 } }, "Add"), React.createElement(AddIcon, null)));
    const SideOptionList = useMemo(() => (React.createElement(SideSheet, Object.assign({ open: isSheetOpen, onClose: closeSheet, title: `Add new ${entityName}`, width: sideSheetWidth, buttonLabel: sideSheetButtonLabel, onSubmit: sideSheetOnSubmit }, otherSideSheetProps), React.createElement(VirtualTableSidePanel, { onCreate: handleOnCreate, closeSideSheet: closeSheet, pageId: createApiMethodPageId, setSideSheetWidth: setSideSheetWidth, setSideSheetButtonLabel: setSideSheetButtonLabel, setSideSheetOnSubmit: setSideSheetOnSubmit, setSideSheetProps: setOtherSideSheetProps, tableDescription: tableDescription }))), [
        isSheetOpen,
        closeSheet,
        entityName,
        sideSheetWidth,
        sideSheetButtonLabel,
        sideSheetOnSubmit,
        handleOnCreate,
        createApiMethodPageId,
        otherSideSheetProps,
        tableDescription,
    ]);
    const formatData = useCallback(() => {
        if ((entityData === null || entityData === void 0 ? void 0 : entityData.data) && tableDescription) {
            let formattedEntityData = cloneDeep(entityData === null || entityData === void 0 ? void 0 : entityData.data);
            //   get list of attributes that are datetime
            const datetimeFields = tableDescription === null || tableDescription === void 0 ? void 0 : tableDescription.reduce((fields, element) => {
                if ((element === null || element === void 0 ? void 0 : element.type) === 'datetime') {
                    fields.push(element === null || element === void 0 ? void 0 : element.name);
                }
                return fields;
            }, []);
            if (datetimeFields.length) {
                formattedEntityData.forEach((e) => {
                    Object.keys(e).forEach((key) => {
                        // format all datetime fields
                        if (datetimeFields.find((field) => field === key)) {
                            // LAA UNT-2977: add null check to prevent default date from being added when null
                            if (e[key] === null)
                                return;
                            e[key] = DateTime.fromJSDate(new Date(e[key])).toFormat('yyyy/MM/dd HH:mm:ss');
                        }
                    });
                });
            }
            return formattedEntityData;
        }
        return [];
    }, [entityData, tableDescription]);
    return (React.createElement(React.Fragment, null, React.createElement(AmbientGridTemplate, Object.assign({ title: (value === null || value === void 0 ? void 0 : value.name) || (entityData === null || entityData === void 0 ? void 0 : entityData.name), data: entityData ? formatData(entityData === null || entityData === void 0 ? void 0 : entityData.data) : [], columnDefs: columnDefs, groupingData: groupData, primaryActionButton: pab, frameworkComponents: { actionsRenderer: ActionsRenderer }, height: `calc(100vh - ${buildEnv ? '139px' : '114px'})`, disableRowSelection: true, loading: isLoading }, other)), SideOptionList));
};
export default VirtualBrowser;
//# sourceMappingURL=VirtualBrowser.js.map