import { triggerSegmentationDataModified } from '../../../../stateManagement/segmentation/events/triggerSegmentationDataModified';
import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
import { getSegmentIndexColor, setSegmentIndexColor, } from '../../../../stateManagement/segmentation/config/segmentationColor';
import { getViewportIdsWithSegmentation } from '../../../../stateManagement/segmentation/getViewportIdsWithSegmentation';
function lightenColor(r, g, b, a, factor = 0.4) {
    return [
        Math.round(r + (255 - r) * factor),
        Math.round(g + (255 - g) * factor),
        Math.round(b + (255 - b) * factor),
        a,
    ];
}
export default {
    [StrategyCallbacks.Preview]: function (operationData) {
        const { previewColors, configuration, enabledElement } = operationData;
        if (!previewColors || !configuration) {
            return;
        }
        if (operationData.preview) {
            delete operationData.preview;
        }
        delete configuration.centerSegmentIndex;
        this.onInteractionStart?.(enabledElement, operationData);
        const preview = this.fill(enabledElement, operationData);
        if (preview) {
            preview.isPreviewFromHover = true;
            operationData.preview = preview;
            this.onInteractionEnd?.(enabledElement, operationData);
        }
        return preview;
    },
    [StrategyCallbacks.Initialize]: (operationData) => {
        const { segmentIndex, previewSegmentIndex, previewColors, preview, segmentationId, segmentationVoxelManager, } = operationData;
        if (previewColors === undefined || !previewSegmentIndex) {
            operationData.memo = operationData.createMemo(segmentationId, segmentationVoxelManager);
            return;
        }
        if (preview) {
            preview.previewVoxelManager.sourceVoxelManager =
                operationData.segmentationVoxelManager;
            operationData.previewVoxelManager = preview.previewVoxelManager;
        }
        if (segmentIndex === null) {
            return;
        }
        const configColor = previewColors?.[segmentIndex];
        const segmentColor = getSegmentIndexColor(operationData.viewport.id, operationData.segmentationId, segmentIndex);
        if (!configColor && !segmentColor) {
            return;
        }
        const previewColor = configColor || lightenColor(...segmentColor);
        const viewportIds = getViewportIdsWithSegmentation(operationData.segmentationId);
        viewportIds?.forEach((viewportId) => {
            setSegmentIndexColor(viewportId, operationData.segmentationId, previewSegmentIndex, previewColor);
        });
    },
    [StrategyCallbacks.AcceptPreview]: (operationData) => {
        const { segmentationVoxelManager, previewVoxelManager: previewVoxelManager, previewSegmentIndex, segmentationId, preview, } = operationData || {};
        if (previewSegmentIndex === undefined) {
            return;
        }
        const segmentIndex = preview?.segmentIndex ?? operationData.segmentIndex;
        if (!previewVoxelManager || previewVoxelManager.modifiedSlices.size === 0) {
            return;
        }
        const memo = operationData.createMemo(segmentationId, segmentationVoxelManager);
        operationData.memo = memo;
        const { voxelManager } = memo;
        const callback = ({ index, value }) => {
            const oldValue = segmentationVoxelManager.getAtIndex(index);
            if (oldValue === previewSegmentIndex) {
                segmentationVoxelManager.setAtIndex(index, value);
                voxelManager.setAtIndex(index, segmentIndex);
            }
        };
        previewVoxelManager.forEach(callback, {});
        triggerSegmentationDataModified(operationData.segmentationId, previewVoxelManager.getArrayOfModifiedSlices(), preview.segmentIndex);
        previewVoxelManager.clear();
    },
    [StrategyCallbacks.RejectPreview]: (operationData) => {
        const { previewVoxelManager: previewVoxelManager, segmentationVoxelManager, } = operationData;
        if (previewVoxelManager.modifiedSlices.size === 0) {
            return;
        }
        const callback = ({ index, value }) => {
            segmentationVoxelManager.setAtIndex(index, value);
        };
        previewVoxelManager.forEach(callback);
        triggerSegmentationDataModified(operationData.segmentationId, previewVoxelManager.getArrayOfModifiedSlices(), 0);
        previewVoxelManager.clear();
    },
};
