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

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

const React = require('react');
const { ScrollView, View, Pressable } = require('react-native');
const AdaptiveView = require('../components/common/AdaptiveView');
const AppText = require('../components/common/AppText');
const AppButton = require('../components/common/AppButton');
const AppSwitch = require('../components/common/AppSwitch');
const CopyButton = require('../components/common/CopyButton');
const InputDialog = require('../components/common/InputDialog');
const AppHeader = require('../components/layout/AppHeader');
const { useAppMessagingContext } = require('../components/layout/AppMessagingProvider');
const { useAppModeContext } = require('../components/layout/AppModeProvider');
const { useAppNavigationContext } = require('../components/layout/AppNavigationProvider');
const { useAppLocalDbContext } = require('../components/layout/AppLocalDbProvider');
const { useAppAuthContext } = require('../components/layout/AppAuthProvider');
const { AUTH_SETTINGS_KEYS, DEFAULT_IDLE_TIMEOUT } = require('../config/authConfig');
const { DIALOG_BUTTON_TYPE, DIALOG_CANCEL_BUTTON, getConfirmButtonOptions } = require('../config/dialogButtons');
const { getAppInfo, getModeLabel } = require('../utils/appInfo');
const { validateServerUrlAllowEmpty, validateIdleTimeout } = require('../utils/validation');
const styles = require('../styles/screens/SettingsScreen.styles');

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

function SettingsScreen() {
    const { showInfo, showError, showSuccess } = useAppMessagingContext();
    const { APP_MODE, mode, setNotConnected } = useAppModeContext();
    const { goBack, canGoBack } = useAppNavigationContext();
    const { getSetting, setSetting, clearSettings, clearInspections, vacuum, isDbReady } = useAppLocalDbContext();
    const { session, isAuthenticated, getDeviceId } = useAppAuthContext();

    const [serverUrl, setServerUrl] = React.useState('');
    const [hideServerUrl, setHideServerUrl] = React.useState(false);
    const [idleTimeout, setIdleTimeout] = React.useState('');
    const [deviceId, setDeviceId] = React.useState('');
    const [isLoading, setIsLoading] = React.useState(false);
    const [isServerUrlDialogVisible, setIsServerUrlDialogVisible] = React.useState(false);
    const [isIdleTimeoutDialogVisible, setIsIdleTimeoutDialogVisible] = React.useState(false);

    //Предотвращение повторной загрузки настроек
    const settingsLoadedRef = React.useRef(false);

    //Загрузка сохраненных настроек при готовности БД
    React.useEffect(() => {
        //Выходим, если БД не готова или уже загрузили настройки
        if (!isDbReady || settingsLoadedRef.current) {
            return;
        }

        settingsLoadedRef.current = true;

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

                const savedHideServerUrl = await getSetting(AUTH_SETTINGS_KEYS.HIDE_SERVER_URL);
                setHideServerUrl(savedHideServerUrl === 'true' || savedHideServerUrl === true);

                const savedIdleTimeout = await getSetting(AUTH_SETTINGS_KEYS.IDLE_TIMEOUT);
                if (savedIdleTimeout) {
                    setIdleTimeout(savedIdleTimeout);
                } else {
                    //Устанавливаем значение по умолчанию
                    const defaultValue = String(DEFAULT_IDLE_TIMEOUT);
                    setIdleTimeout(defaultValue);
                    await setSetting(AUTH_SETTINGS_KEYS.IDLE_TIMEOUT, defaultValue);
                }

                //Получаем или генерируем идентификатор устройства
                const currentDeviceId = await getDeviceId();
                setDeviceId(currentDeviceId || '');
            } catch (error) {
                console.error('Ошибка загрузки настроек:', error);
                showError('Не удалось загрузить настройки');
            } finally {
                setIsLoading(false);
            }
        };

        loadSettings();
    }, [isDbReady, getSetting, setSetting, showError, getDeviceId]);

    //Доступность редактирования URL сервера (только в режиме "Не подключено")
    const isServerUrlEditable = React.useMemo(
        () => !isLoading && isDbReady && mode === APP_MODE.NOT_CONNECTED,
        [isLoading, isDbReady, mode, APP_MODE.NOT_CONNECTED]
    );

    //Стиль поля URL сервера при нажатии
    const getServerUrlFieldPressableStyle = React.useCallback(
        ({ pressed }) => [
            styles.serverUrlField,
            isServerUrlEditable ? (pressed ? styles.serverUrlFieldPressed : null) : styles.serverUrlFieldDisabled
        ],
        [isServerUrlEditable]
    );

    //Стиль поля времени простоя при нажатии
    const getIdleTimeoutFieldPressableStyle = React.useCallback(
        ({ pressed }) => [styles.serverUrlField, pressed && styles.serverUrlFieldPressed],
        []
    );

    //Открытие диалога ввода URL сервера (только в режиме "Не подключено")
    const handleOpenServerUrlDialog = React.useCallback(() => {
        if (!isServerUrlEditable) {
            return;
        }
        setIsServerUrlDialogVisible(true);
    }, [isServerUrlEditable]);

    //Закрытие диалога ввода URL сервера
    const handleCloseServerUrlDialog = React.useCallback(() => {
        setIsServerUrlDialogVisible(false);
    }, []);

    //Сохранение настроек сервера
    const handleSaveServerUrl = React.useCallback(
        async url => {
            setIsServerUrlDialogVisible(false);
            setIsLoading(true);

            const valueToSave = url != null ? String(url).trim() : '';

            try {
                const success = await setSetting(AUTH_SETTINGS_KEYS.SERVER_URL, valueToSave);

                if (success) {
                    setServerUrl(valueToSave);
                    showSuccess('Настройки сервера сохранены');
                } else {
                    showError('Не удалось сохранить настройки');
                }
            } catch (error) {
                console.error('Ошибка сохранения настроек:', error);
                showError('Не удалось сохранить настройки');
            }

            setIsLoading(false);
        },
        [setSetting, showError, showSuccess]
    );

    //Переключатель скрытия URL сервера в окне логина
    const handleToggleHideServerUrl = React.useCallback(
        async value => {
            try {
                const success = await setSetting(AUTH_SETTINGS_KEYS.HIDE_SERVER_URL, value ? 'true' : 'false');

                if (success) {
                    setHideServerUrl(value);
                    showSuccess('Настройка сохранена');
                } else {
                    showError('Не удалось сохранить настройку');
                }
            } catch (error) {
                console.error('Ошибка сохранения настройки:', error);
                showError('Не удалось сохранить настройку');
            }
        },
        [setSetting, showSuccess, showError]
    );

    //Открытие диалога ввода времени простоя
    const handleOpenIdleTimeoutDialog = React.useCallback(() => {
        setIsIdleTimeoutDialogVisible(true);
    }, []);

    //Закрытие диалога ввода времени простоя
    const handleCloseIdleTimeoutDialog = React.useCallback(() => {
        setIsIdleTimeoutDialogVisible(false);
    }, []);

    //Сохранение времени простоя
    const handleSaveIdleTimeout = React.useCallback(
        async value => {
            setIsIdleTimeoutDialogVisible(false);
            setIsLoading(true);

            try {
                const trimmedValue = value ? value.trim() : '';
                const success = await setSetting(AUTH_SETTINGS_KEYS.IDLE_TIMEOUT, trimmedValue);

                if (success) {
                    setIdleTimeout(trimmedValue);
                    showSuccess('Время простоя сохранено');
                } else {
                    showError('Не удалось сохранить настройку');
                }
            } catch (error) {
                console.error('Ошибка сохранения времени простоя:', error);
                showError('Не удалось сохранить настройку');
            }

            setIsLoading(false);
        },
        [setSetting, showSuccess, showError]
    );

    //Выполнение очистки кэша (для диалога подтверждения)
    const performClearCache = React.useCallback(async () => {
        try {
            const success = await clearInspections();
            if (success) {
                showSuccess('Кэш успешно очищен');
            } else {
                showError('Не удалось очистить кэш');
            }
        } catch (error) {
            console.error('Ошибка очистки кэша:', error);
            showError('Не удалось очистить кэш');
        }
    }, [showSuccess, showError, clearInspections]);

    //Очистка кэша (осмотров)
    const handleClearCache = React.useCallback(() => {
        const confirmButton = getConfirmButtonOptions(DIALOG_BUTTON_TYPE.ERROR, 'Очистить', performClearCache);

        showInfo('Очистить кэш приложения?', {
            title: 'Подтверждение',
            buttons: [DIALOG_CANCEL_BUTTON, confirmButton]
        });
    }, [showInfo, performClearCache]);

    //Выполнение сброса настроек (для диалога подтверждения)
    //Подключён (онлайн/офлайн): сбрасываем только непричастные к подключению настройки; не подключён: полный сброс
    const performResetSettings = React.useCallback(async () => {
        try {
            const defaultValue = String(DEFAULT_IDLE_TIMEOUT);

            if (mode === APP_MODE.NOT_CONNECTED) {
                const success = await clearSettings();
                if (success) {
                    setServerUrl('');
                    setHideServerUrl(false);
                    setIdleTimeout(defaultValue);
                    await setSetting(AUTH_SETTINGS_KEYS.IDLE_TIMEOUT, defaultValue);
                    setNotConnected();
                    showSuccess('Настройки сброшены');
                } else {
                    showError('Не удалось сбросить настройки');
                }
            } else {
                //Подключён (онлайн или офлайн): сбрасываем только время простоя
                await setSetting(AUTH_SETTINGS_KEYS.IDLE_TIMEOUT, defaultValue);
                setIdleTimeout(defaultValue);
                showSuccess('Настройки сброшены');
            }
        } catch (error) {
            console.error('Ошибка сброса настроек:', error);
            showError('Не удалось сбросить настройки');
        }
    }, [
        mode,
        APP_MODE.NOT_CONNECTED,
        setServerUrl,
        setHideServerUrl,
        setIdleTimeout,
        setNotConnected,
        clearSettings,
        setSetting,
        showSuccess,
        showError
    ]);

    //Сброс настроек: при подключении (онлайн/офлайн) — без настроек подключения; при отсутствии подключения — все настройки
    const handleResetSettings = React.useCallback(() => {
        const confirmButton = getConfirmButtonOptions(DIALOG_BUTTON_TYPE.WARNING, 'Сбросить', performResetSettings);

        showInfo('Сбросить все настройки к значениям по умолчанию?', {
            title: 'Подтверждение сброса',
            buttons: [DIALOG_CANCEL_BUTTON, confirmButton]
        });
    }, [showInfo, performResetSettings]);

    //Оптимизация базы данных
    const handleOptimizeDb = React.useCallback(async () => {
        setIsLoading(true);
        try {
            const success = await vacuum();
            if (success) {
                showSuccess('База данных оптимизирована');
            } else {
                showError('Не удалось оптимизировать базу данных');
            }
        } catch (error) {
            console.error('Ошибка оптимизации БД:', error);
            showError('Не удалось оптимизировать базу данных');
        } finally {
            setIsLoading(false);
        }
    }, [vacuum, showSuccess, showError]);

    //Информация о приложении
    const handleShowAppInfo = React.useCallback(() => {
        const appInfo = getAppInfo({
            mode,
            serverUrl,
            isDbReady
        });

        showInfo(appInfo, {
            title: 'Информация о приложении'
        });
    }, [mode, serverUrl, isDbReady, showInfo]);

    //Обработчик кнопки назад
    const handleBackPress = React.useCallback(() => {
        if (canGoBack) {
            goBack();
        }
    }, [canGoBack, goBack]);

    //Обработчик копирования адреса сервера
    const handleCopyServerUrl = React.useCallback(() => {
        showSuccess('Адрес сервера скопирован');
    }, [showSuccess]);

    //Обработчик ошибки копирования
    const handleCopyError = React.useCallback(() => {
        showError('Не удалось скопировать адрес');
    }, [showError]);

    //Обработчик копирования идентификатора устройства
    const handleCopyDeviceId = React.useCallback(() => {
        showSuccess('Идентификатор устройства скопирован');
    }, [showSuccess]);

    return (
        <AdaptiveView padding={false}>
            <AppHeader showBackButton={true} onBackPress={handleBackPress} showMenuButton={false} />

            <ScrollView style={styles.scrollView} contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false}>
                {isAuthenticated && session ? (
                    <View style={styles.section}>
                        <AppText style={styles.sectionTitle} variant="h3" weight="semibold">
                            Информация о подключении
                        </AppText>

                        <View style={styles.infoRow}>
                            <AppText style={styles.infoLabel} variant="body">
                                Имя пользователя:
                            </AppText>
                            <AppText style={styles.infoValue} variant="body" weight="medium">
                                {session.userName || session.userCode || 'Не указано'}
                            </AppText>
                        </View>

                        <View style={styles.infoRow}>
                            <AppText style={styles.infoLabel} variant="body">
                                Организация:
                            </AppText>
                            <AppText style={styles.infoValue} variant="body" weight="medium">
                                {session.companyName || 'Не указана'}
                            </AppText>
                        </View>
                    </View>
                ) : null}

                <View style={styles.section}>
                    <AppText style={styles.sectionTitle} variant="h3" weight="semibold">
                        Сервер приложений
                    </AppText>

                    <AppText style={styles.fieldLabel} variant="caption" weight="medium">
                        URL сервера
                    </AppText>

                    <View style={styles.serverUrlRow}>
                        <Pressable style={getServerUrlFieldPressableStyle} onPress={handleOpenServerUrlDialog} disabled={!isServerUrlEditable}>
                            <AppText
                                style={[
                                    styles.serverUrlText,
                                    !serverUrl && styles.serverUrlPlaceholder,
                                    !isServerUrlEditable && styles.serverUrlTextDisabled
                                ]}
                                numberOfLines={1}
                            >
                                {serverUrl || 'Нажмите для ввода адреса'}
                            </AppText>
                        </Pressable>

                        {serverUrl ? (
                            <CopyButton value={serverUrl} onCopy={handleCopyServerUrl} onError={handleCopyError} style={styles.serverUrlCopyButton} />
                        ) : null}
                    </View>

                    <View style={styles.switchRow}>
                        <AppSwitch
                            label="Не отображать адрес сервера в окне логина"
                            value={hideServerUrl}
                            onValueChange={handleToggleHideServerUrl}
                            disabled={isLoading || !isDbReady}
                        />
                    </View>
                </View>

                <View style={styles.section}>
                    <AppText style={styles.sectionTitle} variant="h3" weight="semibold">
                        Системные настройки
                    </AppText>

                    <AppText style={styles.fieldLabel} variant="caption" weight="medium">
                        Максимальное время простоя (минут)
                    </AppText>

                    <Pressable style={getIdleTimeoutFieldPressableStyle} onPress={handleOpenIdleTimeoutDialog} disabled={isLoading || !isDbReady}>
                        <AppText style={styles.serverUrlText} numberOfLines={1}>
                            {idleTimeout || String(DEFAULT_IDLE_TIMEOUT)}
                        </AppText>
                    </Pressable>

                    <AppText style={[styles.fieldLabel, styles.fieldLabelMarginTop]} variant="caption" weight="medium">
                        Идентификатор устройства
                    </AppText>

                    <View style={styles.serverUrlRow}>
                        <View style={[styles.serverUrlField, styles.deviceIdField]}>
                            <AppText style={styles.serverUrlText} numberOfLines={1}>
                                {deviceId || 'Загрузка...'}
                            </AppText>
                        </View>

                        {deviceId ? (
                            <CopyButton value={deviceId} onCopy={handleCopyDeviceId} onError={handleCopyError} style={styles.serverUrlCopyButton} />
                        ) : null}
                    </View>
                </View>

                <View style={styles.section}>
                    <AppText style={styles.sectionTitle} variant="h3" weight="semibold">
                        Управление данными
                    </AppText>

                    <AppButton
                        title="Очистить кэш"
                        onPress={handleClearCache}
                        disabled={!isDbReady}
                        style={[styles.actionButton, styles.clearCacheButton]}
                        textStyle={styles.clearCacheButtonText}
                    />

                    <AppButton
                        title="Сбросить настройки"
                        onPress={handleResetSettings}
                        disabled={!isDbReady}
                        style={[styles.actionButton, styles.resetButton]}
                        textStyle={styles.resetButtonText}
                    />

                    <AppButton
                        title="Оптимизировать БД"
                        onPress={handleOptimizeDb}
                        disabled={isLoading || !isDbReady}
                        style={[styles.actionButton, styles.optimizeButton]}
                        textStyle={styles.optimizeButtonText}
                    />
                </View>

                <View style={styles.section}>
                    <AppText style={styles.sectionTitle} variant="h3" weight="semibold">
                        Информация
                    </AppText>

                    <AppButton title="О приложении" onPress={handleShowAppInfo} style={[styles.actionButton, styles.infoButton]} />

                    <View style={styles.infoRow}>
                        <AppText style={styles.infoLabel} variant="body">
                            Текущий режим:
                        </AppText>
                        <AppText style={styles.infoValue} variant="body" weight="medium">
                            {getModeLabel(mode)}
                        </AppText>
                    </View>

                    <View style={styles.infoRow}>
                        <AppText style={styles.infoLabel} variant="body">
                            Адрес сервера:
                        </AppText>
                        <View style={styles.infoValueWithAction}>
                            <AppText style={styles.infoValueFlex} variant="body" weight="medium" numberOfLines={1}>
                                {serverUrl || 'Не настроен'}
                            </AppText>
                            {serverUrl ? (
                                <CopyButton value={serverUrl} onCopy={handleCopyServerUrl} onError={handleCopyError} style={styles.copyButton} />
                            ) : null}
                        </View>
                    </View>

                    <View style={styles.infoRow}>
                        <AppText style={styles.infoLabel} variant="body">
                            База данных:
                        </AppText>
                        <AppText style={styles.infoValue} variant="body" weight="medium">
                            {isDbReady ? 'Готова' : 'Загрузка...'}
                        </AppText>
                    </View>
                </View>
            </ScrollView>

            <InputDialog
                visible={isServerUrlDialogVisible}
                title="Адрес сервера"
                label="URL сервера приложений"
                value={serverUrl}
                placeholder="https://example.com/api"
                keyboardType="url"
                confirmText="Сохранить"
                cancelText="Отмена"
                onConfirm={handleSaveServerUrl}
                onCancel={handleCloseServerUrlDialog}
                validator={validateServerUrlAllowEmpty}
            />

            <InputDialog
                visible={isIdleTimeoutDialogVisible}
                title="Время простоя"
                label="Максимальное время простоя (минут)"
                value={idleTimeout}
                placeholder="Например: 30"
                keyboardType="numeric"
                confirmText="Сохранить"
                cancelText="Отмена"
                onConfirm={handleSaveIdleTimeout}
                onCancel={handleCloseIdleTimeoutDialog}
                validator={validateIdleTimeout}
            />
        </AdaptiveView>
    );
}

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

module.exports = SettingsScreen;
