import { ANIMATION_CONSTANTS, TRANSITION_CONFIG, animateDrillIn, animateDrillOut, animateViewport, calculateNodeFocusViewport, getCanvasSize } from "../utils/transitions.js";
class AnimatedViewportManager {
    reactFlowInstance = null;
    currentViewport = {
        x: 0,
        y: 0,
        zoom: 1
    };
    transitionState = {
        isTransitioning: false,
        type: 'none',
        startTime: 0,
        progress: 0
    };
    transitionTimeoutId;
    onTransitionStart;
    onTransitionUpdate;
    onTransitionComplete;
    setReactFlowInstance(instance) {
        this.reactFlowInstance = instance;
    }
    getReactFlowInstance() {
        return this.reactFlowInstance;
    }
    setCurrentViewport(viewport) {
        this.currentViewport = viewport;
    }
    getCurrentViewport() {
        if (this.reactFlowInstance) return this.reactFlowInstance.getViewport();
        return this.currentViewport;
    }
    getTransitionState() {
        return {
            ...this.transitionState
        };
    }
    isTransitioning() {
        return this.transitionState.isTransitioning;
    }
    setTransitionCallbacks(callbacks) {
        this.onTransitionStart = callbacks.onStart;
        this.onTransitionUpdate = callbacks.onUpdate;
        this.onTransitionComplete = callbacks.onComplete;
    }
    updateTransitionState(updates) {
        this.transitionState = {
            ...this.transitionState,
            ...updates
        };
        if (this.onTransitionUpdate) this.onTransitionUpdate(this.transitionState);
    }
    startTransition(type, fromViewport, toViewport) {
        this.updateTransitionState({
            isTransitioning: true,
            type,
            startTime: performance.now(),
            progress: 0,
            fromViewport,
            toViewport
        });
        if (this.onTransitionStart) this.onTransitionStart(type);
        this.clearTransitionTimeout();
        this.transitionTimeoutId = window.setTimeout(()=>{
            if (this.isTransitioning()) {
                console.warn(`AnimatedViewportManager: Transition timeout after ${ANIMATION_CONSTANTS.TRANSITION_TIMEOUT}ms, forcing completion`);
                this.completeTransition();
            }
        }, ANIMATION_CONSTANTS.TRANSITION_TIMEOUT);
    }
    completeTransition() {
        const type = this.transitionState.type;
        this.clearTransitionTimeout();
        this.updateTransitionState({
            isTransitioning: false,
            type: 'none',
            progress: 1
        });
        if (this.onTransitionComplete) this.onTransitionComplete(type);
    }
    clearTransitionTimeout() {
        if (void 0 !== this.transitionTimeoutId) {
            window.clearTimeout(this.transitionTimeoutId);
            this.transitionTimeoutId = void 0;
        }
    }
    async animateToViewport(targetViewport, duration, type = 'viewport') {
        if (!this.reactFlowInstance) return void console.warn('AnimatedViewportManager: No ReactFlow instance available for viewport animation');
        if (this.isTransitioning()) return void console.warn('AnimatedViewportManager: Transition already in progress, skipping viewport animation');
        const fromViewport = this.getCurrentViewport();
        this.startTransition(type, fromViewport, targetViewport);
        try {
            await animateViewport(fromViewport, targetViewport, duration, (viewport)=>{
                this.reactFlowInstance?.setViewport(viewport, {
                    duration: 0
                });
                const elapsed = performance.now() - this.transitionState.startTime;
                const totalDuration = 1000 * (duration || TRANSITION_CONFIG.viewportDuration);
                const progress = Math.min(1, elapsed / totalDuration);
                this.updateTransitionState({
                    progress
                });
            }, ()=>{
                this.currentViewport = targetViewport;
                this.completeTransition();
            });
        } catch (error) {
            console.error('AnimatedViewportManager: Animation failed', error);
            this.completeTransition();
        }
    }
    async drillIntoNode(node) {
        if (!this.reactFlowInstance) return void console.warn('AnimatedViewportManager: No ReactFlow instance available for drill-in');
        if (this.isTransitioning()) return void console.warn('AnimatedViewportManager: Transition already in progress, skipping drill-in');
        const canvasElement = document.querySelector('.react-flow');
        const canvasSize = getCanvasSize(canvasElement);
        const nodeBounds = {
            x: node.position.x,
            y: node.position.y,
            width: node.width || 200,
            height: node.height || 100
        };
        const nodeFocusViewport = calculateNodeFocusViewport(nodeBounds, canvasSize, ANIMATION_CONSTANTS.NODE_FOCUS_PADDING);
        const fromViewport = this.getCurrentViewport();
        this.startTransition('drill-in', fromViewport, nodeFocusViewport);
        try {
            await animateDrillIn(fromViewport, nodeFocusViewport, (viewport)=>{
                this.reactFlowInstance?.setViewport(viewport, {
                    duration: 0
                });
                const elapsed = performance.now() - this.transitionState.startTime;
                const totalDuration = 1000 * TRANSITION_CONFIG.drillDuration;
                const progress = Math.min(1, elapsed / totalDuration);
                this.updateTransitionState({
                    progress
                });
            });
            this.currentViewport = nodeFocusViewport;
            this.completeTransition();
        } catch (error) {
            console.error(`AnimatedViewportManager: Drill-in animation failed for node ${node.id}:`, error);
            this.completeTransition();
        }
    }
    async drillOutToParent(parentViewport) {
        if (!this.reactFlowInstance) return void console.warn('AnimatedViewportManager: No ReactFlow instance available for drill-out');
        if (this.isTransitioning()) return void console.warn('AnimatedViewportManager: Transition already in progress, skipping drill-out');
        const fromViewport = this.getCurrentViewport();
        this.startTransition('drill-out', fromViewport, parentViewport);
        try {
            await animateDrillOut(fromViewport, parentViewport, (viewport)=>{
                this.reactFlowInstance?.setViewport(viewport, {
                    duration: 0
                });
                const elapsed = performance.now() - this.transitionState.startTime;
                const totalDuration = 1000 * TRANSITION_CONFIG.drillDuration;
                const progress = Math.min(1, elapsed / totalDuration);
                this.updateTransitionState({
                    progress
                });
            });
            this.currentViewport = parentViewport;
            this.completeTransition();
        } catch (error) {
            console.error('AnimatedViewportManager: Drill-out animation failed', error);
            this.completeTransition();
        }
    }
    setViewportImmediate(viewport) {
        if (this.reactFlowInstance) this.reactFlowInstance.setViewport(viewport, {
            duration: 0
        });
        this.currentViewport = viewport;
    }
    getNodeBounds(nodeId) {
        if (!this.reactFlowInstance) return null;
        const node = this.reactFlowInstance.getNode(nodeId);
        if (!node) return null;
        return {
            x: node.position.x,
            y: node.position.y,
            width: node.width || 200,
            height: node.height || 100
        };
    }
    cancelTransition() {
        if (this.isTransitioning()) {
            console.warn('AnimatedViewportManager: Cancelling active transition');
            this.completeTransition();
        }
    }
    destroy() {
        this.clearTransitionTimeout();
        this.cancelTransition();
        this.reactFlowInstance = null;
    }
}
const animatedViewportManager = new AnimatedViewportManager();
export { animatedViewportManager };
