import { useEffect, useMemo, useState, useRef } from 'react';
import { Flex, Progress, StyledPageLayout, useAfterInitialEffect } from '@pega/cosmos-react-core';
import { LifeCycle, moveStage, moveStep } from '@pega/cosmos-react-build';
import { loadingTimeoutMS } from '../../core/Progress/Progress.mocks';
import { addStepCallback, deleteStepCallback, addTaskCallback, deleteTaskCallback, addStageCallback, deleteStageCallback } from './utils';
import { adhocCaseFlowNodeLibrary, lifeCycleAdhocCaseFlowData, lifeCycleEmptyData, lifeCycleEmptyPlanViewData, lifeCyclePlanViewData, lifeCycleWorkFlowData, planViewNodeLibrary, workFlowNodeLibrary } from './LifeCycle.mocks';
import { StyledContainer } from './LifeCycle.styles';
export default {
    title: 'Build/LifeCycle',
    component: LifeCycle,
    argTypes: {
        readOnly: {
            control: { type: 'boolean' }
        },
        stepWrap: {
            control: { type: 'boolean' }
        },
        useNodeLibrary: {
            control: { type: 'boolean' }
        },
        showStageRegionLabels: {
            control: { type: 'boolean' }
        }
    },
    args: {
        readOnly: false,
        stepWrap: false,
        useNodeLibrary: true,
        showStageRegionLabels: false
    },
    parameters: {
        layout: 'fullscreen',
        docs: {
            description: {
                component: 'Lifecycle visually represents the case designer in the form of stages, processes, and steps along with parallel processes and alternate stages.'
            }
        }
    }
};
export const PlanView = (args) => {
    const workFlowState = {
        activeElementId: '',
        data: lifeCyclePlanViewData
    };
    const [planViewData, setPlanViewData] = useState(workFlowState);
    const addStep = (stepData, libItem) => {
        const newStep = {
            id: libItem.id,
            label: libItem.primary,
            visual: {
                name: libItem.type.icon.name,
                label: libItem.type.icon.label,
                category: libItem.type.icon.category,
                inverted: libItem.type.icon.inverted
            },
            error: '',
            status: { label: '' }
        };
        const updatedTask = {
            ...stepData.task,
            steps: [...stepData.task.steps, newStep]
        };
        const updatedData = { ...stepData, task: updatedTask };
        const changedData = addStepCallback(updatedData, planViewData);
        setPlanViewData(changedData.dataClone);
    };
    const deleteStep = (stepData) => {
        const changedData = deleteStepCallback(stepData, planViewData);
        setPlanViewData(changedData);
    };
    const addTask = (taskData) => {
        const changedData = addTaskCallback(taskData, planViewData);
        setPlanViewData(changedData.dataClone);
    };
    const deleteTask = (taskData) => {
        const changedData = deleteTaskCallback(taskData, planViewData);
        setPlanViewData(changedData);
    };
    const onAddStage = () => {
        const changedData = addStageCallback(planViewData, 'stages');
        setPlanViewData(changedData.dataClone);
    };
    const onAddAlternateStage = () => {
        const changedData = addStageCallback(planViewData, 'alternateStages');
        setPlanViewData(changedData.dataClone);
    };
    const onDeleteStage = param => {
        const changedData = deleteStageCallback(param, planViewData);
        if (changedData === 'firstStage') {
            alert("you can't delete the create stage");
        }
        else {
            setPlanViewData(changedData);
        }
    };
    useEffect(() => {
        if (planViewData.activeElementId) {
            const elementId = document.getElementById(`${planViewData.activeElementId}`);
            if (elementId) {
                elementId.focus();
            }
        }
    });
    const stages = planViewData.data.stages;
    const alternateStages = planViewData.data.alternateStages;
    const { categories } = planViewData.data;
    const channelActions = useMemo(() => args.readOnly
        ? []
        : [
            {
                text: 'Delete channel',
                id: 'delete5',
                icon: 'trash',
                onClick: deleteStep
            }
        ], [args.readOnly]);
    const dataSourceActions = useMemo(() => args.readOnly
        ? []
        : [
            {
                text: 'Delete data source',
                id: 'delete6',
                icon: 'trash',
                onClick: deleteStep
            }
        ], [args.readOnly]);
    const personaActions = useMemo(() => args.readOnly
        ? []
        : [
            {
                text: 'Delete persona',
                id: 'delete2',
                icon: 'trash',
                onClick: deleteTask
            }
        ], [args.readOnly]);
    const dataActions = useMemo(() => args.readOnly
        ? []
        : [
            {
                text: 'Delete data',
                id: 'delete4',
                icon: 'trash',
                onClick: deleteTask
            }
        ], [args.readOnly]);
    const stageActions = useMemo(() => args.readOnly
        ? []
        : [
            { text: 'Add Alternate Stage', id: 'add2', onClick: onAddAlternateStage },
            { text: 'Delete Stage', id: 'delete11', onClick: onDeleteStage }
        ], [args.readOnly]);
    const alternateStageActions = useMemo(() => args.readOnly
        ? []
        : [{ text: 'Delete Stage', id: 'delete11', icon: 'trash', onClick: onDeleteStage }], [args.readOnly]);
    return (<LifeCycle items={stages} alternateItems={alternateStages} categories={categories} task={[
            {
                actions: personaActions,
                addStepTitle: 'channels',
                addTask: {
                    title: 'Persona',
                    showOnce: false,
                    onAddTask: addTask
                },
                onAddStep: addStep,
                nodeLibrary: planViewNodeLibrary
            },
            {
                actions: dataActions,
                addStepTitle: 'Data and Systems',
                addTask: {
                    title: 'Data',
                    showOnce: false,
                    onAddTask: addTask
                },
                onAddStep: addStep,
                nodeLibrary: args.useNodeLibrary ? planViewNodeLibrary : undefined
            }
        ]} step={[
            {
                actions: channelActions,
                wrap: args.stepWrap
            },
            {
                actions: dataSourceActions,
                wrap: args.stepWrap
            }
        ]} stage={{
            label: args.showStageRegionLabels ? 'Primary stages' : '',
            actions: stageActions
        }} alternateStage={{
            label: args.showStageRegionLabels ? 'Alternate stages' : '',
            actions: alternateStageActions
        }} onAddStage={onAddStage} onAddAlternateStage={onAddAlternateStage} readOnly={args.readOnly}/>);
};
export const EmptyPlanView = (args) => {
    const emptyPlanView = {
        activeElementId: '',
        data: lifeCycleEmptyPlanViewData
    };
    const [planViewData, setPlanViewData] = useState(emptyPlanView);
    const addStep = (stepData, libItem) => {
        const newStep = {
            id: libItem.id,
            label: libItem.primary,
            visual: {
                name: libItem.type.icon.name,
                label: libItem.type.icon.label,
                category: libItem.type.icon.category,
                inverted: libItem.type.icon.inverted
            },
            error: '',
            status: { label: '' }
        };
        const updatedTask = {
            ...stepData.task,
            steps: [...stepData.task.steps, newStep]
        };
        const updatedData = { ...stepData, task: updatedTask };
        const changedData = addStepCallback(updatedData, planViewData);
        setPlanViewData(changedData.dataClone);
    };
    const deleteStep = (stepData) => {
        const changedData = deleteStepCallback(stepData, planViewData);
        setPlanViewData(changedData);
    };
    const addTask = (taskData) => {
        const changedData = addTaskCallback(taskData, planViewData);
        setPlanViewData(changedData.dataClone);
    };
    const deleteTask = (taskData) => {
        const changedData = deleteTaskCallback(taskData, planViewData);
        setPlanViewData(changedData);
    };
    const onAddStage = () => {
        const changedData = addStageCallback(planViewData, 'stages');
        setPlanViewData(changedData.dataClone);
    };
    const onAddAlternateStage = () => {
        const changedData = addStageCallback(planViewData, 'alternateStages');
        setPlanViewData(changedData.dataClone);
    };
    const onDeleteStage = param => {
        const changedData = deleteStageCallback(param, planViewData);
        if (changedData === 'firstStage') {
            alert("you can't delete the create stage");
        }
        else {
            setPlanViewData(changedData);
        }
    };
    useEffect(() => {
        if (planViewData.activeElementId) {
            const elementId = document.getElementById(`${planViewData.activeElementId}`);
            if (elementId) {
                elementId.focus();
            }
        }
    });
    const stages = planViewData.data.stages;
    const alternateStages = planViewData.data.alternateStages;
    const categories = planViewData.data.categories;
    const channelActions = useMemo(() => args.readOnly
        ? []
        : [
            {
                text: 'Delete channel',
                id: 'delete5',
                icon: 'trash',
                onClick: deleteStep
            }
        ], [args.readOnly]);
    const dataSourceActions = useMemo(() => args.readOnly
        ? []
        : [
            {
                text: 'Delete data source',
                id: 'delete6',
                icon: 'trash',
                onClick: deleteStep
            }
        ], [args.readOnly]);
    const personaActions = useMemo(() => args.readOnly
        ? []
        : [
            {
                text: 'Delete persona',
                id: 'delete2',
                icon: 'trash',
                onClick: deleteTask
            }
        ], [args.readOnly]);
    const dataActions = useMemo(() => args.readOnly
        ? []
        : [
            {
                text: 'Delete data',
                id: 'delete4',
                icon: 'trash',
                onClick: deleteTask
            }
        ], [args.readOnly]);
    const stageActions = useMemo(() => args.readOnly
        ? []
        : [
            { text: 'Add Alternate Stage', id: 'add2', onClick: onAddAlternateStage },
            { text: 'Delete Stage', id: 'delete11', onClick: onDeleteStage }
        ], [args.readOnly]);
    const alternateStageActions = useMemo(() => args.readOnly
        ? []
        : [{ text: 'Delete Stage', id: 'delete11', icon: 'trash', onClick: onDeleteStage }], [args.readOnly]);
    return (<LifeCycle items={stages} alternateItems={alternateStages} categories={categories} task={[
            {
                actions: personaActions,
                addStepTitle: 'channels',
                addTask: {
                    title: 'Persona',
                    showOnce: false,
                    onAddTask: addTask
                },
                onAddStep: addStep,
                nodeLibrary: planViewNodeLibrary
            },
            {
                actions: dataActions,
                addStepTitle: 'Data and Systems',
                addTask: {
                    title: 'Data',
                    showOnce: false,
                    onAddTask: addTask
                },
                onAddStep: addStep,
                nodeLibrary: args.useNodeLibrary ? workFlowNodeLibrary : undefined
            }
        ]} step={[
            {
                actions: channelActions,
                wrap: args.stepWrap
            },
            {
                actions: dataSourceActions,
                wrap: args.stepWrap
            }
        ]} stage={{
            label: args.showStageRegionLabels ? 'Primary stages' : '',
            actions: stageActions
        }} alternateStage={{
            label: args.showStageRegionLabels ? 'Alternate stages' : '',
            actions: alternateStageActions
        }} onAddStage={onAddStage} onAddAlternateStage={onAddAlternateStage} readOnly={args.readOnly}/>);
};
export const WorkFlowView = (args) => {
    const workFlowState = {
        activeElementId: '',
        data: lifeCycleWorkFlowData
    };
    const [workFlowData, setWorkFlowData] = useState(workFlowState);
    const [activeFieldItem, setActiveFieldItem] = useState();
    const lifeCycleRef = useRef(null);
    const { id: activeFieldItemId } = activeFieldItem || {};
    const [, setProgress] = useState(true);
    useAfterInitialEffect(() => {
        setProgress(true);
        const timerId = setTimeout(() => {
            setProgress(false);
        }, 600);
        return () => {
            clearTimeout(timerId);
        };
    }, [activeFieldItemId]);
    const addProcessStep = (stepData, libItem) => {
        const newStep = {
            id: libItem.id,
            label: libItem.primary,
            visual: {
                name: libItem.type.icon.name,
                label: libItem.type.icon.label,
                category: libItem.type.icon.category,
                inverted: libItem.type.icon.inverted
            },
            error: '',
            status: { label: '' }
        };
        const updatedTask = {
            ...stepData.task,
            steps: [...stepData.task.steps, newStep]
        };
        const updatedData = { ...stepData, task: updatedTask };
        const changedData = addStepCallback(updatedData, workFlowData);
        setActiveFieldItem({ ...changedData.newStepData, type: 'Step' });
        setWorkFlowData(changedData.dataClone);
    };
    const deleteProcessStep = (stepData) => {
        const changedData = deleteStepCallback(stepData, workFlowData);
        if (stepData?.step?.id === activeFieldItem?.id) {
            setActiveFieldItem(undefined);
        }
        setWorkFlowData(changedData);
    };
    const addProcess = (taskData) => {
        const changedData = addTaskCallback(taskData, workFlowData);
        setActiveFieldItem({ ...changedData.newTaskData, type: 'Task' });
        setWorkFlowData(changedData.dataClone);
    };
    const addParallelProcess = (taskData) => {
        const changedData = addTaskCallback(taskData, workFlowData, true);
        setActiveFieldItem({ ...changedData.newTaskData, type: 'Task' });
        setWorkFlowData(changedData.dataClone);
    };
    const deleteProcess = (taskData) => {
        const changedData = deleteTaskCallback(taskData, workFlowData);
        if (taskData?.task?.id === activeFieldItem?.id) {
            setActiveFieldItem(undefined);
        }
        setWorkFlowData(changedData);
    };
    const onAddStage = () => {
        const changedData = addStageCallback(workFlowData, 'stages');
        setActiveFieldItem({ ...changedData.newStageData, type: 'Stage' });
        setWorkFlowData(changedData.dataClone);
    };
    const onAddAlternateStage = () => {
        const changedData = addStageCallback(workFlowData, 'alternateStages');
        setActiveFieldItem({ ...changedData.newStageData, type: 'Alternate Stage' });
        setWorkFlowData(changedData.dataClone);
    };
    const onDeleteStage = (stageData) => {
        const changedData = deleteStageCallback(stageData, workFlowData);
        if (changedData === 'firstStage') {
            alert("you can't delete the create stage");
        }
        else {
            if (stageData?.stage?.id === activeFieldItem?.id) {
                setActiveFieldItem(undefined);
            }
            setWorkFlowData(changedData);
        }
    };
    const onOpenProcess = () => { };
    const onSelectedItem = (selectedData) => {
        switch (selectedData.type) {
            case 'Step':
                setActiveFieldItem({ ...selectedData, id: selectedData?.step?.id });
                break;
            case 'Task':
                setActiveFieldItem({ ...selectedData, id: selectedData?.task?.id });
                break;
            case 'Stage':
                setActiveFieldItem({ ...selectedData, id: selectedData?.stage?.id });
                break;
            default:
                setActiveFieldItem(undefined);
        }
    };
    useEffect(() => {
        if (workFlowData.activeElementId) {
            const elementId = document.getElementById(`${workFlowData.activeElementId}`);
            if (elementId) {
                elementId.focus();
            }
        }
    });
    const stages = workFlowData.data.stages;
    const alternateStages = workFlowData.data.alternateStages;
    const { categories } = lifeCycleWorkFlowData;
    const stepActions = useMemo(() => {
        return args.readOnly
            ? []
            : [
                {
                    text: 'Delete',
                    id: 'delete10',
                    icon: 'trash',
                    onClick: deleteProcessStep
                }
            ];
    }, [args.readOnly, activeFieldItem]);
    const taskActions = useMemo(() => {
        return args.readOnly
            ? [
                {
                    text: 'Open Process',
                    id: 'layers2',
                    icon: 'layers',
                    onClick: onOpenProcess
                }
            ]
            : [
                {
                    text: 'Delete Process',
                    id: 'delete9',
                    icon: 'trash',
                    onClick: deleteProcess
                },
                {
                    text: 'Open Process',
                    id: 'layers2',
                    icon: 'layers',
                    onClick: onOpenProcess
                }
            ];
    }, [args.readOnly, activeFieldItem]);
    const StageActions = useMemo(() => {
        return args.readOnly
            ? {
                start: [],
                default: [],
                alternate: []
            }
            : {
                start: [
                    { text: 'Add Process', id: 'add1', onClick: addProcess },
                    { text: 'Add Parallel Process', id: 'add3', onClick: addParallelProcess },
                    { text: 'Add Alternate Stage', id: 'add2', onClick: onAddAlternateStage }
                ],
                default: [
                    { text: 'Add Process', id: 'add1', onClick: addProcess },
                    { text: 'Add Parallel Process', id: 'add3', onClick: addParallelProcess },
                    { text: 'Add Alternate Stage', id: 'add2', onClick: onAddAlternateStage },
                    { text: 'Delete Stage', id: 'delete11', onClick: onDeleteStage }
                ],
                alternate: [
                    { text: 'Add Process', id: 'add1', onClick: addProcess },
                    { text: 'Delete Stage', id: 'delete11', onClick: onDeleteStage }
                ]
            };
    }, [args.readOnly, activeFieldItem]);
    const alternateStageActions = useMemo(() => args.readOnly
        ? []
        : [
            { text: 'Add Process', id: 'add1', onClick: addProcess },
            { text: 'Add Parallel Process', id: 'add3', onClick: addParallelProcess },
            { text: 'Delete Stage', id: 'delete11', onClick: onDeleteStage }
        ], [args.readOnly]);
    return (<Flex container as={StyledContainer}>
      <Flex container as={StyledPageLayout}>
        <LifeCycle items={stages} alternateItems={alternateStages} categories={categories} task={[
            {
                actions: taskActions,
                addStepTitle: 'step',
                addTask: {
                    title: 'Process',
                    showOnce: true,
                    onAddTask: addProcess
                },
                onClick: onSelectedItem,
                onAddStep: addProcessStep,
                onAddCustomStep: () => { },
                nodeLibrary: args.useNodeLibrary ? workFlowNodeLibrary : undefined
            }
        ]} step={[
            {
                actions: stepActions,
                onClick: onSelectedItem,
                wrap: args.stepWrap
            }
        ]} stage={{
            label: args.showStageRegionLabels ? 'Primary stages' : '',
            actions: StageActions,
            onClick: () => { }
        }} alternateStage={{
            label: args.showStageRegionLabels ? 'Alternate stages' : '',
            actions: alternateStageActions,
            onClick: () => { }
        }} onAddStage={onAddStage} onAddAlternateStage={onAddAlternateStage} selectedItemId={activeFieldItem?.id} readOnly={args.readOnly} ref={lifeCycleRef}/>
      </Flex>
    </Flex>);
};
export const EmptyWorkFlowView = (args) => {
    const emptyState = {
        activeElementId: '',
        data: lifeCycleEmptyData
    };
    const [emptyStateData, setEmptyStateData] = useState(emptyState);
    const addProcessStep = (stepData, libItem) => {
        const newStep = {
            id: libItem.id,
            label: libItem.primary,
            visual: {
                name: libItem.type.icon.name,
                label: libItem.type.icon.label,
                category: libItem.type.icon.category,
                inverted: libItem.type.icon.inverted
            },
            error: '',
            status: { label: '' }
        };
        const updatedTask = {
            ...stepData.task,
            steps: [...stepData.task.steps, newStep]
        };
        const updatedData = { ...stepData, task: updatedTask };
        const changedData = addStepCallback(updatedData, emptyStateData);
        setEmptyStateData(changedData.dataClone);
    };
    const deleteProcessStep = (stepData) => {
        const changedData = deleteStepCallback(stepData, emptyStateData);
        setEmptyStateData(changedData);
    };
    const addProcess = (taskData) => {
        const changedData = addTaskCallback(taskData, emptyStateData);
        setEmptyStateData(changedData.dataClone);
    };
    const addParallelProcess = (taskData) => {
        const changedData = addTaskCallback(taskData, emptyStateData, true);
        setEmptyStateData(changedData.dataClone);
    };
    const deleteProcess = (taskData) => {
        const changedData = deleteTaskCallback(taskData, emptyStateData);
        setEmptyStateData(changedData);
    };
    const onAddStage = () => {
        const changedData = addStageCallback(emptyStateData, 'stages');
        setEmptyStateData(changedData.dataClone);
    };
    const onAddAlternateStage = () => {
        const changedData = addStageCallback(emptyStateData, 'alternateStages');
        setEmptyStateData(changedData.dataClone);
    };
    const onDeleteStage = param => {
        const changedData = deleteStageCallback(param, emptyStateData);
        if (changedData === 'firstStage') {
            alert("you can't delete the create stage");
        }
        else {
            setEmptyStateData(changedData);
        }
    };
    const onOpenProcess = () => { };
    useEffect(() => {
        if (emptyStateData.activeElementId) {
            const elementId = document.getElementById(`${emptyStateData.activeElementId}`);
            if (elementId) {
                elementId.focus();
            }
        }
    });
    const stages = emptyStateData.data.stages;
    const { alternateStages } = emptyStateData.data;
    const { categories } = lifeCycleEmptyData;
    const stepActions = useMemo(() => {
        return args.readOnly
            ? []
            : [
                {
                    text: 'Delete step',
                    id: 'delete10',
                    icon: 'trash',
                    onClick: deleteProcessStep
                }
            ];
    }, [args.readOnly]);
    const taskActions = useMemo(() => {
        return args.readOnly
            ? [
                {
                    text: 'Open Process',
                    id: 'layers2',
                    icon: 'layers',
                    onClick: onOpenProcess
                }
            ]
            : [
                {
                    text: 'Delete Process',
                    id: 'delete9',
                    icon: 'trash',
                    onClick: deleteProcess
                },
                {
                    text: 'Open Process',
                    id: 'layers2',
                    icon: 'layers',
                    onClick: onOpenProcess
                }
            ];
    }, [args.readOnly]);
    const StageActions = useMemo(() => {
        return args.readOnly
            ? {
                start: [],
                default: [],
                alternate: []
            }
            : {
                start: [
                    { text: 'Add Process', id: 'add1', onClick: addProcess },
                    { text: 'Add Parallel Process', id: 'add3', onClick: addParallelProcess },
                    { text: 'Add Alternate Stage', id: 'add2', onClick: onAddAlternateStage }
                ],
                default: [
                    { text: 'Add Process', id: 'add1', onClick: addProcess },
                    { text: 'Add Parallel Process', id: 'add3', onClick: addParallelProcess },
                    { text: 'Add Alternate Stage', id: 'add2', onClick: onAddAlternateStage },
                    { text: 'Delete Stage', id: 'delete11', onClick: onDeleteStage }
                ],
                alternate: [
                    { text: 'Add Process', id: 'add1', onClick: addProcess },
                    { text: 'Delete Stage', id: 'delete11', onClick: onDeleteStage }
                ]
            };
    }, [args.readOnly]);
    const alternateStageActions = useMemo(() => args.readOnly
        ? []
        : [
            { text: 'Add Process', id: 'add1', onClick: addProcess },
            { text: 'Add Parallel Process', id: 'add3', onClick: addParallelProcess },
            { text: 'Delete Stage', id: 'delete11', onClick: onDeleteStage }
        ], [args.readOnly]);
    return (<LifeCycle items={stages} alternateItems={alternateStages} categories={categories} task={[
            {
                actions: taskActions,
                addStepTitle: 'step',
                addTask: {
                    title: 'Process',
                    showOnce: true,
                    onAddTask: addProcess
                },
                onAddStep: addProcessStep,
                nodeLibrary: args.useNodeLibrary ? workFlowNodeLibrary : undefined
            }
        ]} step={[
            {
                actions: stepActions,
                wrap: args.stepWrap
            }
        ]} stage={{
            label: args.showStageRegionLabels ? 'Primary stages' : '',
            actions: StageActions
        }} alternateStage={{
            label: args.showStageRegionLabels ? 'Alternate stages' : '',
            actions: alternateStageActions
        }} onAddStage={onAddStage} onAddAlternateStage={onAddAlternateStage} readOnly={args.readOnly}/>);
};
export const AdhocCaseFlowView = (args) => {
    const AdhocCaseFlowState = {
        activeElementId: '',
        data: lifeCycleAdhocCaseFlowData
    };
    const [adhocCaseFlowData, setAdhocCaseFlowData] = useState(AdhocCaseFlowState);
    const [activeFieldItem, setActiveFieldItem] = useState();
    const lifeCycleRef = useRef(null);
    const addProcessStep = (stepData, libItem) => {
        const newStep = {
            id: libItem.id,
            label: libItem.primary,
            visual: {
                name: libItem.type.icon.name,
                label: libItem.type.icon.label,
                category: libItem.type.icon.category,
                inverted: libItem.type.icon.inverted
            },
            error: '',
            status: { label: '' }
        };
        const updatedTask = {
            ...stepData.task,
            steps: [...stepData.task.steps, newStep]
        };
        const updatedData = { ...stepData, task: updatedTask };
        const changedData = addStepCallback(updatedData, adhocCaseFlowData);
        setActiveFieldItem({ ...changedData.newStepData, type: 'Step' });
        setAdhocCaseFlowData(changedData.dataClone);
    };
    const deleteProcessStep = (stepData) => {
        const changedData = deleteStepCallback(stepData, adhocCaseFlowData);
        if (stepData?.step?.id === activeFieldItem?.id) {
            setActiveFieldItem(undefined);
        }
        setAdhocCaseFlowData(changedData);
    };
    useEffect(() => {
        if (adhocCaseFlowData.activeElementId) {
            const elementId = document.getElementById(`${adhocCaseFlowData.activeElementId}`);
            if (elementId) {
                elementId.focus();
            }
        }
    });
    const stages = adhocCaseFlowData.data.stages;
    const { categories } = lifeCycleAdhocCaseFlowData;
    const stepActions = useMemo(() => {
        return args.readOnly
            ? []
            : [
                {
                    text: 'Delete',
                    id: 'delete10',
                    icon: 'trash',
                    onClick: deleteProcessStep
                }
            ];
    }, [args.readOnly, activeFieldItem]);
    return (<Flex container as={StyledContainer}>
      <Flex container as={StyledPageLayout}>
        <LifeCycle items={stages} categories={categories} task={[
            {
                addStepTitle: 'step',
                addTask: {
                    title: 'Process',
                    showOnce: true
                },
                onAddStep: addProcessStep,
                nodeLibrary: args.useNodeLibrary ? adhocCaseFlowNodeLibrary : undefined
            }
        ]} step={[
            {
                actions: stepActions,
                onClick: () => { },
                wrap: args.stepWrap
            }
        ]} selectedItemId={activeFieldItem?.id} readOnly={args.readOnly} ref={lifeCycleRef}/>
      </Flex>
    </Flex>);
};
AdhocCaseFlowView.argTypes = {
    showStageRegionLabels: {
        table: {
            disable: true
        }
    }
};
export const DragDropLifeCycle = (args) => {
    const workFlowState = {
        activeElementId: '',
        data: lifeCycleWorkFlowData
    };
    const [dragDropLoading, setDragDropLoading] = useState(false);
    const [workFlowData, setWorkFlowData] = useState(workFlowState);
    const [activeFieldItem, setActiveFieldItem] = useState();
    const lifeCycleRef = useRef(null);
    const { id: activeFieldItemId } = activeFieldItem || {};
    const [, setProgress] = useState(true);
    useAfterInitialEffect(() => {
        setProgress(true);
        const timerId = setTimeout(() => {
            setProgress(false);
        }, 600);
        return () => {
            clearTimeout(timerId);
        };
    }, [activeFieldItemId]);
    const addProcessStep = (stepData, libItem) => {
        const newStep = {
            id: libItem.id,
            label: libItem.primary,
            visual: {
                name: libItem.type.icon.name,
                label: libItem.type.icon.label,
                category: libItem.type.icon.category,
                inverted: libItem.type.icon.inverted
            },
            error: '',
            status: { label: '' }
        };
        const updatedTask = {
            ...stepData.task,
            steps: [...stepData.task.steps, newStep]
        };
        const updatedData = { ...stepData, task: updatedTask };
        const changedData = addStepCallback(updatedData, workFlowData);
        setActiveFieldItem({ ...changedData.newStepData, type: 'Step' });
        setWorkFlowData(changedData.dataClone);
    };
    const deleteProcessStep = (stepData) => {
        const changedData = deleteStepCallback(stepData, workFlowData);
        if (stepData?.step?.id === activeFieldItem?.id) {
            setActiveFieldItem(undefined);
        }
        setWorkFlowData(changedData);
    };
    const addProcess = (taskData) => {
        const changedData = addTaskCallback(taskData, workFlowData);
        setActiveFieldItem({ ...changedData.newTaskData, type: 'Task' });
        setWorkFlowData(changedData.dataClone);
    };
    const addParallelProcess = (taskData) => {
        const changedData = addTaskCallback(taskData, workFlowData, true);
        setActiveFieldItem({ ...changedData.newTaskData, type: 'Task' });
        setWorkFlowData(changedData.dataClone);
    };
    const deleteProcess = (taskData) => {
        const changedData = deleteTaskCallback(taskData, workFlowData);
        if (taskData?.task?.id === activeFieldItem?.id) {
            setActiveFieldItem(undefined);
        }
        setWorkFlowData(changedData);
    };
    const onAddStage = () => {
        const changedData = addStageCallback(workFlowData, 'stages');
        setActiveFieldItem({ ...changedData.newStageData, type: 'Stage' });
        setWorkFlowData(changedData.dataClone);
    };
    const onAddAlternateStage = () => {
        const changedData = addStageCallback(workFlowData, 'alternateStages');
        setActiveFieldItem({ ...changedData.newStageData, type: 'Alternate Stage' });
        setWorkFlowData(changedData.dataClone);
    };
    const onDeleteStage = (stageData) => {
        const changedData = deleteStageCallback(stageData, workFlowData);
        if (changedData === 'firstStage') {
            alert("you can't delete the create stage");
        }
        else {
            if (stageData?.stage?.id === activeFieldItem?.id) {
                setActiveFieldItem(undefined);
            }
            setWorkFlowData(changedData);
        }
    };
    const onDragDrop = (event) => {
        setDragDropLoading(true);
        let moveData;
        if (event.type === 'stage') {
            moveData = moveStage;
        }
        else if (event.type === 'step') {
            moveData = moveStep;
        }
        const changedData = moveData?.(event, workFlowData.data.stages, workFlowData.data.alternateStages);
        if (changedData) {
            const { stages, alternateStages } = changedData;
            if (event.type === 'stage') {
                stages.forEach((stage, index) => {
                    stage.type = index === 0 ? 'start' : 'default';
                    if (stage.transitionType === 'resolution' && index !== stages.length - 1) {
                        stage.transitionType = undefined;
                    }
                    else if (index === stages.length - 1) {
                        stage.transitionType = 'resolution';
                    }
                });
                alternateStages.forEach((altStage, index) => {
                    altStage.type = 'alternate';
                    if (altStage.transitionType === 'resolution' && index !== alternateStages.length - 1) {
                        altStage.transitionType = undefined;
                    }
                    else if (index === alternateStages.length - 1) {
                        altStage.transitionType = 'resolution';
                    }
                });
            }
            setTimeout(() => {
                setWorkFlowData(cur => ({ ...cur, data: { ...cur.data, stages, alternateStages } }));
                setDragDropLoading(false);
            }, loadingTimeoutMS);
        }
    };
    const onOpenProcess = () => { };
    const onSelectedItem = (selectedData) => {
        switch (selectedData.type) {
            case 'Step':
                setActiveFieldItem({ ...selectedData, id: selectedData?.step?.id });
                break;
            case 'Task':
                setActiveFieldItem({ ...selectedData, id: selectedData?.task?.id });
                break;
            case 'Stage':
                setActiveFieldItem({ ...selectedData, id: selectedData?.stage?.id });
                break;
            default:
                setActiveFieldItem(undefined);
        }
    };
    useEffect(() => {
        if (workFlowData.activeElementId) {
            const elementId = document.getElementById(`${workFlowData.activeElementId}`);
            if (elementId) {
                elementId.focus();
            }
        }
    });
    const stages = workFlowData.data.stages;
    const alternateStages = workFlowData.data.alternateStages;
    const { categories } = lifeCycleWorkFlowData;
    const stepActions = useMemo(() => {
        return args.readOnly
            ? []
            : [
                {
                    text: 'Delete',
                    id: 'delete10',
                    icon: 'trash',
                    onClick: deleteProcessStep
                }
            ];
    }, [args.readOnly, activeFieldItem]);
    const taskActions = useMemo(() => {
        return args.readOnly
            ? [
                {
                    text: 'Open Process',
                    id: 'layers2',
                    icon: 'layers',
                    onClick: onOpenProcess
                }
            ]
            : [
                {
                    text: 'Delete Process',
                    id: 'delete9',
                    icon: 'trash',
                    onClick: deleteProcess
                },
                {
                    text: 'Open Process',
                    id: 'layers2',
                    icon: 'layers',
                    onClick: onOpenProcess
                }
            ];
    }, [args.readOnly, activeFieldItem]);
    const StageActions = useMemo(() => {
        return args.readOnly
            ? {
                start: [],
                default: [],
                alternate: []
            }
            : {
                start: [
                    { text: 'Add Process', id: 'add1', onClick: addProcess },
                    { text: 'Add Parallel Process', id: 'add3', onClick: addParallelProcess },
                    { text: 'Add Alternate Stage', id: 'add2', onClick: onAddAlternateStage }
                ],
                default: [
                    { text: 'Add Process', id: 'add1', onClick: addProcess },
                    { text: 'Add Parallel Process', id: 'add3', onClick: addParallelProcess },
                    { text: 'Add Alternate Stage', id: 'add2', onClick: onAddAlternateStage },
                    { text: 'Delete Stage', id: 'delete11', onClick: onDeleteStage }
                ],
                alternate: [
                    { text: 'Add Process', id: 'add1', onClick: addProcess },
                    { text: 'Delete Stage', id: 'delete11', onClick: onDeleteStage }
                ]
            };
    }, [args.readOnly, activeFieldItem]);
    const alternateStageActions = useMemo(() => args.readOnly
        ? []
        : [
            { text: 'Add Process', id: 'add1', onClick: addProcess },
            { text: 'Add Parallel Process', id: 'add3', onClick: addParallelProcess },
            { text: 'Delete Stage', id: 'delete11', onClick: onDeleteStage }
        ], [args.readOnly]);
    return (<Flex container as={StyledContainer}>
      <Flex container as={StyledPageLayout} style={{ width: '100%' }}>
        <LifeCycle items={stages} alternateItems={alternateStages} categories={categories} task={[
            {
                actions: taskActions,
                addStepTitle: 'step',
                addTask: {
                    title: 'Process',
                    showOnce: true,
                    onAddTask: addProcess
                },
                onClick: onSelectedItem,
                onAddStep: addProcessStep,
                onAddCustomStep: () => { },
                nodeLibrary: args.useNodeLibrary ? workFlowNodeLibrary : undefined
            }
        ]} step={[
            {
                actions: stepActions,
                onClick: onSelectedItem,
                wrap: args.stepWrap
            }
        ]} stage={{
            label: args.showStageRegionLabels ? 'Primary stages' : '',
            actions: StageActions,
            onClick: () => { }
        }} alternateStage={{
            label: args.showStageRegionLabels ? 'Alternate stages' : '',
            actions: alternateStageActions,
            onClick: () => { }
        }} onAddStage={onAddStage} onAddAlternateStage={onAddAlternateStage} onDragDrop={onDragDrop} dragDropConfig={{
            loading: dragDropLoading,
            stage: {
                enabled: args.draggableStages,
                accept: args.canDragAcrossStageTypes ? ['stage', 'alternate-stage'] : ['stage']
            },
            step: {
                enabled: args.draggableSteps,
                accept: args.canDragAcrossStageTypes ? ['step', 'alternate-step'] : ['step']
            },
            'alternate-stage': {
                enabled: args.draggableAlternateStages,
                accept: args.canDragAcrossStageTypes
                    ? ['stage', 'alternate-stage']
                    : ['alternate-stage']
            },
            'alternate-step': {
                enabled: args.draggableAlternateSteps,
                accept: args.canDragAcrossStageTypes ? ['step', 'alternate-step'] : ['alternate-step']
            }
        }} selectedItemId={activeFieldItem?.id} readOnly={args.readOnly} ref={lifeCycleRef}/>

        <Progress visible={!!dragDropLoading} focusOnVisible placement='local'/>
      </Flex>
    </Flex>);
};
DragDropLifeCycle.argTypes = {
    draggableStages: { control: { type: 'boolean' } },
    draggableSteps: { control: { type: 'boolean' } },
    draggableAlternateStages: { control: { type: 'boolean' } },
    draggableAlternateSteps: { control: { type: 'boolean' } },
    canDragAcrossStageTypes: { control: { type: 'boolean' } }
};
DragDropLifeCycle.args = {
    draggableStages: true,
    draggableSteps: true,
    draggableAlternateStages: true,
    draggableAlternateSteps: true,
    canDragAcrossStageTypes: true
};
//# sourceMappingURL=LifeCycle.stories.jsx.map