/*
    Предрейсовые осмотры - мобильное приложение
    Провайдер встроенного сканера: маршрутизация данных по текущему экрану
*/

//---------------------
//Подключение библиотек
//---------------------

const React = require('react');
const { useAppNavigationContext } = require('./AppNavigationProvider'); //Контекст навигации
const HardwareScannerBridge = require('../../services/HardwareScannerBridge'); //Мост встроенного сканера

//---------
//Контекст
//---------

const HardwareScannerContext = React.createContext(null);

//-----------
//Тело модуля
//-----------

//Вызов обработчика для текущего экрана при получении данных от встроенного сканера
function dispatchHardwareScan(currentScreen, handlersRef, barcode) {
    const handlers = handlersRef.current;
    const hasHandler = handlers && typeof handlers[currentScreen] === 'function';
    if (!handlers || !hasHandler) return;
    try {
        handlers[currentScreen](barcode);
    } catch (_err) {}
}

//Провайдер встроенного сканера
function HardwareScannerProvider({ children }) {
    const { currentScreen, SCREENS } = useAppNavigationContext();
    const handlersRef = React.useRef(Object.create(null));
    const currentScreenRef = React.useRef(currentScreen);
    const unsubscribeRef = React.useRef(null);

    currentScreenRef.current = currentScreen;

    const registerHandler = React.useCallback(function registerHandler(screen, handler) {
        if (!screen || typeof handler !== 'function') return;
        handlersRef.current[screen] = handler;
    }, []);

    const unregisterHandler = React.useCallback(function unregisterHandler(screen) {
        if (!screen) return;
        delete handlersRef.current[screen];
    }, []);

    React.useEffect(function subscribeToHardwareScanner() {
        const unsubscribe = HardwareScannerBridge.startHardwareListener(function onData(barcode) {
            const screen = currentScreenRef.current;
            dispatchHardwareScan(screen, handlersRef, barcode);
        });
        unsubscribeRef.current = unsubscribe;
        return function cleanup() {
            if (typeof unsubscribeRef.current === 'function') {
                unsubscribeRef.current();
            }
            unsubscribeRef.current = null;
        };
    }, []);

    const value = React.useMemo(
        function getValue() {
            return {
                registerHandler,
                unregisterHandler,
                SCREENS
            };
        },
        [registerHandler, unregisterHandler, SCREENS]
    );

    return <HardwareScannerContext.Provider value={value}>{children}</HardwareScannerContext.Provider>;
}

//Хук доступа к контексту встроенного сканера
function useHardwareScannerContext() {
    const ctx = React.useContext(HardwareScannerContext);
    if (!ctx) {
        throw new Error('useHardwareScannerContext должен использоваться внутри HardwareScannerProvider');
    }
    return ctx;
}

//----------------
//Интерфейс модуля
//----------------

module.exports = {
    HardwareScannerProvider,
    useHardwareScannerContext
};
