/*
    Предрейсовые осмотры - мобильное приложение
    Главный экран приложения
*/

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

const React = require('react'); //React и хуки
const { View } = require('react-native'); //Базовые компоненты
const { useAppMessagingContext } = require('../components/layout/AppMessagingProvider'); //Контекст сообщений
const { useAppModeContext } = require('../components/layout/AppModeProvider'); //Контекст режима работы
const { useAppNavigationContext } = require('../components/layout/AppNavigationProvider'); //Контекст навигации
const { useHardwareScannerContext } = require('../components/layout/HardwareScannerProvider'); //Встроенный сканер
const { useAppLocalDbContext } = require('../components/layout/AppLocalDbProvider'); //Контекст локальной БД
const { useAppAuthContext } = require('../components/layout/AppAuthProvider'); //Контекст авторизации
const AppHeader = require('../components/layout/AppHeader'); //Заголовок с меню
const SideMenu = require('../components/menu/SideMenu'); //Боковое меню
const ScannerArea = require('../components/scanner/ScannerArea'); //Область сканера
const ScanResultModal = require('../components/scanner/ScanResultModal'); //Модальное окно результата сканирования
const { AUTH_SETTINGS_KEYS } = require('../config/authConfig'); //Ключи настроек
const { getAppInfo } = require('../utils/appInfo'); //Информация о приложении
const {
    APP_ABOUT_TITLE,
    SIDE_MENU_TITLE,
    MENU_ITEM_SETTINGS,
    MENU_ITEM_ABOUT,
    MENU_ITEM_LOGIN,
    MENU_ITEM_LOGOUT,
    OFFLINE_MODE_TITLE,
    LOGOUT_CONFIRM_TITLE,
    LOGOUT_CONFIRM_MESSAGE,
    AUTH_BUTTON_LOGOUT
} = require('../config/messages'); //Сообщения
const { DIALOG_BUTTON_TYPE, DIALOG_CANCEL_BUTTON, getConfirmButtonOptions } = require('../config/dialogButtons'); //Кнопки диалогов
const { createLogoutHandler } = require('../utils/logoutFlow'); //Универсальный поток выхода
const { APP_COLORS } = require('../config/theme'); //Цветовая схема
const { MENU_ITEM_ID_SETTINGS, MENU_ITEM_ID_ABOUT, MENU_ITEM_ID_LOGIN, MENU_ITEM_ID_LOGOUT, MENU_ITEM_ID_DIVIDER } = require('../config/menuItemIds'); //ID пунктов меню
const { shouldShowScanner, HARDWARE_SCANNER_TRIGGER_EVENT_NAME, HARDWARE_SCANNER_CAMERA_HIDE_MS } = require('../config/scannerConfig'); //Логика и константы сканера
const { DeviceEventEmitter } = require('react-native'); //События нативного модуля
const HardwareScannerBridge = require('../services/HardwareScannerBridge'); //Отключение фокуса у камеры при отображении
const styles = require('../styles/screens/MainScreen.styles'); //Стили экрана

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

//Главный экран приложения
function MainScreen() {
    const { showInfo, showError, state: messagingState } = useAppMessagingContext();
    const { mode, setNotConnected } = useAppModeContext();
    const { navigate, SCREENS, setInitialScreen } = useAppNavigationContext();
    const { getSetting, isDbReady: isLocalDbReady } = useAppLocalDbContext();
    const { session, isAuthenticated, logout, isStartupSessionCheckInProgress } = useAppAuthContext();

    const [menuVisible, setMenuVisible] = React.useState(false);
    const [serverUrl, setServerUrl] = React.useState('');
    const [alwaysShowScanner, setAlwaysShowScanner] = React.useState(false);
    const [mainScannerPriority, setMainScannerPriority] = React.useState('camera');
    const [cameraResumedByTap, setCameraResumedByTap] = React.useState(false);
    const [scanResult, setScanResult] = React.useState(null);
    const [cameraHiddenForHardwareScan, setCameraHiddenForHardwareScan] = React.useState(false);

    const { registerHandler, unregisterHandler, SCREENS: scannerScreens } = useHardwareScannerContext();

    //Обработчик встроенного сканера: данные как есть в результат сканирования (все символы)
    const handleHardwareScan = React.useCallback(barcode => {
        if (barcode == null) return;
        const value = typeof barcode === 'string' ? barcode : String(barcode);
        setScanResult({ type: 'unknown', value: value });
        setCameraHiddenForHardwareScan(false);
    }, []);

    const mainScanHandlerRef = React.useRef(handleHardwareScan);
    mainScanHandlerRef.current = handleHardwareScan;
    const stableMainScanHandler = React.useCallback(barcode => {
        if (typeof mainScanHandlerRef.current === 'function') mainScanHandlerRef.current(barcode);
    }, []);

    //Регистрация обработчика встроенного сканера
    React.useEffect(() => {
        registerHandler(scannerScreens.MAIN, stableMainScanHandler);
        return function cleanup() {
            unregisterHandler(scannerScreens.MAIN);
        };
    }, [registerHandler, unregisterHandler, scannerScreens.MAIN, stableMainScanHandler]);

    //При нажатии кнопки встроенного сканера (142/141): скрываем камеру (отложенно, вне контекста события)
    React.useEffect(function subscribeHardwareScannerTrigger() {
        let restoreTimeoutId = null;
        const sub = DeviceEventEmitter.addListener(HARDWARE_SCANNER_TRIGGER_EVENT_NAME, function onTrigger() {
            setTimeout(function applyTriggerState() {
                setCameraResumedByTap(false);
                setCameraHiddenForHardwareScan(true);
                if (restoreTimeoutId != null) clearTimeout(restoreTimeoutId);
                restoreTimeoutId = setTimeout(function restoreCamera() {
                    restoreTimeoutId = null;
                    setCameraHiddenForHardwareScan(false);
                }, HARDWARE_SCANNER_CAMERA_HIDE_MS);
            }, 0);
        });
        return function cleanup() {
            sub.remove();
            if (restoreTimeoutId != null) clearTimeout(restoreTimeoutId);
        };
    }, []);

    //При отображении области сканера вызываем setCameraViewsNotFocusable
    React.useEffect(() => {
        if (!isScannerOpen) return;
        HardwareScannerBridge.setCameraViewsNotFocusable();
    }, [isScannerOpen]);

    //Загрузка настроек главного экрана при готовности БД
    React.useEffect(() => {
        if (!isLocalDbReady) {
            return;
        }

        const loadMainScreenSettings = async () => {
            try {
                const savedUrl = await getSetting(AUTH_SETTINGS_KEYS.SERVER_URL);
                if (savedUrl) {
                    setServerUrl(savedUrl);
                }

                const savedAlwaysShowScanner = await getSetting(AUTH_SETTINGS_KEYS.ALWAYS_SHOW_SCANNER);
                setAlwaysShowScanner(savedAlwaysShowScanner === 'true' || savedAlwaysShowScanner === true);

                const savedPriority = await getSetting(AUTH_SETTINGS_KEYS.MAIN_SCANNER_PRIORITY);
                setMainScannerPriority(savedPriority === 'hardware' ? 'hardware' : 'camera');
            } catch (loadError) {}
        };

        loadMainScreenSettings();
    }, [isLocalDbReady, getSetting]);

    //Обработчик открытия меню
    const handleMenuOpen = React.useCallback(() => {
        setMenuVisible(true);
    }, []);

    //Обработчик закрытия меню
    const handleMenuClose = React.useCallback(() => {
        setMenuVisible(false);
    }, []);

    //Обработчик показа информации о приложении
    const handleShowAbout = React.useCallback(() => {
        const appInfo = getAppInfo({
            mode,
            serverUrl,
            isDbReady: isLocalDbReady
        });

        showInfo(appInfo, {
            title: APP_ABOUT_TITLE
        });
    }, [showInfo, mode, serverUrl, isLocalDbReady]);

    //Обработчик перехода на экран входа
    const handleLogin = React.useCallback(() => {
        navigate(SCREENS.AUTH, { fromMenu: true, fromMenuKey: Date.now() });
    }, [navigate, SCREENS.AUTH]);

    //Обработчик перехода в настройки
    const handleOpenSettings = React.useCallback(() => {
        navigate(SCREENS.SETTINGS);
    }, [navigate, SCREENS.SETTINGS]);

    //Универсальный обработчик выхода
    const { handleLogout } = React.useMemo(
        () =>
            createLogoutHandler({
                logout,
                mode,
                setNotConnected,
                setInitialScreen,
                SCREENS,
                showError,
                showInfo,
                logoutConfirmTitle: LOGOUT_CONFIRM_TITLE,
                logoutConfirmMessage: LOGOUT_CONFIRM_MESSAGE,
                logoutButtonTitle: AUTH_BUTTON_LOGOUT,
                getConfirmButtonOptions,
                dialogButtonTypeError: DIALOG_BUTTON_TYPE.ERROR,
                dialogCancelButton: DIALOG_CANCEL_BUTTON
            }),
        [logout, mode, setNotConnected, setInitialScreen, SCREENS, showError, showInfo]
    );

    //Пункты бокового меню
    const menuItems = React.useMemo(() => {
        const items = [
            {
                id: MENU_ITEM_ID_SETTINGS,
                title: MENU_ITEM_SETTINGS,
                onPress: handleOpenSettings
            },
            {
                id: MENU_ITEM_ID_ABOUT,
                title: MENU_ITEM_ABOUT,
                onPress: handleShowAbout
            }
        ];

        //Добавляем разделитель перед кнопками авторизации
        items.push({
            id: MENU_ITEM_ID_DIVIDER,
            type: 'divider'
        });

        //Кнопка "Вход" для оффлайн режима
        if (mode === 'OFFLINE') {
            items.push({
                id: MENU_ITEM_ID_LOGIN,
                title: MENU_ITEM_LOGIN,
                onPress: handleLogin
            });
        }

        //Кнопка "Выход" для онлайн/оффлайн режима (когда есть сессия)
        if ((mode === 'ONLINE' || mode === 'OFFLINE') && isAuthenticated) {
            items.push({
                id: MENU_ITEM_ID_LOGOUT,
                title: MENU_ITEM_LOGOUT,
                onPress: handleLogout,
                textStyle: { color: APP_COLORS.error },
                iconColor: APP_COLORS.error
            });
        }

        return items;
    }, [handleOpenSettings, handleShowAbout, handleLogin, handleLogout, mode, isAuthenticated]);

    //Обработчик результата сканирования
    const handleScanResult = React.useCallback(result => {
        setScanResult(result);
    }, []);

    //Закрытие модального окна результата сканирования
    const handleCloseScanResult = React.useCallback(() => {
        setScanResult(null);
    }, []);

    //Видимость сканера
    const isOfflineMessageVisible = Boolean(messagingState.visible && messagingState.title === OFFLINE_MODE_TITLE);
    const isAboutMessageVisible = Boolean(messagingState.visible && messagingState.title === APP_ABOUT_TITLE);
    const isScannerOpen = shouldShowScanner({
        alwaysShowScanner,
        hasScanResult: scanResult != null,
        isStartupCheckInProgress: isStartupSessionCheckInProgress,
        isOfflineMessageVisible,
        isAboutMessageVisible
    });
    const cameraShown = isScannerOpen && !cameraHiddenForHardwareScan;
    const cameraActiveOnMain = !(alwaysShowScanner && mainScannerPriority === 'hardware') || cameraResumedByTap;

    //Когда камера на главном экране видима
    React.useEffect(
        function cameraVisibleOnMain() {
            if (!cameraShown) return;
            const t1 = setTimeout(function run1() {
                HardwareScannerBridge.setCameraViewsNotFocusable();
            }, 100);
            const t2 = setTimeout(function run2() {
                HardwareScannerBridge.setCameraViewsNotFocusable();
            }, 400);
            return function cleanup() {
                clearTimeout(t1);
                clearTimeout(t2);
            };
        },
        [cameraShown]
    );

    const handleResumeCameraByTap = React.useCallback(function resumeCameraByTap() {
        setCameraResumedByTap(true);
    }, []);

    return (
        <View style={styles.container}>
            <AppHeader onMenuPress={handleMenuOpen} />

            <View style={styles.content}>
                <ScannerArea
                    alwaysShowScanner={alwaysShowScanner}
                    scannerOpen={cameraShown}
                    cameraActive={cameraActiveOnMain}
                    onScanResult={handleScanResult}
                    onResumeCameraPress={mainScannerPriority === 'hardware' ? handleResumeCameraByTap : undefined}
                />
            </View>

            <SideMenu
                visible={menuVisible}
                onClose={handleMenuClose}
                items={menuItems}
                title={SIDE_MENU_TITLE}
                mode={mode}
                username={session?.userName}
                organization={session?.companyName}
            />

            <ScanResultModal
                visible={scanResult != null}
                codeType={scanResult?.type}
                value={scanResult?.value}
                onRequestClose={handleCloseScanResult}
            />
        </View>
    );
}

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

module.exports = MainScreen;
