import React, { useEffect, useMemo, forwardRef, useImperativeHandle, useCallback, useState } from 'react';
import { LinearProgress } from '@material-ui/core';
import { apiMutate, useAxiosMutate } from '../../../../../utilities/useAxiosMutate';
import { UdpTimeline } from '../../../../../UI/timeline/UdpTimeline';
import { EmptyStateDisplay, SideSheet } from '../../../../../UI';
import { useTranslation } from 'react-i18next';
import { useSnackbar } from 'notistack';
import { TransactionTimelineItem } from './TransactionTimelineItem';
import { ConfigService } from '../../../../../configService';
import { formatDate } from '../../../../../UI/widgets/utils/dateUtils';
import { AmbientCard } from '../../../../../UI/surfaces/cards/AmbientCard';
import { TransactionChangeLog } from './TransactionChangeLog';
import { HttpStatusCode } from '../../../../../enums/httpStatusCodesEnums';
import { useCatalogStore } from '../../../../../stores';
const META_DATA_BLOCKLIST = new Set([
    "businessobjectkey",
    "id",
    "ignoringloggingtransactions",
]);
export const TransactionTimeline = forwardRef((props, ref) => {
    var _a, _b;
    const { transactionId } = props;
    const { t } = useTranslation();
    const { enqueueSnackbar } = useSnackbar();
    const { currentApiCatalogId } = useCatalogStore();
    const [udpDomainObjects, setUdpDomainObjects] = useState(null);
    const [sideSheetOpen, setSideSheetOpen] = useState(false);
    const searchObj = useMemo(() => {
        return {
            eagerLoad: true,
            pageNumber: 0,
            pageSize: 100,
            filterElements: [
                {
                    searchField: 'transactionId',
                    searchValue: transactionId,
                    searchOperator: '='
                }
            ],
            orderElements: [
                {
                    sortColumn: 'createdOn',
                    sortDirection: 'desc'
                }
            ],
            getAll: true
        };
    }, [transactionId]);
    const [{ data: transactionHistory, loading: isLoading }, fetchTransactionHistory] = useAxiosMutate(ConfigService.productV1ApiUrl, `UdpTransactionHistory/search`, {
        method: 'post',
        data: searchObj
    });
    const filterData = (dataObj, allowedKeys) => {
        if (!dataObj)
            return {};
        const allowedSet = new Set(allowedKeys
            .map(key => key.toLowerCase())
            .filter(key => !META_DATA_BLOCKLIST.has(key)));
        return Object.fromEntries(Object.entries(dataObj).filter(([key]) => allowedSet.has(key.toLowerCase())));
    };
    const handleOnClick = useCallback(async (transactionHistoryRecord) => {
        var _a;
        const domain = (_a = transactionHistoryRecord === null || transactionHistoryRecord === void 0 ? void 0 : transactionHistoryRecord.udpTransactionHistoryUdpAuditEvent) === null || _a === void 0 ? void 0 : _a.domain;
        try {
            const [catalogRes, comparisonRes] = await Promise.all([
                apiMutate(ConfigService.integrationV2ApiUrl, `apiCatalog/${currentApiCatalogId}/catalogObject/${domain}`, { method: 'get' }),
                apiMutate(ConfigService.productV1ApiUrl, `UdpTransactionHistory/GetComparison`, {
                    method: 'post',
                    data: {
                        auditEventId: transactionHistoryRecord.auditEventId,
                        entityBusinessKey: transactionHistoryRecord.entityBusinessKey,
                        transactionEventTypeId: transactionHistoryRecord.transactionEventTypeId
                    }
                })
            ]);
            const catalog = catalogRes === null || catalogRes === void 0 ? void 0 : catalogRes.data;
            if (!catalog) {
                console.error("Missing catalog metadata for domain:", domain);
                enqueueSnackbar(t("Unable to load metadata for this record."), {
                    variant: 'error',
                    autoHideDuration: 7000,
                    anchorOrigin: { vertical: 'top', horizontal: 'center' },
                    preventDuplicate: true
                });
                return;
            }
            const permissableFieldTypes = new Set(["string", "DateTime", "string uuid", "int", "bool"]);
            const catalogPropertyNames = catalog.properties
                .filter(field => permissableFieldTypes.has(field.type))
                .map(property => property.name);
            const data = comparisonRes.data;
            const domainObjects = {
                previous: filterData(data.previous, catalogPropertyNames),
                current: filterData(data.current, catalogPropertyNames)
            };
            setUdpDomainObjects(domainObjects);
            setSideSheetOpen(true);
        }
        catch (error) {
            console.error("Fetch Failed:", error);
            let userMessage = "Unable to load comparison. Please try again.";
            if (error.response && error.response.status) {
                const status = error.response.status;
                switch (status) {
                    case HttpStatusCode.BAD_REQUEST:
                        userMessage = "Data mismatch detected. Please refresh the page and try again.";
                        break;
                    case HttpStatusCode.NOT_FOUND:
                        userMessage = "This history record no longer exists.";
                        break;
                    case HttpStatusCode.INTERNAL_SERVER_ERROR:
                        userMessage = "System error. Please contact support if this persists.";
                        break;
                }
            }
            else if (error.request) {
                userMessage = "Network error. Please check your connection.";
            }
            enqueueSnackbar(t(userMessage), {
                variant: 'error',
                autoHideDuration: 7000,
                anchorOrigin: {
                    vertical: 'top',
                    horizontal: 'center',
                },
                preventDuplicate: true
            });
        }
    }, [currentApiCatalogId, t, enqueueSnackbar]);
    const handleOnSideSheetClose = useCallback(() => {
        setSideSheetOpen(false);
    }, []);
    useImperativeHandle(ref, () => ({
        refresh: () => {
            fetchTransactionHistory();
        }
    }));
    useEffect(() => {
        fetchTransactionHistory();
    }, [fetchTransactionHistory]);
    return (React.createElement("div", null, isLoading ? (React.createElement("div", null, React.createElement(LinearProgress, null))) : ((_a = transactionHistory === null || transactionHistory === void 0 ? void 0 : transactionHistory.pageList) === null || _a === void 0 ? void 0 : _a.length) > 0 ? (React.createElement(AmbientCard, null, React.createElement(UdpTimeline, null, (_b = transactionHistory === null || transactionHistory === void 0 ? void 0 : transactionHistory.pageList) === null || _b === void 0 ? void 0 : _b.map((item, index) => {
        var _a, _b, _c;
        var _d;
        return (React.createElement(TransactionTimelineItem, { key: index, item: item, title: (_d = (_a = item === null || item === void 0 ? void 0 : item.udpTransactionHistoryUdpTransactionTypeTransactionAction) === null || _a === void 0 ? void 0 : _a.name) !== null && _d !== void 0 ? _d : (_b = item === null || item === void 0 ? void 0 : item.udpTransactionHistoryUdpTransactionEventType) === null || _b === void 0 ? void 0 : _b.name, description: (item === null || item === void 0 ? void 0 : item.changedByName) ? `By ${item === null || item === void 0 ? void 0 : item.changedByName}` : null, date: (item === null || item === void 0 ? void 0 : item.createdOn)
                ? formatDate(item === null || item === void 0 ? void 0 : item.createdOn, 'dd/mm/yyyy')
                : null, status: (_c = item === null || item === void 0 ? void 0 : item.udpTransactionHistoryUdpTransactionTypeStatus) === null || _c === void 0 ? void 0 : _c.name, onClick: handleOnClick }));
    })))) : (React.createElement("div", null, React.createElement(EmptyStateDisplay, { primaryText: t('No History') }))), udpDomainObjects && (React.createElement(React.Fragment, null, React.createElement(SideSheet, { title: t('Domain Comparison'), width: 700, open: sideSheetOpen, onClose: handleOnSideSheetClose, PaperProps: {
            style: { maxWidth: '100vw' }
        } }, React.createElement(TransactionChangeLog, { oldData: udpDomainObjects.previous, newData: udpDomainObjects.current }))))));
});
TransactionTimeline.displayName = 'TransactionTimeline';
export default TransactionTimeline;
//# sourceMappingURL=TransactionTimeline.js.map