{"version":3,"file":"useNavigation.cjs","sources":["../../../src/hooks/useNavigation.ts"],"sourcesContent":["import { useEffect, useRef, useCallback } from 'react';\nimport ResourceManager from '../managers/ResourceManager';\n\n// Development environment check\nconst isDevelopment = import.meta.env?.MODE === 'development';\n\n// Enhanced interfaces for better type safety\ninterface UseNavigationProps {\n    onNext: () => void;\n    onPrev: () => void;\n    enableKeyboardNav?: boolean;\n    resourceManager?: ResourceManager | null;\n}\n\ninterface NavigationResult {\n    goNext: () => void;\n    goPrev: () => void;\n    isKeyboardEnabled: boolean;\n}\n\n// Type definition for event callbacks to match ResourceManager's expected type\ntype EventCallback = EventListenerOrEventListenerObject;\n\n// Interface for stable handler storage\ninterface StableHandlers {\n    keyDownHandler: EventCallback;\n    slideChangeHandler: EventCallback;\n    latestNextFn: (() => void) | null;\n    latestPrevFn: (() => void) | null;\n}\n\n// Interface for batch operation states\ninterface BatchOperationState {\n    pendingListeners: Map<EventTarget, Map<string, EventCallback[]>>;\n    processedCount: number;\n}\n\n/**\n * Hook to set up navigation controls for the slider\n * Fully optimized with:\n * - Batch event listener registration\n * - Comprehensive error handling\n * - Memory leak prevention\n * - Stable handler references\n * - Strong cancellation mechanisms\n * - Server-side rendering safety\n */\nconst useNavigation = ({\n                           onNext,\n                           onPrev,\n                           enableKeyboardNav = true,\n                           resourceManager\n                       }: UseNavigationProps): NavigationResult => {\n    // Track component mount state\n    const isMountedRef = useRef(true);\n\n    // Track batch operations\n    const batchOperationsRef = useRef<BatchOperationState>({\n        pendingListeners: new Map(),\n        processedCount: 0\n    });\n\n    // Define stable handler interface with ref\n    const handlersRef = useRef<StableHandlers>({\n        keyDownHandler: (event: Event) => {\n            try {\n                if (!isMountedRef.current || !enableKeyboardNav) return;\n\n                const keyEvent = event as KeyboardEvent;\n                const handlers = handlersRef.current;\n\n                // Handle keyboard navigation\n                switch (keyEvent.key) {\n                    case 'ArrowLeft':\n                        if (handlers.latestPrevFn) {\n                            handlers.latestPrevFn();\n                        }\n                        break;\n                    case 'ArrowRight':\n                        if (handlers.latestNextFn) {\n                            handlers.latestNextFn();\n                        }\n                        break;\n                }\n            } catch (error) {\n                if (isDevelopment) {\n                    console.error('Error in keyboard navigation handler:', error);\n                }\n            }\n        },\n        slideChangeHandler: (event: Event) => {\n            try {\n                if (!isMountedRef.current) return;\n\n                const customEvent = event as CustomEvent;\n                const handlers = handlersRef.current;\n\n                // Handle custom slide change events\n                if (customEvent.detail && typeof customEvent.detail.nextIndex === 'number') {\n                    if (handlers.latestNextFn) {\n                        handlers.latestNextFn();\n                    }\n                }\n            } catch (error) {\n                if (isDevelopment) {\n                    console.error('Error in slide change handler:', error);\n                }\n            }\n        },\n        latestNextFn: null,\n        latestPrevFn: null\n    });\n\n    /**\n     * Process any pending event listeners in batch\n     */\n    const processPendingListeners = useCallback(() => {\n        try {\n            const { pendingListeners } = batchOperationsRef.current;\n\n            // Skip if no ResourceManager or no pending listeners\n            if (!resourceManager || pendingListeners.size === 0) return;\n\n            let totalProcessed = 0;\n\n            // Process each event target\n            pendingListeners.forEach((listenerMap, target) => {\n                try {\n                    resourceManager.addEventListenerBatch(target, listenerMap);\n                    totalProcessed += Array.from(listenerMap.values())\n                        .reduce((sum, callbacks) => sum + callbacks.length, 0);\n                } catch (error) {\n                    if (isDevelopment) {\n                        console.error('Error processing listener batch for target:', error);\n                    }\n                }\n            });\n\n            // Clear the pending map\n            pendingListeners.clear();\n\n            // Update processed count\n            batchOperationsRef.current.processedCount += totalProcessed;\n\n            if (isDevelopment) {\n                console.log(`Processed ${totalProcessed} event listeners in batch`);\n            }\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error processing batch listeners:', error);\n            }\n            // Clear pending listeners even on error\n            batchOperationsRef.current.pendingListeners.clear();\n        }\n    }, [resourceManager]);\n\n    /**\n     * Add a listener to the pending batch\n     */\n    const addListenerToBatch = useCallback((\n        target: EventTarget,\n        eventType: string,\n        callback: EventCallback\n    ) => {\n        try {\n            const { pendingListeners } = batchOperationsRef.current;\n\n            // Get or create map for this target\n            if (!pendingListeners.has(target)) {\n                pendingListeners.set(target, new Map());\n            }\n\n            const targetMap = pendingListeners.get(target)!;\n\n            // Get or create array for this event type\n            if (!targetMap.has(eventType)) {\n                targetMap.set(eventType, []);\n            }\n\n            // Add callback to the list\n            targetMap.get(eventType)!.push(callback);\n\n            return true;\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error adding listener to batch:', error);\n            }\n            return false;\n        }\n    }, []);\n\n    // Keep the latest function references updated\n    useEffect(() => {\n        handlersRef.current.latestNextFn = onNext;\n        handlersRef.current.latestPrevFn = onPrev;\n    }, [onNext, onPrev]);\n\n    // Set up keyboard navigation\n    useEffect(() => {\n        // Skip during server-side rendering\n        if (typeof window === 'undefined') return;\n\n        // Skip if keyboard navigation is disabled\n        if (!enableKeyboardNav) return;\n\n        // Reset mounted state\n        isMountedRef.current = true;\n\n        try {\n            const { keyDownHandler } = handlersRef.current;\n\n            // Start performance timer if in development\n            const startTime = isDevelopment ? performance.now() : 0;\n\n            // Register event listener with batch processing if ResourceManager available\n            if (resourceManager) {\n                // Add to batch operations\n                addListenerToBatch(window, 'keydown', keyDownHandler);\n\n                // Process in batch\n                processPendingListeners();\n            } else {\n                // Direct registration\n                window.addEventListener('keydown', keyDownHandler);\n            }\n\n            // Log performance if in development\n            if (isDevelopment && startTime > 0) {\n                const setupTime = performance.now() - startTime;\n                console.log(`Keyboard navigation setup completed in ${setupTime.toFixed(2)}ms`);\n            }\n\n            // Cleanup on unmount\n            return () => {\n                // Update mounted state immediately\n                isMountedRef.current = false;\n\n                try {\n                    // ResourceManager handles its own cleanup\n                    if (!resourceManager) {\n                        window.removeEventListener('keydown', keyDownHandler);\n                    }\n                } catch (cleanupError) {\n                    if (isDevelopment) {\n                        console.error('Error during keyboard navigation cleanup:', cleanupError);\n                    }\n                }\n            };\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error setting up keyboard navigation:', error);\n            }\n            // Return empty cleanup function\n            return () => {};\n        }\n    }, [enableKeyboardNav, resourceManager, addListenerToBatch, processPendingListeners]);\n\n    // Listen for custom slide change events\n    useEffect(() => {\n        // Skip during server-side rendering\n        if (typeof window === 'undefined') return;\n\n        try {\n            const { slideChangeHandler } = handlersRef.current;\n\n            // Start performance timer if in development\n            const startTime = isDevelopment ? performance.now() : 0;\n\n            // Register with batch processing if ResourceManager is available\n            if (resourceManager) {\n                // Add to batch operations\n                addListenerToBatch(window, 'slideChange', slideChangeHandler);\n\n                // Process in batch\n                processPendingListeners();\n            } else {\n                // Direct registration\n                window.addEventListener('slideChange', slideChangeHandler);\n            }\n\n            // Log performance if in development\n            if (isDevelopment && startTime > 0) {\n                const setupTime = performance.now() - startTime;\n                console.log(`Slide change listener setup completed in ${setupTime.toFixed(2)}ms`);\n            }\n\n            // Cleanup on unmount\n            return () => {\n                try {\n                    // ResourceManager handles its own cleanup\n                    if (!resourceManager) {\n                        window.removeEventListener('slideChange', slideChangeHandler);\n                    }\n                } catch (cleanupError) {\n                    if (isDevelopment) {\n                        console.error('Error removing slide change event listener:', cleanupError);\n                    }\n                }\n            };\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error setting up slide change listener:', error);\n            }\n            // Return empty cleanup function\n            return () => {};\n        }\n    }, [resourceManager, addListenerToBatch, processPendingListeners]);\n\n    // Expose memoized navigation methods\n    const goNext = useCallback(() => {\n        try {\n            if (isMountedRef.current && handlersRef.current.latestNextFn) {\n                const startTime = isDevelopment ? performance.now() : 0;\n\n                handlersRef.current.latestNextFn();\n\n                if (isDevelopment && startTime > 0) {\n                    const executionTime = performance.now() - startTime;\n                    console.log(`Navigation next completed in ${executionTime.toFixed(2)}ms`);\n                }\n            }\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error in goNext navigation function:', error);\n            }\n        }\n    }, []);\n\n    const goPrev = useCallback(() => {\n        try {\n            if (isMountedRef.current && handlersRef.current.latestPrevFn) {\n                const startTime = isDevelopment ? performance.now() : 0;\n\n                handlersRef.current.latestPrevFn();\n\n                if (isDevelopment && startTime > 0) {\n                    const executionTime = performance.now() - startTime;\n                    console.log(`Navigation prev completed in ${executionTime.toFixed(2)}ms`);\n                }\n            }\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error in goPrev navigation function:', error);\n            }\n        }\n    }, []);\n\n    return {\n        goNext,\n        goPrev,\n        isKeyboardEnabled: enableKeyboardNav\n    };\n};\n\nexport default useNavigation;"],"names":["useRef","useCallback","useEffect"],"mappings":"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"}