import { utilities as csUtils } from '@cornerstonejs/core';
import { state as annotationState } from '../../../stateManagement/annotation';
import getInterpolationDataCollection from '../../contours/interpolation/getInterpolationDataCollection';
import interpolate from '../../contours/interpolation/interpolate';
import deleteRelatedAnnotations from './deleteRelatedAnnotations';
import ChangeTypes from '../../../enums/ChangeTypes';
import getViewportForAnnotation from '../../getViewportForAnnotation';
import { addContourSegmentationAnnotation } from '../../contourSegmentation/addContourSegmentationAnnotation';
const { uuidv4 } = csUtils;
const ChangeTypesForInterpolation = [
    ChangeTypes.HandlesUpdated,
    ChangeTypes.InterpolationUpdated,
];
export default class InterpolationManager {
    static { this.toolNames = []; }
    static addTool(toolName) {
        if (!this.toolNames.includes(toolName)) {
            this.toolNames.push(toolName);
        }
    }
    static acceptAutoGenerated(annotationGroupSelector, selector = {}) {
        const { toolNames, segmentationId, segmentIndex, sliceIndex } = selector;
        for (const toolName of toolNames || InterpolationManager.toolNames) {
            const annotations = annotationState.getAnnotations(toolName, annotationGroupSelector);
            if (!annotations?.length) {
                continue;
            }
            for (const annotation of annotations) {
                const { interpolationUID, data, autoGenerated, metadata } = annotation;
                if (interpolationUID) {
                    annotation.interpolationCompleted = true;
                }
                if (!autoGenerated) {
                    continue;
                }
                if (segmentIndex && segmentIndex !== data.segmentation.segmentIndex) {
                    continue;
                }
                if (sliceIndex !== undefined &&
                    metadata &&
                    sliceIndex !== metadata.sliceIndex) {
                    continue;
                }
                if (segmentationId &&
                    segmentationId !== data.segmentation.segmentationId) {
                    continue;
                }
                addContourSegmentationAnnotation(annotation);
                annotation.autoGenerated = false;
            }
        }
    }
    static { this.handleAnnotationCompleted = (evt) => {
        const annotation = evt.detail.annotation;
        if (!annotation?.metadata) {
            return;
        }
        const { toolName, originalToolName } = annotation.metadata;
        if (!this.toolNames.includes(toolName) &&
            !this.toolNames.includes(originalToolName)) {
            return;
        }
        const viewport = getViewportForAnnotation(annotation);
        if (!viewport) {
            console.warn('Unable to find viewport for', annotation);
            return;
        }
        const sliceData = getSliceData(viewport);
        const viewportData = {
            viewport,
            sliceData,
            annotation,
            interpolationUID: annotation.interpolationUID,
        };
        const hasInterpolationUID = !!annotation.interpolationUID;
        annotation.autoGenerated = false;
        if (hasInterpolationUID) {
            deleteRelatedAnnotations(viewportData);
            interpolate(viewportData);
            return;
        }
        const filterData = [
            {
                key: 'segmentIndex',
                value: annotation.data.segmentation.segmentIndex,
                parentKey: (annotation) => annotation.data.segmentation,
            },
            {
                key: 'viewPlaneNormal',
                value: annotation.metadata.viewPlaneNormal,
                parentKey: (annotation) => annotation.metadata,
            },
            {
                key: 'viewUp',
                value: annotation.metadata.viewUp,
                parentKey: (annotation) => annotation.metadata,
            },
        ];
        let interpolationAnnotations = getInterpolationDataCollection(viewportData, filterData);
        const { sliceIndex } = annotation.metadata;
        const skipUIDs = new Set();
        interpolationAnnotations.forEach((interpolationAnnotation) => {
            if (interpolationAnnotation.interpolationCompleted ||
                interpolationAnnotation.metadata.sliceIndex === sliceIndex) {
                const { interpolationUID } = interpolationAnnotation;
                skipUIDs.add(interpolationUID);
            }
        });
        interpolationAnnotations = interpolationAnnotations.filter((interpolationAnnotation) => !skipUIDs.has(interpolationAnnotation.interpolationUID));
        annotation.interpolationUID =
            interpolationAnnotations[0]?.interpolationUID || uuidv4();
        viewportData.interpolationUID = annotation.interpolationUID;
        interpolate(viewportData);
    }; }
    static { this.handleAnnotationUpdate = (evt) => {
        const annotation = evt.detail.annotation;
        const { changeType = ChangeTypes.HandlesUpdated } = evt.detail;
        if (!annotation?.metadata) {
            return;
        }
        const { toolName, originalToolName } = annotation.metadata;
        if ((!this.toolNames.includes(toolName) &&
            !this.toolNames.includes(originalToolName)) ||
            !ChangeTypesForInterpolation.includes(changeType)) {
            return;
        }
        const viewport = getViewportForAnnotation(annotation);
        if (!viewport) {
            console.warn('Unable to find matching viewport for annotation interpolation', annotation);
            return;
        }
        if (annotation.autoGenerated) {
            addContourSegmentationAnnotation(annotation);
            annotation.autoGenerated = false;
        }
        const sliceData = getSliceData(viewport);
        const viewportData = {
            viewport,
            sliceData,
            annotation,
            interpolationUID: annotation.interpolationUID,
            isInterpolationUpdate: changeType === ChangeTypes.InterpolationUpdated,
        };
        interpolate(viewportData);
    }; }
    static { this.handleAnnotationDelete = (evt) => {
        const annotation = evt.detail.annotation;
        if (!annotation?.metadata) {
            return;
        }
        const { toolName } = annotation.metadata;
        if (!this.toolNames.includes(toolName) || annotation.autoGenerated) {
            return;
        }
        const viewport = getViewportForAnnotation(annotation);
        if (!viewport) {
            console.warn("No viewport, can't delete interpolated results", annotation);
            return;
        }
        const sliceData = getSliceData(viewport);
        const viewportData = {
            viewport,
            sliceData,
            annotation,
            interpolationUID: annotation.interpolationUID,
        };
        annotation.autoGenerated = false;
        deleteRelatedAnnotations(viewportData);
    }; }
}
function getSliceData(viewport) {
    const sliceData = {
        numberOfSlices: viewport.getNumberOfSlices(),
        imageIndex: viewport.getCurrentImageIdIndex(),
    };
    return sliceData;
}
