import React, { useState, useMemo, useRef, useCallback, useEffect } from 'react';
import ViewTransaction from './sidesheets/ViewTransaction';
import AttachmentTransaction from './sidesheets/AttachmentTransaction';
import { LinearProgress, SideSheet } from '../../../UI';
import WorkflowActions from './sidesheets/WorkflowActions';
import EditTransaction from './sidesheets/EditTransaction';
import { useTransactionEngine } from '../../../utilities/transactions/useTransactionEngine';
import { TransactionUiActionTypeEnums } from '../../../enums';
import UdpTransactionCustomPage from './components/UdpTransactionCustomPage';
import { apiMutate, useAxiosMutate } from '../../../utilities';
import { ConfigService } from '../../../configService';
import { useHandleAxiosSnackbar } from '../../../utilities';
import { useTranslation } from 'react-i18next';
import { FluentDialog } from '../../../UI';
import { PageContainer } from '../../../page/PageContainer';
import { Attachments } from '../../../uploader';
import { allowedExtensions, MAX_FILE_SIZE_MB } from '../../../uploader/utils/allowedFileProperties';
import { useSnackbar } from 'notistack';
import { Badge } from '@material-ui/core';
import DynamicTransactionDomainForm from './components/DynamicTransactionDomainForm';
const UdpTransactionSidesheet = (props) => {
    var _a, _b;
    var _c;
    const { openStates, handleSidesheet, handleAttachmentTransaction, transaction, transactionTypeId, domainName, refreshGridData, label: sidesheetLabel, hideSaveChanges, catalogObject } = props;
    const [sidesheetLoading, setSidesheetLoading] = useState(false);
    const [closingTransactionLoading, setClosingTransactionLoading] = useState(false);
    const [editTransactionopenInnerSidesheetState, setEditTransactionOpenInnerSidesheetState] = useState({
        attachments: false,
        workflowActions: false,
        notes: false
    });
    const [dialogOpen, setDialogOpen] = useState(false);
    const [unsavedChangesDialogOpen, setUnsavedChangesDialogOpen] = useState(false);
    const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
    const [createTransactionOpenInnerSidesheetState, setCreateTransactionOpenInnerSidesheetState] = useState({
        attachments: false
    });
    const [attachmentType, setAttachmentType] = useState(null);
    const [currentAttachments, setCurrentAttachments] = useState([]);
    const [attachmentProgress, setAttachmentProgress] = useState(false);
    const [transactionAttachments, setTransactionAttachments] = useState([]);
    const [filePreview, setFilePreview] = useState(false);
    const [sidesheetPrimaryButtonDisabled, setSidesheetPrimaryButtonDisabled] = useState(false);
    const [sidesheetSecondaryButtonDisabled, setSidesheetSecondaryButtonDisabled] = useState(false);
    const { handleSuccessSnackbar, handleErrorSnackbar } = useHandleAxiosSnackbar();
    const { hasClosedStatus, checkIfTransactionIsClosed, getTransactionTypeLabel, getUiActionRenderParameters, transactionTypePageConfiguration, closedStatuses } = useTransactionEngine(transactionTypeId);
    const { t } = useTranslation();
    const formRef = useRef(null);
    const createdTransactionIdRef = useRef(null);
    const attachmentRef = useRef();
    const sidesheetWidth = (_c = openStates === null || openStates === void 0 ? void 0 : openStates.width) !== null && _c !== void 0 ? _c : 800;
    const transactionTypeEntry = transaction === null || transaction === void 0 ? void 0 : transaction.entityBusinessObject;
    const { enqueueSnackbar } = useSnackbar();
    const [{ data: transactionAttachmentTypes }, fetchTransactionAttachmentType] = useAxiosMutate(ConfigService.productV1ApiUrl, `UdpTransactionAttachmentType/search`, {
        method: 'post',
        data: {
            pageSize: 50,
            filterElements: [
                {
                    searchField: 'TransactionTypeId',
                    searchValue: transactionTypeId,
                    searchOperator: '='
                }
            ]
        }
    });
    const handleDialogClose = () => {
        setDialogOpen(false);
    };
    const handleUnsavedChangesDialogClose = () => {
        setUnsavedChangesDialogOpen(false);
    };
    const handleResetAttachmentState = useCallback((resetSavedAttachmentsState) => {
        if (resetSavedAttachmentsState) {
            setAttachmentType(null);
            setCurrentAttachments([]);
        }
        setAttachmentProgress(false);
        setTransactionAttachments([]);
        setFilePreview(false);
    }, []);
    const executeCloseTransaction = useCallback(async () => {
        // setSidesheetLoading(true);
        const response = await apiMutate(ConfigService.productV1ApiUrl, `udpTransaction/${transaction === null || transaction === void 0 ? void 0 : transaction.transactionId}/closeTransaction`, {
            method: 'post'
        });
        // setSidesheetLoading(false);
        if ((response === null || response === void 0 ? void 0 : response.status) === 200) {
            handleSidesheet('edit', false);
            refreshGridData();
            handleSuccessSnackbar(t(`Transaction has been closed successfully`));
        }
        else {
            handleErrorSnackbar(new Error(t(`Error closing Transaction. Please try again later.`)));
        }
    }, [
        transaction,
        refreshGridData,
        handleSidesheet,
        handleSuccessSnackbar,
        handleErrorSnackbar,
        t
    ]);
    const handleConfirmCloseTransactionDialog = useCallback(async () => {
        try {
            setClosingTransactionLoading(true);
            await executeCloseTransaction();
        }
        catch (error) {
            handleErrorSnackbar(error);
        }
        finally {
            setClosingTransactionLoading(false);
            handleDialogClose();
        }
    }, [executeCloseTransaction, handleErrorSnackbar]);
    const formattedBusinesskey = (_b = (_a = transactionTypeEntry === null || transactionTypeEntry === void 0 ? void 0 : transactionTypeEntry.businessObjectKey) === null || _a === void 0 ? void 0 : _a.split('|')) === null || _b === void 0 ? void 0 : _b.pop();
    const handleTransactionCreationSuccess = useCallback((response) => {
        var _a;
        var _b;
        createdTransactionIdRef.current = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.transactionId) !== null && _b !== void 0 ? _b : null;
        handleSidesheet('add', false);
        handleResetAttachmentState(true);
    }, [handleSidesheet, handleResetAttachmentState]);
    const handleTransactionRevisionCreationSuccess = useCallback((response) => {
        handleSidesheet('createRevision', false);
        refreshGridData();
    }, [handleSidesheet, refreshGridData]);
    const handleFilesSelectedForUpload = useCallback(() => {
        setCreateTransactionOpenInnerSidesheetState({ attachments: false });
        enqueueSnackbar(`${currentAttachments.length} file(s) added for upload`, {
            variant: 'success',
            anchorOrigin: {
                vertical: 'top',
                horizontal: 'center'
            }
        });
    }, [enqueueSnackbar, currentAttachments.length]);
    const handleUploadFilesForCreateTransaction = useCallback(async (transactionId) => {
        if (!currentAttachments.length) {
            throw new Error('No files added for upload');
        }
        const formData = new FormData();
        currentAttachments.forEach((file) => formData.append('files', file));
        formData.append('attachmentTypeId', attachmentType.transactionAttachmentTypeId);
        try {
            setAttachmentProgress(true);
            await apiMutate(ConfigService.productV1ApiUrl, `UdpTransactionAttachment/transaction/${transactionId}/upload`, {
                method: 'post',
                headers: {
                    transactionId: transactionId,
                    attachmentTypeId: attachmentType.transactionAttachmentTypeId
                },
                data: formData
            });
            setCurrentAttachments([]);
            setCreateTransactionOpenInnerSidesheetState({ attachments: false });
            enqueueSnackbar('Files uploaded successfully', {
                variant: 'success',
                anchorOrigin: {
                    vertical: 'top',
                    horizontal: 'center'
                }
            });
        }
        catch (error) {
            enqueueSnackbar(`File upload failed: We encountered a system error. Please try again or contact support if the issue persists.`, {
                variant: 'error',
                anchorOrigin: {
                    vertical: 'top',
                    horizontal: 'center'
                }
            });
            throw error;
        }
        finally {
            setAttachmentProgress(false);
        }
    }, [
        attachmentType,
        currentAttachments,
        enqueueSnackbar,
        setCurrentAttachments,
        setAttachmentProgress
    ]);
    const handleTransactionCreation = useCallback(async () => {
        var _a, _b;
        setSidesheetLoading(true);
        createdTransactionIdRef.current = null;
        await ((_b = (_a = formRef.current) === null || _a === void 0 ? void 0 : _a.form) === null || _b === void 0 ? void 0 : _b.submit());
        const newTransactionId = createdTransactionIdRef.current;
        if (newTransactionId && currentAttachments.length > 0) {
            await handleUploadFilesForCreateTransaction(newTransactionId);
        }
        refreshGridData();
        setSidesheetLoading(false);
    }, [
        formRef,
        currentAttachments.length,
        handleUploadFilesForCreateTransaction,
        refreshGridData
    ]);
    const handleCreateRevision = useCallback(async () => {
        var _a, _b;
        setSidesheetLoading(true);
        await ((_b = (_a = formRef.current) === null || _a === void 0 ? void 0 : _a.form) === null || _b === void 0 ? void 0 : _b.submit());
        setSidesheetLoading(false);
    }, [formRef]);
    const handleNextStepsAction = useCallback(() => {
        if (!hasUnsavedChanges) {
            setEditTransactionOpenInnerSidesheetState({ workflowAction: true });
        }
        else {
            setUnsavedChangesDialogOpen(true);
        }
    }, [hasUnsavedChanges]);
    const handleConfirmUnsavedChangesDialog = useCallback(() => {
        setUnsavedChangesDialogOpen(false);
        setEditTransactionOpenInnerSidesheetState({ workflowAction: true });
    }, []);
    const pdfViewPageId = useMemo(() => {
        var _a;
        return (_a = getUiActionRenderParameters(TransactionUiActionTypeEnums.Render_View_Pdf_Page)) === null || _a === void 0 ? void 0 : _a.pageId;
    }, [getUiActionRenderParameters]);
    const viewTransactionPage = useMemo(() => {
        if (pdfViewPageId) {
            return (React.createElement(PageContainer, { pageId: pdfViewPageId, widgetParams: { transaction } }));
        }
        else {
            return React.createElement(ViewTransaction, { transaction: transaction });
        }
    }, [transaction, pdfViewPageId]);
    const transactionIsClosed = useMemo(() => {
        return checkIfTransactionIsClosed(transaction);
    }, [checkIfTransactionIsClosed, transaction]);
    const transactionLabel = useMemo(() => {
        var _a;
        return ` ${(_a = getTransactionTypeLabel(transaction)) !== null && _a !== void 0 ? _a : `${domainName} ${formattedBusinesskey !== null && formattedBusinesskey !== void 0 ? formattedBusinesskey : ''}`}`;
    }, [getTransactionTypeLabel, transaction, formattedBusinesskey, domainName]);
    const sheetLabel = useMemo(() => {
        if (sidesheetLabel) {
            return sidesheetLabel;
        }
        return transactionLabel;
    }, [sidesheetLabel, transactionLabel]);
    const transactionCreatePageId = useMemo(() => {
        var _a;
        return (_a = getUiActionRenderParameters(TransactionUiActionTypeEnums.Render_Create_Transaction_Page)) === null || _a === void 0 ? void 0 : _a.pageId;
    }, [getUiActionRenderParameters]);
    const sidesheetList = useMemo(() => {
        const list = [
            {
                open: openStates.addTransaction,
                closeSheet: () => {
                    handleSidesheet('add', false);
                    handleResetAttachmentState(true);
                },
                title: (sheetLabel === null || sheetLabel === void 0 ? void 0 : sheetLabel.trim()) || domainName,
                width: sidesheetWidth,
                onSubmit: handleTransactionCreation,
                children: (React.createElement(React.Fragment, null, transactionCreatePageId ? (React.createElement(UdpTransactionCustomPage, { transactionTypeId: transactionTypeId, transactionUiActionType: TransactionUiActionTypeEnums.Render_Create_Transaction_Page, formRef: formRef, onSubmitSuccess: handleTransactionCreationSuccess, refreshGridData: refreshGridData, additionalPageParms: {
                        sidesheetParams: {
                            setSidesheetPrimaryButtonDisabled,
                            setSidesheetSecondaryButtonDisabled
                        }
                    } })) : (React.createElement(DynamicTransactionDomainForm, { transaction: transaction, formRef: formRef, domainName: domainName, transactionTypeId: transactionTypeId, transactionUiActionType: TransactionUiActionTypeEnums.Render_Create_Transaction_Page, onSubmitSuccess: handleTransactionCreationSuccess, catalogObject: catalogObject })), React.createElement(SideSheet, { key: 'Create Transaction: Add Attachment', open: createTransactionOpenInnerSidesheetState === null || createTransactionOpenInnerSidesheetState === void 0 ? void 0 : createTransactionOpenInnerSidesheetState.attachments, width: 600, title: t('Add Attachment'), onClose: () => {
                        setCreateTransactionOpenInnerSidesheetState({
                            attachments: false
                        });
                        handleResetAttachmentState(true);
                    }, buttonLabel: t('Save'), buttonOneDisabled: !attachmentType || currentAttachments.length <= 0, onSubmit: handleFilesSelectedForUpload, color: "primary" }, React.createElement(Attachments, { attachmentTypes: transactionAttachmentTypes, attachmentType: attachmentType, setAttachmentType: setAttachmentType, attachmentProgress: attachmentProgress, setAttachmentProgress: setAttachmentProgress, currentAttachments: currentAttachments, setCurrentAttachments: setCurrentAttachments, transaction: transaction, previousAttachments: transactionAttachments, setPreviousAttachments: setTransactionAttachments, MAX_FILE_SIZE_MB: MAX_FILE_SIZE_MB, allowedExtensions: allowedExtensions, filePreview: filePreview, setFilePreview: setFilePreview })))),
                buttonLabel: 'Add',
                buttonTwoLabel: (React.createElement(Badge, { badgeContent: currentAttachments === null || currentAttachments === void 0 ? void 0 : currentAttachments.length, color: "primary" }, 'Add Attachment')),
                buttonTwoAction: () => setCreateTransactionOpenInnerSidesheetState({ attachments: true })
            },
            {
                open: openStates.viewTransaction,
                closeSheet: () => handleSidesheet('view', false),
                title: sheetLabel + ' - Preview',
                width: sidesheetWidth,
                children: viewTransactionPage,
                buttonLabel: !pdfViewPageId ? 'Download' : null
            },
            {
                open: openStates.attachmentTransaction,
                closeSheet: () => handleSidesheet('view', false),
                title: 'Attachment for ' + sheetLabel,
                width: sidesheetWidth,
                buttonLabel: 'Download',
                onSubmit: () => {
                    if (attachmentRef.current) {
                        attachmentRef.current.downloadSelectedFile();
                    }
                },
                children: (React.createElement(AttachmentTransaction, { handleAttachmentTransaction: handleAttachmentTransaction, attachmentRef: attachmentRef, transaction: transaction, domainName: domainName, setSidesheetLoading: setSidesheetLoading }))
            },
            {
                open: openStates.workflowAction,
                closeSheet: () => handleSidesheet('action', false),
                title: `Workflow Actions - ${sheetLabel}`,
                width: sidesheetWidth,
                children: (React.createElement(WorkflowActions, { transaction: transaction, closeSideSheet: () => {
                        handleSidesheet('action', false);
                    }, refreshGridData: refreshGridData, handleSidesheet: handleSidesheet }))
            },
            {
                open: openStates.editTransaction,
                closeSheet: () => {
                    handleSidesheet('edit', false);
                    handleResetAttachmentState(true);
                },
                title: `Edit ${sheetLabel}`,
                width: sidesheetWidth,
                buttonLabel: 'Next Steps',
                buttonOneDisabled: transactionIsClosed,
                onSubmit: handleNextStepsAction,
                buttonTwoLabel: (closedStatuses === null || closedStatuses === void 0 ? void 0 : closedStatuses.length) === 1 ? 'Close ' + domainName : null,
                buttonTwoDisabled: transactionIsClosed || !hasClosedStatus,
                buttonTwoAction: () => setDialogOpen(true),
                children: (React.createElement(EditTransaction, { transaction: transaction, transactionTypeId: transactionTypeId, transactionIsClosed: transactionIsClosed, openInnerSidesheetState: editTransactionopenInnerSidesheetState, setOpenInnerSidesheetState: setEditTransactionOpenInnerSidesheetState, refreshGridData: refreshGridData, closeSideSheet: () => {
                        handleSidesheet('edit', false);
                        handleResetAttachmentState(true);
                    }, setSidesheetLoading: setSidesheetLoading, setHasUnsavedChanges: setHasUnsavedChanges, attachmentType: attachmentType, setAttachmentType: setAttachmentType, currentAttachments: currentAttachments, setCurrentAttachments: setCurrentAttachments, attachmentProgress: attachmentProgress, setAttachmentProgress: setAttachmentProgress, transactionAttachmentTypes: transactionAttachmentTypes, transactionAttachments: transactionAttachments, setTransactionAttachments: setTransactionAttachments, filePreview: filePreview, setFilePreview: setFilePreview, domainName: domainName, additionalPageParms: {
                        sidesheetParams: {
                            setSidesheetPrimaryButtonDisabled,
                            setSidesheetSecondaryButtonDisabled
                        }
                    }, hideSaveChanges: hideSaveChanges ||
                        (transactionTypePageConfiguration === null || transactionTypePageConfiguration === void 0 ? void 0 : transactionTypePageConfiguration.hideSaveChanges), catalogObject: catalogObject }))
            },
            {
                open: openStates.createRevision,
                closeSheet: () => handleSidesheet('createRevision', false),
                title: `Create Revision for ${domainName}`,
                width: sidesheetWidth,
                onSubmit: handleCreateRevision,
                children: (React.createElement(UdpTransactionCustomPage, { transactionTypeId: transactionTypeId, transactionUiActionType: TransactionUiActionTypeEnums.Render_Create_Revision_Page, formRef: formRef, transaction: transaction, onSubmitSuccess: handleTransactionRevisionCreationSuccess, refreshGridData: refreshGridData, additionalPageParms: {
                        sidesheetParams: {
                            setSidesheetPrimaryButtonDisabled,
                            setSidesheetSecondaryButtonDisabled
                        }
                    } })),
                buttonLabel: 'Create Revision'
            }
        ];
        return list;
    }, [
        openStates,
        handleSidesheet,
        handleAttachmentTransaction,
        transaction,
        domainName,
        editTransactionopenInnerSidesheetState,
        setEditTransactionOpenInnerSidesheetState,
        sheetLabel,
        refreshGridData,
        transactionTypeId,
        handleTransactionCreation,
        handleTransactionCreationSuccess,
        hasClosedStatus,
        handleCreateRevision,
        transactionIsClosed,
        viewTransactionPage,
        pdfViewPageId,
        sidesheetWidth,
        handleNextStepsAction,
        transactionCreatePageId,
        createTransactionOpenInnerSidesheetState,
        t,
        attachmentType,
        setAttachmentType,
        currentAttachments,
        setCurrentAttachments,
        attachmentProgress,
        setAttachmentProgress,
        transactionAttachmentTypes,
        transactionAttachments,
        setTransactionAttachments,
        filePreview,
        setFilePreview,
        handleResetAttachmentState,
        handleFilesSelectedForUpload,
        handleTransactionRevisionCreationSuccess,
        hideSaveChanges,
        transactionTypePageConfiguration
    ]);
    useEffect(() => {
        if (((openStates === null || openStates === void 0 ? void 0 : openStates.addTransaction) || (openStates === null || openStates === void 0 ? void 0 : openStates.editTransaction)) &&
            !transactionAttachmentTypes) {
            setAttachmentProgress(true);
            fetchTransactionAttachmentType().then(() => {
                setAttachmentProgress(false);
            });
        }
    }, [
        fetchTransactionAttachmentType,
        transactionAttachmentTypes,
        openStates.addTransaction,
        openStates.editTransaction
    ]);
    return (React.createElement(React.Fragment, null, openStates &&
        sidesheetList.map((item) => {
            return (React.createElement(SideSheet, { key: item.title, open: item.open, width: sidesheetWidth, title: item.title, onClose: item.closeSheet, noPadding: openStates.attachmentTransaction || openStates.editTransaction, buttonLabel: item === null || item === void 0 ? void 0 : item.buttonLabel, onSubmit: item === null || item === void 0 ? void 0 : item.onSubmit, color: "primary", buttonTwoLabel: item === null || item === void 0 ? void 0 : item.buttonTwoLabel, buttonTwoAction: item === null || item === void 0 ? void 0 : item.buttonTwoAction, buttonOneDisabled: (item === null || item === void 0 ? void 0 : item.buttonOneDisabled) || sidesheetPrimaryButtonDisabled, buttonTwoDisabled: (item === null || item === void 0 ? void 0 : item.buttonTwoDisabled) || sidesheetSecondaryButtonDisabled, progress: sidesheetLoading, variant: "indeterminate" }, React.createElement("div", null, item.children)));
        }), React.createElement(FluentDialog, { title: t(`Close Transaction`), message: `Are you sure you want to close transaction for ${(transaction === null || transaction === void 0 ? void 0 : transaction.entityBusinessKey) || ''}?`, labelOne: t('Confirm'), actionOne: handleConfirmCloseTransactionDialog, labelTwo: t('Cancel'), actionTwo: handleDialogClose, open: dialogOpen, handleClose: handleDialogClose, loading: closingTransactionLoading }), React.createElement(FluentDialog, { title: t(`Unsaved Changes`), message: `You have unsaved changes. Are you sure you want to go to next steps?`, labelOne: t('Confirm'), actionOne: handleConfirmUnsavedChangesDialog, labelTwo: t('Cancel'), actionTwo: handleUnsavedChangesDialogClose, open: unsavedChangesDialogOpen, handleClose: handleUnsavedChangesDialogClose, loading: closingTransactionLoading })));
};
export default UdpTransactionSidesheet;
//# sourceMappingURL=UdpTransactionSidesheet.js.map