{"version":3,"file":"useIdleTimer.cjs","sources":["../../../src/hooks/useIdleTimer.ts"],"sourcesContent":["import { useEffect, useRef, useCallback, type RefObject } from 'react';\nimport { DisplacementFilter } from 'pixi.js';\nimport { gsap } from 'gsap';\nimport ResourceManager from '../managers/ResourceManager';\nimport RenderScheduler from '../managers/RenderScheduler';\nimport { UpdateType } from '../managers/UpdateTypes';\nimport AnimationCoordinator, { AnimationGroupType } from '../managers/AnimationCoordinator';\n\n// Development environment check\nconst isDevelopment = import.meta.env?.MODE === 'development';\n\n// Type definitions for function parameters\ninterface UseIdleTimerProps {\n    sliderRef: RefObject<HTMLDivElement | null>;\n    cursorActive: RefObject<boolean>;\n    bgDispFilterRef: RefObject<DisplacementFilter | null>;\n    cursorDispFilterRef: RefObject<DisplacementFilter | null>;\n    cursorImgEffect: boolean;\n    defaultBgFilterScale: number;\n    defaultCursorFilterScale: number;\n    idleTimeout?: number;\n    resourceManager?: ResourceManager | null;\n}\n\n// Interface for animation state tracking\ninterface AnimationState {\n    isAnimating: boolean;\n    activeAnimations: gsap.core.Tween[];\n    pendingBatchAnimations: gsap.core.Tween[];\n}\n\n/**\n * Hook to manage idle timer for resetting displacement effects\n * Fully optimized with:\n * - Batch resource management\n * - Efficient timer handling\n * - Comprehensive error handling\n * - Memory leak prevention\n * - Optimized animation management\n * - Cancellation mechanisms\n * - Animation coordination\n */\nconst useIdleTimer = ({\n                          sliderRef,\n                          cursorActive,\n                          bgDispFilterRef,\n                          cursorDispFilterRef,\n                          cursorImgEffect,\n                          defaultBgFilterScale,\n                          defaultCursorFilterScale,\n                          idleTimeout = 300,\n                          resourceManager\n                      }: UseIdleTimerProps) => {\n    // Store idle timer reference\n    const idleTimerRef = useRef<number | null>(null);\n\n    // Store animation state with a ref to avoid re-renders\n    const animationStateRef = useRef<AnimationState>({\n        isAnimating: false,\n        activeAnimations: [],\n        pendingBatchAnimations: []\n    });\n\n    // Flag to prevent operations during unmounting\n    const isUnmountingRef = useRef(false);\n\n    // Last animation operation timestamp for performance tracking\n    const lastAnimationOpRef = useRef<number>(0);\n\n    // Get the animation coordinator\n    const animationCoordinator = AnimationCoordinator.getInstance();\n\n    /**\n     * Process pending animations in batch for better performance\n     */\n    const processPendingAnimations = useCallback(() => {\n        try {\n            // Skip if unmounting or no resource manager\n            if (isUnmountingRef.current || !resourceManager) return;\n\n            const { pendingBatchAnimations } = animationStateRef.current;\n\n            // Process animations in batch if any exist\n            if (pendingBatchAnimations.length > 0) {\n                if (isDevelopment) {\n                    console.log(`Processing batch of ${pendingBatchAnimations.length} animations`);\n                }\n\n                resourceManager.trackAnimationBatch(pendingBatchAnimations);\n\n                // Clear the array after tracking (more efficient than creating a new array)\n                pendingBatchAnimations.length = 0;\n\n                // Record performance metrics\n                const now = performance.now();\n                const opTime = now - lastAnimationOpRef.current;\n                if (isDevelopment && lastAnimationOpRef.current > 0) {\n                    console.debug(`Animation batch processing took ${opTime.toFixed(2)}ms`);\n                }\n                lastAnimationOpRef.current = now;\n            }\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error processing pending animations:', error);\n            }\n            // Clear pending animations even on error to avoid stuck state\n            animationStateRef.current.pendingBatchAnimations = [];\n        }\n    }, [resourceManager]);\n\n    /**\n     * Track an animation for batch processing\n     */\n    const trackAnimationForBatch = useCallback((animation: gsap.core.Tween): gsap.core.Tween => {\n        try {\n            // Skip if unmounting\n            if (isUnmountingRef.current) return animation;\n\n            // Add to pending batch\n            animationStateRef.current.pendingBatchAnimations.push(animation);\n            return animation;\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error tracking animation for batch:', error);\n            }\n            return animation;\n        }\n    }, []);\n\n    /**\n     * Create animations for filter scale changes\n     * Now uses AnimationCoordinator for better coordination\n     */\n    const createFilterAnimations = useCallback((\n        targetScale: number,\n        duration: number = 0.5,\n        onComplete?: () => void\n    ): gsap.core.Tween[] => {\n        try {\n            // Skip if unmounting\n            if (isUnmountingRef.current) return [];\n\n            // Record start time for performance tracking\n            lastAnimationOpRef.current = performance.now();\n\n            if (isDevelopment) {\n                console.log(`Creating filter animations with targetScale: ${targetScale}, duration: ${duration}`, {\n                    bgFilterCurrent: bgDispFilterRef.current ?\n                        { x: bgDispFilterRef.current.scale.x, y: bgDispFilterRef.current.scale.y } : 'no filter',\n                    cursorFilterCurrent: cursorDispFilterRef.current ?\n                        { x: cursorDispFilterRef.current.scale.x, y: cursorDispFilterRef.current.scale.y } : 'no filter',\n                    defaultBgFilterScale,\n                    defaultCursorFilterScale\n                });\n            }\n\n            // Create animations array for batch tracking\n            const animations: gsap.core.Tween[] = [];\n\n            // Create background displacement filter animation\n            if (bgDispFilterRef.current) {\n                // Ensure we're using the correct target scale\n                const actualTargetScale = targetScale === 0 ? 0 : defaultBgFilterScale;\n\n                // Apply immediate scale if needed for visibility\n                if (targetScale > 0 && (bgDispFilterRef.current.scale.x === 0 || bgDispFilterRef.current.scale.y === 0)) {\n                    bgDispFilterRef.current.scale.x = actualTargetScale;\n                    bgDispFilterRef.current.scale.y = actualTargetScale;\n\n                    if (isDevelopment) {\n                        console.log(`Applied immediate scale to background filter: ${actualTargetScale}`);\n                    }\n                }\n\n                const bgTween = gsap.to(bgDispFilterRef.current.scale, {\n                    x: actualTargetScale,\n                    y: actualTargetScale,\n                    duration,\n                    ease: \"power2.out\",\n                    onComplete: () => {\n                        // Re-track the filter after animation\n                        if (resourceManager && bgDispFilterRef.current) {\n                            resourceManager.trackFilter(bgDispFilterRef.current);\n                        }\n\n                        if (isDevelopment) {\n                            console.log(`Background filter animation complete, scale: (${actualTargetScale}, ${actualTargetScale})`);\n                        }\n                    }\n                });\n\n                animations.push(bgTween);\n            }\n\n            // Create cursor displacement filter animation if enabled\n            if (cursorImgEffect && cursorDispFilterRef.current) {\n                const cursorScale = targetScale === 0 ? 0 : defaultCursorFilterScale;\n\n                // Apply immediate scale if needed for visibility\n                if (targetScale > 0 && (cursorDispFilterRef.current.scale.x === 0 || cursorDispFilterRef.current.scale.y === 0)) {\n                    cursorDispFilterRef.current.scale.x = cursorScale;\n                    cursorDispFilterRef.current.scale.y = cursorScale;\n\n                    if (isDevelopment) {\n                        console.log(`Applied immediate scale to cursor filter: ${cursorScale}`);\n                    }\n                }\n\n                const cursorTween = gsap.to(cursorDispFilterRef.current.scale, {\n                    x: cursorScale,\n                    y: cursorScale,\n                    duration,\n                    ease: \"power2.out\",\n                    onComplete: () => {\n                        // Re-track the filter after animation\n                        if (resourceManager && cursorDispFilterRef.current) {\n                            resourceManager.trackFilter(cursorDispFilterRef.current);\n                        }\n\n                        if (isDevelopment) {\n                            console.log(`Cursor filter animation complete, scale: (${cursorScale}, ${cursorScale})`);\n                        }\n                    }\n                });\n\n                animations.push(cursorTween);\n            }\n\n            // Use AnimationCoordinator to create a coordinated animation group\n            const groupType = targetScale === 0\n                ? AnimationGroupType.IDLE_EFFECT\n                : AnimationGroupType.INTERACTION;\n\n            animationCoordinator.queueAnimationGroup({\n                id: `filter_animation_${Date.now()}`,\n                type: groupType,\n                animations,\n                onComplete\n            });\n\n            return animations;\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error creating filter animations:', error);\n            }\n\n            // Call completion handler even on error\n            if (onComplete) onComplete();\n            return [];\n        }\n    }, [\n        bgDispFilterRef,\n        cursorDispFilterRef,\n        cursorImgEffect,\n        defaultCursorFilterScale,\n        defaultBgFilterScale,\n        resourceManager,\n        animationCoordinator\n    ]);\n\n    /**\n     * Reset filters to idle state (no effect)\n     * Now uses AnimationCoordinator for better coordination\n     */\n    const resetFilters = useCallback(() => {\n        try {\n            // Skip if unmounting\n            if (isUnmountingRef.current) return;\n\n            if (isDevelopment) {\n                console.log('Resetting filters to idle state');\n            }\n\n            // Cancel any active idle timer\n            if (idleTimerRef.current !== null) {\n                window.clearTimeout(idleTimerRef.current);\n                idleTimerRef.current = null;\n            }\n\n            // Skip if cursor is active\n            if (cursorActive.current) {\n                if (isDevelopment) {\n                    console.log('Skipping filter reset - cursor is active');\n                }\n                return;\n            }\n\n            // Cancel any existing animations of the same type\n            animationCoordinator.cancelAnimationsByType(AnimationGroupType.IDLE_EFFECT);\n\n            // Create animations to reset filters\n            createFilterAnimations(0, 0.5, () => {\n                if (isDevelopment) {\n                    console.log('Filters reset to idle state');\n                }\n            });\n\n            // Schedule a render update\n            animationCoordinator.scheduleAnimationUpdate(\n                AnimationGroupType.IDLE_EFFECT,\n                () => {\n                    if (isDevelopment) {\n                        console.log('Idle effect render update completed');\n                    }\n                },\n                'idle_reset'\n            );\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error resetting filters:', error);\n            }\n        }\n    }, [\n        cursorActive,\n        createFilterAnimations,\n        animationCoordinator\n    ]);\n\n    /**\n     * Restore filters to active state\n     * Now uses AnimationCoordinator for better coordination\n     * @param immediate Whether to apply changes immediately without animation\n     */\n    const restoreFilters = useCallback((immediate = false) => {\n        try {\n            // Skip if unmounting\n            if (isUnmountingRef.current) return;\n\n            if (isDevelopment) {\n                console.log(`Restoring filters to active state (immediate: ${immediate})`, {\n                    defaultBgFilterScale,\n                    defaultCursorFilterScale,\n                    bgFilterCurrent: bgDispFilterRef.current ?\n                        { x: bgDispFilterRef.current.scale.x, y: bgDispFilterRef.current.scale.y } : 'no filter',\n                    cursorFilterCurrent: cursorDispFilterRef.current ?\n                        { x: cursorDispFilterRef.current.scale.x, y: cursorDispFilterRef.current.scale.y } : 'no filter'\n                });\n            }\n\n            // Cancel any active idle timer\n            if (idleTimerRef.current !== null) {\n                window.clearTimeout(idleTimerRef.current);\n                idleTimerRef.current = null;\n            }\n\n            // Cancel any existing animations of the same type\n            animationCoordinator.cancelAnimationsByType(AnimationGroupType.INTERACTION);\n\n            // Ensure the cursor is marked as active\n            cursorActive.current = true;\n\n            // Apply immediate changes to ensure filters are visible right away\n            if (bgDispFilterRef.current) {\n                // Store original values for debugging\n                const originalX = bgDispFilterRef.current.scale.x;\n                const originalY = bgDispFilterRef.current.scale.y;\n\n                // Set to full scale values\n                bgDispFilterRef.current.scale.x = defaultBgFilterScale;\n                bgDispFilterRef.current.scale.y = defaultBgFilterScale;\n\n                if (isDevelopment) {\n                    console.log(`Directly set background filter scale from (${originalX}, ${originalY}) to (${defaultBgFilterScale}, ${defaultBgFilterScale})`);\n                }\n            }\n\n            if (cursorImgEffect && cursorDispFilterRef.current) {\n                // Store original values for debugging\n                const originalX = cursorDispFilterRef.current.scale.x;\n                const originalY = cursorDispFilterRef.current.scale.y;\n\n                // Set to full scale values\n                cursorDispFilterRef.current.scale.x = defaultCursorFilterScale;\n                cursorDispFilterRef.current.scale.y = defaultCursorFilterScale;\n\n                if (isDevelopment) {\n                    console.log(`Directly set cursor filter scale from (${originalX}, ${originalY}) to (${defaultCursorFilterScale}, ${defaultCursorFilterScale})`);\n                }\n            }\n\n            // Schedule an immediate render update to ensure changes are visible\n            RenderScheduler.getInstance().scheduleTypedUpdate(\n                'idleTimer',\n                UpdateType.DISPLACEMENT_EFFECT,\n                () => {\n                    if (isDevelopment) {\n                        console.log('Immediate render update for filter restoration');\n                    }\n                },\n                immediate ? 'critical' : 'high' // Use critical priority for immediate restoration\n            );\n\n            // If immediate is true, we've already set the filter scales directly\n            // For smoother transitions, still create animations but with shorter duration\n            const animationDuration = immediate ? 0.2 : 0.5;\n\n            // Create animations to restore filters (for smooth transition)\n            createFilterAnimations(defaultBgFilterScale, animationDuration, () => {\n                if (isDevelopment) {\n                    console.log('Filters restored to active state - animation complete', {\n                        bgFilterFinal: bgDispFilterRef.current ?\n                            { x: bgDispFilterRef.current.scale.x, y: bgDispFilterRef.current.scale.y } : 'no filter',\n                        cursorFilterFinal: cursorDispFilterRef.current ?\n                            { x: cursorDispFilterRef.current.scale.x, y: cursorDispFilterRef.current.scale.y } : 'no filter'\n                    });\n                }\n            });\n\n            // Schedule a render update with appropriate priority\n            animationCoordinator.scheduleAnimationUpdate(\n                AnimationGroupType.INTERACTION,\n                () => {\n                    if (isDevelopment) {\n                        console.log('Interaction effect render update completed');\n                    }\n                },\n                immediate ? 'critical' : 'high'\n            );\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error restoring filters:', error);\n            }\n        }\n    }, [\n        defaultBgFilterScale,\n        defaultCursorFilterScale,\n        bgDispFilterRef,\n        cursorDispFilterRef,\n        cursorImgEffect,\n        cursorActive,\n        createFilterAnimations,\n        animationCoordinator\n    ]);\n\n    /**\n     * Handle mouse movement to reset idle timer\n     */\n    const handleMouseMove = useCallback(() => {\n        try {\n            // Skip if unmounting\n            if (isUnmountingRef.current) return;\n\n            // Cancel any active idle timer\n            if (idleTimerRef.current !== null) {\n                window.clearTimeout(idleTimerRef.current);\n                idleTimerRef.current = null;\n            }\n\n            // Set cursor as active\n            if (cursorActive.current !== true) {\n                cursorActive.current = true;\n\n                if (isDevelopment) {\n                    console.log('Mouse movement detected - setting cursor as active');\n                }\n\n                // Immediately restore filters when cursor becomes active after being inactive\n                // This ensures there's no delay in showing the displacement effect\n                const bgFilter = bgDispFilterRef.current;\n                const cursorFilter = cursorDispFilterRef.current;\n\n                if (bgFilter) {\n                    // Apply full scale immediately for instant visibility\n                    bgFilter.scale.x = defaultBgFilterScale;\n                    bgFilter.scale.y = defaultBgFilterScale;\n\n                    if (isDevelopment) {\n                        console.log(`Immediately set background filter scale to ${defaultBgFilterScale} after idle`);\n                    }\n                }\n\n                if (cursorImgEffect && cursorFilter) {\n                    // Apply full scale immediately for instant visibility\n                    cursorFilter.scale.x = defaultCursorFilterScale;\n                    cursorFilter.scale.y = defaultCursorFilterScale;\n\n                    if (isDevelopment) {\n                        console.log(`Immediately set cursor filter scale to ${defaultCursorFilterScale} after idle`);\n                    }\n                }\n\n                // Schedule an immediate render update to ensure changes are visible\n                RenderScheduler.getInstance().scheduleTypedUpdate(\n                    'idleTimer',\n                    UpdateType.DISPLACEMENT_EFFECT,\n                    () => {\n                        if (isDevelopment) {\n                            console.log('Immediate render update for filter restoration after idle');\n                        }\n                    },\n                    'critical' // Use critical priority to ensure immediate processing\n                );\n\n                // Then call restoreFilters to handle animations and other logic\n                restoreFilters(true); // Pass true to indicate immediate restoration\n            }\n\n            // Check if filters need to be restored\n            const bgFilter = bgDispFilterRef.current;\n            const cursorFilter = cursorDispFilterRef.current;\n\n            const bgFilterInactive = bgFilter && (bgFilter.scale.x === 0 || bgFilter.scale.y === 0);\n            const cursorFilterInactive = cursorImgEffect && cursorFilter &&\n                (cursorFilter.scale.x === 0 || cursorFilter.scale.y === 0);\n\n            if (bgFilterInactive || cursorFilterInactive) {\n                if (isDevelopment) {\n                    console.log('Filters are inactive, restoring them immediately', {\n                        bgFilterInactive,\n                        cursorFilterInactive,\n                        bgScale: bgFilter ? [bgFilter.scale.x, bgFilter.scale.y] : 'no filter',\n                        cursorScale: cursorFilter ? [cursorFilter.scale.x, cursorFilter.scale.y] : 'no filter'\n                    });\n                }\n\n                // Restore filters to active state immediately\n                restoreFilters(true); // Pass true to indicate immediate restoration\n            }\n\n            // Set a new idle timer\n            idleTimerRef.current = window.setTimeout(() => {\n                // Set cursor as inactive\n                cursorActive.current = false;\n\n                if (isDevelopment) {\n                    console.log('Idle timeout reached - setting cursor as inactive');\n                }\n\n                // Reset filters when idle\n                resetFilters();\n\n                // Clear timer reference\n                idleTimerRef.current = null;\n            }, idleTimeout);\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error handling mouse movement:', error);\n            }\n        }\n    }, [\n        cursorActive,\n        bgDispFilterRef,\n        cursorDispFilterRef,\n        cursorImgEffect,\n        defaultBgFilterScale,\n        defaultCursorFilterScale,\n        idleTimeout,\n        resetFilters,\n        restoreFilters\n    ]);\n\n    // Set up mouse movement tracking\n    useEffect(() => {\n        // Skip during server-side rendering\n        if (typeof window === 'undefined') return;\n\n        // Skip if slider reference is not available\n        if (!sliderRef.current) return;\n\n        // Reset unmounting flag\n        isUnmountingRef.current = false;\n\n        try {\n            const node = sliderRef.current;\n\n            // Register event listeners\n            if (resourceManager) {\n                // Batch registration with ResourceManager\n                const listeners = new Map<string, EventCallback[]>();\n                listeners.set('mousemove', [handleMouseMove]);\n                resourceManager.addEventListenerBatch(node, listeners);\n            } else {\n                // Direct registration\n                node.addEventListener('mousemove', handleMouseMove, { passive: true });\n            }\n\n            // Set initial idle timer\n            idleTimerRef.current = window.setTimeout(() => {\n                // Set cursor as inactive\n                cursorActive.current = false;\n\n                // Reset filters when idle\n                resetFilters();\n\n                // Clear timer reference\n                idleTimerRef.current = null;\n            }, idleTimeout);\n\n            // Cleanup on unmount\n            return () => {\n                // Update unmounting flag immediately\n                isUnmountingRef.current = true;\n\n                try {\n                    // Cancel any active idle timer\n                    if (idleTimerRef.current !== null) {\n                        window.clearTimeout(idleTimerRef.current);\n                        idleTimerRef.current = null;\n                    }\n\n                    // ResourceManager handles its own cleanup\n                    if (!resourceManager) {\n                        node.removeEventListener('mousemove', handleMouseMove);\n                    }\n                } catch (cleanupError) {\n                    if (isDevelopment) {\n                        console.error('Error during idle timer cleanup:', cleanupError);\n                    }\n                }\n            };\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error setting up idle timer:', error);\n            }\n            // Return empty cleanup function\n            return () => {};\n        }\n    }, [\n        sliderRef,\n        handleMouseMove,\n        idleTimeout,\n        resetFilters,\n        resourceManager\n    ]);\n\n    // Return methods for external control\n    return {\n        resetFilters,\n        restoreFilters\n    };\n};\n\n// Type definition for event callback - to match ResourceManager's expected type\ntype EventCallback = EventListenerOrEventListenerObject;\n\nexport default useIdleTimer;"],"names":["useRef","AnimationCoordinator","useCallback","gsap","AnimationGroupType","RenderScheduler","UpdateType","bgFilter","cursorFilter","useEffect"],"mappings":"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"}