import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react';
import { useAxiosGet } from '../utilities/useAxiosGet';
import { makeStyles } from '@material-ui/core';
import { PageContainer } from '../page/PageContainer';
import { useUser } from '../utilities/auth/useUser';
import { PrimaryActionHeader } from '../UI/utilityDisplay/utilityHeader/PrimaryActionHeader';
import { Card } from '@material-ui/core';
import { useWorkflowStore } from '../stores/workflowStore';
import { apiMutate } from '../utilities/useAxiosMutate';
import { WorkflowTaskFlow } from './components/WorkflowTaskFlow';
import { orderBy } from 'lodash-es';
import { UnitStateType } from '../enums/workflowEnums';
import { LinearProgress } from '../UI/loading/LinearProgress';
import { FluentTextFieldAutoComplete } from '../UI/inputs/textField/FluentTextFieldAutoComplete';
import { useTranslation } from 'react-i18next';
import { CancelIcon, ForwardIcon } from '@fluentui/react-icons';
import { SideSheet } from '../UI/surfaces/SideSheet';
import { Field, Form } from '../utilities/form';
import { cloneDeep } from 'lodash-es';
import { CircularProgress } from '../UI/loading/CircularProgress';
import { ConfigService } from '../configService';
const useStyles = makeStyles((theme) => ({
    root: {},
    loadingContent: {
        flex: 1,
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        height: 'calc(100vh - 160px)'
    }
}));
export const WorkflowUiInterruptContent = (props) => {
    var _a, _b, _c;
    const { selectedNode, workflow, reloadWorkflow, users, groups, handleClose, inquiryPageParams = {} } = props;
    const classes = useStyles();
    const [selectedPageId, setSelectedPageId] = useState('');
    const [currentWorkflowStep, setCurrentWorkflowStep] = useState(0);
    const [loading, setLoading] = useState(false);
    const [loadingTaskData, setLoadingTaskData] = useState(true);
    const [reassignSidesheetOpen, setReassignSidesheetOpen] = useState(false);
    const [reassigningAssignee, setReassigningAssignee] = useState(false);
    const [workflowPageData, setWorkflowPageData] = useState(null);
    const [orderedPageData, setOrderedPageData] = useState([]);
    const user = useUser();
    const taskDataMap = useWorkflowStore((state) => state.taskDataMap);
    const setTaskDataMap = useWorkflowStore((state) => state.setTaskDataMap);
    const { t } = useTranslation();
    const formRef = useRef(null);
    const [{ data: pageData, loading: pageLoading, error: pageError }] = useAxiosGet(ConfigService.tenantV1ApiUrl, `page/${selectedPageId}`, {}, !!!selectedPageId, false);
    const [{ data: playScene, loading: playSceneLoading, error: playSceneError }, fetchPlayScene] = useAxiosGet(ConfigService.maestroV1ApiUrl, `maestro/play/scene/${((_a = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _a === void 0 ? void 0 : _a.playSceneId) || null}?includeData=true`, {}, !!!((_b = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _b === void 0 ? void 0 : _b.playSceneId), false);
    const updatePlaySceneData = useCallback(async (data = '') => {
        var _a;
        return apiMutate(ConfigService.maestroV1ApiUrl, `maestro/play/scene/${((_a = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _a === void 0 ? void 0 : _a.playSceneId) || null}/data`, {
            method: 'put'
        }, { data: data });
    }, [selectedNode]);
    const updatePlaySceneState = useCallback(async (data = {}, sceneState) => {
        var _a;
        return apiMutate(ConfigService.maestroV1ApiUrl, `maestro/play/scene/${((_a = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _a === void 0 ? void 0 : _a.playSceneId) || null}/${sceneState}`, {
            method: 'put'
        }, { data: data });
    }, [selectedNode]);
    const updatePlaySceneAssignee = useCallback(async (data = '') => {
        var _a;
        return apiMutate(ConfigService.maestroV1ApiUrl, `maestro/play/scene/${((_a = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _a === void 0 ? void 0 : _a.playSceneId) || null}/assignee`, {
            method: 'put'
        }, { data: data });
    }, [selectedNode]);
    const closeReassignmentSheet = useCallback(() => {
        setReassignSidesheetOpen(false);
    }, []);
    const workflowTaskSteps = useMemo(() => {
        var _a;
        if (!((_a = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _a === void 0 ? void 0 : _a.interruptPages)) {
            return [];
        }
        const orderedInterruptPages = orderBy(selectedNode.properties.interruptPages, ['sequenceNo'], ['asc']);
        const steps = orderedInterruptPages.reduce((list, ip) => {
            var _a, _b;
            const step = {
                label: ip.displayName || ((_a = ip.page) === null || _a === void 0 ? void 0 : _a.name),
                pageId: (_b = ip.page) === null || _b === void 0 ? void 0 : _b.pageId,
                requiredFieldMapping: ip.requiredFieldMapping
            };
            list.push(step);
            return list;
        }, []);
        return steps;
    }, [selectedNode]);
    const assigneeOptions = useMemo(() => {
        const formattedUsers = (users === null || users === void 0 ? void 0 : users.reduce((list, user) => {
            list.push({
                id: (user === null || user === void 0 ? void 0 : user.unityId) || '',
                name: `${user === null || user === void 0 ? void 0 : user.displayName} - (User)` || ''
            });
            return list;
        }, [])) || [];
        const formattedGroups = groups.reduce((list, group) => {
            list.push({
                id: (group === null || group === void 0 ? void 0 : group.groupId) || '',
                name: `${group === null || group === void 0 ? void 0 : group.name} - (Group)` || ''
            });
            return list;
        }, []) || [];
        const options = formattedUsers.concat(formattedGroups);
        return options;
    }, [users, groups]);
    const saveCurrentWorkflowData = useCallback(async () => {
        var _a;
        let playSceneData = null;
        if ((_a = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _a === void 0 ? void 0 : _a.playSceneId) {
            playSceneData = taskDataMap[selectedNode.properties.playSceneId];
        }
        if (playSceneData) {
            await updatePlaySceneData({
                data: JSON.stringify(playSceneData)
            });
            await fetchPlayScene();
        }
    }, [taskDataMap, fetchPlayScene, updatePlaySceneData, selectedNode]);
    const updateWorkflowPageData = useCallback(async (data, pageId) => {
        var _a, _b, _c, _d, _e, _f;
        if (!((_a = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _a === void 0 ? void 0 : _a.playSceneId) || !pageId) {
            console.warn('No TaskId or PageId availble to save Workflow Page Data');
            return;
        }
        if (((_b = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _b === void 0 ? void 0 : _b.state) === UnitStateType.Initial ||
            ((_c = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _c === void 0 ? void 0 : _c.state) === UnitStateType.Completed ||
            ((_d = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _d === void 0 ? void 0 : _d.state) === UnitStateType.Cancelled ||
            ((_e = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _e === void 0 ? void 0 : _e.state) === UnitStateType.Failed) {
            return;
        }
        let playSceneData = null;
        if ((_f = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _f === void 0 ? void 0 : _f.playSceneId) {
            playSceneData = taskDataMap[selectedNode.properties.playSceneId];
            if (playSceneData) {
                playSceneData[pageId] = data;
            }
        }
        if (playSceneData) {
            await updatePlaySceneData({
                data: JSON.stringify(playSceneData)
            });
            await fetchPlayScene();
        }
    }, [selectedNode, fetchPlayScene, taskDataMap, updatePlaySceneData]);
    const handleTaskChange = useCallback(async (step) => {
        setCurrentWorkflowStep(step);
    }, []);
    const handleTaskSubmit = useCallback(async () => {
        setLoading(true);
        await saveCurrentWorkflowData();
        await updatePlaySceneState('', 2);
        await reloadWorkflow();
        setLoading(false);
    }, [updatePlaySceneState, reloadWorkflow, saveCurrentWorkflowData]);
    const secondaryButtons = useMemo(() => {
        var _a;
        const buttons = [];
        if (handleClose) {
            buttons.push({
                label: t('Close'),
                component: CancelIcon,
                click: () => handleClose()
            });
        }
        if (((_a = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _a === void 0 ? void 0 : _a.state) !== UnitStateType.Started) {
            return buttons;
        }
        buttons.push({
            label: t('Reassign'),
            component: ForwardIcon,
            click: () => setReassignSidesheetOpen(true)
        });
        return buttons;
    }, [t, selectedNode, handleClose]);
    const handleReassignment = useCallback(() => {
        formRef === null || formRef === void 0 ? void 0 : formRef.current.form.submit();
    }, []);
    const reassignTask = useCallback(async (values) => {
        var _a;
        setReassigningAssignee(true);
        await updatePlaySceneAssignee({
            data: ((_a = values === null || values === void 0 ? void 0 : values.assignee) === null || _a === void 0 ? void 0 : _a.id) || ''
        });
        await fetchPlayScene();
        setReassigningAssignee(false);
        closeReassignmentSheet();
    }, [updatePlaySceneAssignee, fetchPlayScene, closeReassignmentSheet]);
    const requiredFieldMapping = useMemo(() => {
        var _a, _b;
        const step = workflowTaskSteps === null || workflowTaskSteps === void 0 ? void 0 : workflowTaskSteps.find((wts) => wts.pageId === (pageData === null || pageData === void 0 ? void 0 : pageData.pageId));
        let fieldMapping = (step === null || step === void 0 ? void 0 : step.requiredFieldMapping)
            ? cloneDeep(step.requiredFieldMapping)
            : {};
        const workflowVariables = ((_a = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _a === void 0 ? void 0 : _a.variables) || null;
        if (!!fieldMapping && !!workflowVariables) {
            (_b = Object.keys(fieldMapping)) === null || _b === void 0 ? void 0 : _b.forEach((rfmKey) => {
                const requiredField = fieldMapping[rfmKey];
                if (!!(requiredField === null || requiredField === void 0 ? void 0 : requiredField.value)) {
                    if ((requiredField === null || requiredField === void 0 ? void 0 : requiredField.type) === 'workflowVariable') {
                        let matchedVariable = false;
                        Object.keys(workflowVariables).forEach((key) => {
                            if (requiredField.value === key) {
                                requiredField.value = workflowVariables[key] || '';
                                matchedVariable = true;
                                return;
                            }
                        });
                        if (!matchedVariable) {
                            requiredField.value = null;
                        }
                    }
                }
            });
        }
        return fieldMapping || {};
    }, [pageData === null || pageData === void 0 ? void 0 : pageData.pageId, selectedNode, workflowTaskSteps]);
    const pageWidgetParams = useMemo(() => {
        const requiredFieldsMap = Object.keys(requiredFieldMapping).reduce((fieldMap, key) => {
            var _a;
            fieldMap[key] = ((_a = requiredFieldMapping[key]) === null || _a === void 0 ? void 0 : _a.value) || '';
            return fieldMap;
        }, {});
        // have to pass in unimplemented parameters because certain pages
        // are used in action sheets/screens
        return Object.assign(Object.assign({ setSideSheetWidth: () => {
                console.warn('setSideSheetWidth Not implemented');
            }, setSideSheetButtonLabel: () => {
                console.warn('setSideSheetButtonLabel Not implemented');
            }, setSideSheetOnSubmit: () => {
                console.warn('setSideSheetOnSubmit Not implemented');
            }, setSideSheetAdditionalOnClose: () => {
                console.warn('setSideSheetAdditionalOnClose Not implemented');
            }, setSideSheetProps: () => {
                console.warn('setSideSheetProps Not implemented');
            }, closeSideSheet: () => {
                console.warn('closeSideSheet Not implemented');
            }, onCreate: () => {
                console.warn('onCreate Not implemented');
            }, onUpdate: () => {
                console.warn('onUpdate Not implemented');
            } }, inquiryPageParams), { pageId: pageData === null || pageData === void 0 ? void 0 : pageData.pageId, updateWorkflowPageData: (data) => updateWorkflowPageData(data, pageData === null || pageData === void 0 ? void 0 : pageData.pageId), workflowTask: selectedNode, workflowPageData: Object.assign(Object.assign({}, requiredFieldsMap), workflowPageData), requiredFieldsMap: requiredFieldMapping || null, currentWorkflowStep, orderedWorkflowPageData: orderedPageData });
    }, [
        pageData === null || pageData === void 0 ? void 0 : pageData.pageId,
        selectedNode,
        workflowPageData,
        updateWorkflowPageData,
        requiredFieldMapping,
        inquiryPageParams,
        currentWorkflowStep,
        orderedPageData
    ]);
    const currentAssignee = useMemo(() => {
        if (!(playScene === null || playScene === void 0 ? void 0 : playScene.assignee) || !(assigneeOptions === null || assigneeOptions === void 0 ? void 0 : assigneeOptions.length)) {
            return '';
        }
        const matchingAssignee = assigneeOptions.find((assignee) => assignee.id === playScene.assignee);
        return matchingAssignee || '';
    }, [playScene, assigneeOptions]);
    const pageHeight = useMemo(() => 'calc(100vh - 162px)', []);
    useEffect(() => {
        var _a, _b;
        if (!((_a = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _a === void 0 ? void 0 : _a.playSceneId) ||
            !selectedPageId ||
            loadingTaskData) {
            setWorkflowPageData(null);
            return;
        }
        if ((taskDataMap === null || taskDataMap === void 0 ? void 0 : taskDataMap[selectedNode.properties.playSceneId]) &&
            taskDataMap[selectedNode.properties.playSceneId][selectedPageId]) {
            setWorkflowPageData(taskDataMap[selectedNode.properties.playSceneId][selectedPageId]);
            return;
        }
        // Use this condition for making sure workflowPageData is resolved before
        // returning value so that PageContainer will render
        if (Object.keys(taskDataMap).length &&
            ((_b = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _b === void 0 ? void 0 : _b.playSceneId) &&
            selectedPageId &&
            !playSceneLoading &&
            !loadingTaskData) {
            setWorkflowPageData((prevData) => {
                if (!prevData) {
                    return {};
                }
                else if (!Object.keys(prevData).length) {
                    return prevData;
                }
            });
            return;
        }
        setWorkflowPageData(null);
    }, [
        selectedNode,
        selectedPageId,
        taskDataMap,
        loadingTaskData,
        playSceneLoading,
        workflowTaskSteps
    ]);
    useEffect(() => {
        var _a;
        if (workflowTaskSteps === null || workflowTaskSteps === void 0 ? void 0 : workflowTaskSteps.length) {
            setSelectedPageId((_a = workflowTaskSteps[currentWorkflowStep]) === null || _a === void 0 ? void 0 : _a.pageId);
        }
    }, [workflowTaskSteps, currentWorkflowStep]);
    useEffect(() => {
        var _a;
        setLoadingTaskData(true);
        if (!playSceneLoading && ((_a = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _a === void 0 ? void 0 : _a.playSceneId)) {
            const json = (playScene === null || playScene === void 0 ? void 0 : playScene.data) ? JSON.parse(playScene.data) : {};
            setTaskDataMap(selectedNode.properties.playSceneId, json);
        }
        setLoadingTaskData(false);
    }, [playScene, playSceneLoading, setTaskDataMap, selectedNode]);
    useEffect(() => {
        const orderedData = [];
        if (taskDataMap === null || taskDataMap === void 0 ? void 0 : taskDataMap[selectedNode.properties.playSceneId]) {
            workflowTaskSteps.forEach((step) => {
                orderedData.push(taskDataMap[selectedNode.properties.playSceneId][step.pageId] || {});
            });
        }
        setOrderedPageData(orderedData);
    }, [taskDataMap, workflowTaskSteps, selectedNode]);
    return (React.createElement("div", null, React.createElement(Card, { variant: 'outlined', style: {
            border: 'none',
            paddingBottom: (workflowTaskSteps === null || workflowTaskSteps === void 0 ? void 0 : workflowTaskSteps.length) > 1 ? 10 : 0
        } }, React.createElement(PrimaryActionHeader, { single: true, title: workflow === null || workflow === void 0 ? void 0 : workflow.name, buttonLabel: 'Submit', handleClick: handleTaskSubmit, pabDisabled: ((_c = selectedNode === null || selectedNode === void 0 ? void 0 : selectedNode.properties) === null || _c === void 0 ? void 0 : _c.state) !== UnitStateType.Started, secondaryButtons: secondaryButtons }), loading && React.createElement(LinearProgress, null)), (workflowTaskSteps === null || workflowTaskSteps === void 0 ? void 0 : workflowTaskSteps.length) > 1 && (React.createElement(WorkflowTaskFlow, { steps: workflowTaskSteps, handleClick: handleTaskChange, task: selectedNode })), selectedPageId && workflowPageData ? (React.createElement(PageContainer, { user: user, 
        // key={playScene?.playSceneId || selectedNode?.id}
        key: selectedPageId, pageData: pageData, pageLoading: pageLoading, widgetParams: pageWidgetParams, disableMargins: true, fromMenu: true, height: pageHeight })) : (React.createElement("div", { className: classes.loadingContent }, React.createElement(CircularProgress, { size: 64 }))), React.createElement(SideSheet, { open: reassignSidesheetOpen, buttonLabel: t('Reassign'), onClose: closeReassignmentSheet, onSubmit: handleReassignment, title: t('Reassign Task'), width: '25%', progress: reassigningAssignee, variant: "indeterminate" }, React.createElement(Form, { onSubmit: reassignTask, ref: formRef }, React.createElement(Field, { component: FluentTextFieldAutoComplete, name: "assignee", id: "assignee", label: t('Assignee'), initialValue: currentAssignee || '', options: assigneeOptions || [], optionKey: 'name', variant: "outlined", margin: "dense" })))));
};
//# sourceMappingURL=WorkflowUiInterruptContent.js.map