import { useRef, useEffect, useMemo } from 'react';
import { SmoothScrollEngine } from './SmoothScrollEngine.js';
import { isReducedMotion } from '../../../../utils/smoothScrollUtils.js';

/**
 * Custom hook for applying smooth scrolling to any element
 *
 * @param elementRef - Ref to the scrollable element
 * @param config - Smooth scroll configuration
 * @param orientation - Scroll orientation
 * @returns API object for programmatic control, or null if disabled
 *
 * @example
 * ```tsx
 * const ref = useRef<HTMLDivElement>(null);
 * const smoothAPI = useSmoothScroll(ref, {
 *   lerp: 0.1,
 *   elasticEdges: true,
 * });
 *
 * // Programmatic control
 * <button onClick={() => smoothAPI?.scrollTo(500)}>
 *   Scroll to 500px
 * </button>
 * ```
 */
function useSmoothScroll(elementRef, config = {}, orientation = 'vertical') {
    const engineRef = useRef(null);
    // Check for reduced motion preference
    const shouldDisable = isReducedMotion();
    // Initialize engine
    useEffect(() => {
        // Don't initialize if ref is null, disabled, or element doesn't exist
        if (!elementRef || !elementRef.current || shouldDisable) {
            return;
        }
        const element = elementRef.current;
        if (process.env.NODE_ENV !== 'production') {
            console.log('[useSmoothScroll] Initializing engine', {
                element,
                config,
                orientation,
            });
        }
        // Create engine
        engineRef.current = new SmoothScrollEngine(element, config, orientation);
        // Start engine
        engineRef.current.start();
        // Refresh snap points after a short delay to ensure DOM is ready
        if (config.respectSnapPoints) {
            setTimeout(() => {
                var _a;
                (_a = engineRef.current) === null || _a === void 0 ? void 0 : _a.refreshSnapPoints();
            }, 100);
        }
        // Cleanup
        return () => {
            var _a;
            if (process.env.NODE_ENV !== 'production') {
                console.log('[useSmoothScroll] Destroying engine');
            }
            (_a = engineRef.current) === null || _a === void 0 ? void 0 : _a.destroy();
            engineRef.current = null;
        };
    }, [elementRef, shouldDisable, orientation, config.respectSnapPoints]);
    // Update config when it changes
    useEffect(() => {
        if (engineRef.current && Object.keys(config).length > 0) {
            engineRef.current.updateConfig(config);
        }
    }, [config]);
    // Return stable API object
    // Note: We don't gate on engineRef.current here because refs don't trigger
    // re-renders. The methods use optional chaining so they safely no-op before
    // the engine is initialised in the effect above.
    const api = useMemo(() => {
        if (shouldDisable) {
            return null;
        }
        return {
            scrollTo: (position, options) => {
                var _a;
                (_a = engineRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo(position, options);
            },
            scrollToElement: (element, options) => {
                var _a;
                (_a = engineRef.current) === null || _a === void 0 ? void 0 : _a.scrollToElement(element, options);
            },
            getVelocity: () => {
                var _a, _b;
                return (_b = (_a = engineRef.current) === null || _a === void 0 ? void 0 : _a.getVelocity()) !== null && _b !== void 0 ? _b : 0;
            },
            getProgress: () => {
                var _a, _b;
                return (_b = (_a = engineRef.current) === null || _a === void 0 ? void 0 : _a.getProgress()) !== null && _b !== void 0 ? _b : null;
            },
            stop: () => {
                var _a;
                (_a = engineRef.current) === null || _a === void 0 ? void 0 : _a.stop();
            },
            start: () => {
                var _a;
                (_a = engineRef.current) === null || _a === void 0 ? void 0 : _a.start();
            },
            update: (newConfig) => {
                var _a;
                (_a = engineRef.current) === null || _a === void 0 ? void 0 : _a.updateConfig(newConfig);
            },
            refreshSnapPoints: () => {
                var _a;
                (_a = engineRef.current) === null || _a === void 0 ? void 0 : _a.refreshSnapPoints();
            },
        };
    }, [shouldDisable]);
    return api;
}

export { useSmoothScroll };
