/**
 * JavaScript для страницы настройки приложения
 */
document.addEventListener('DOMContentLoaded', function() {
    // Инициализация статуса настроек
    updateSetupStatus();
    
    // Обработка выбора типа базы данных
    const dbDriverSelect = document.getElementById('db-driver');
    const serverSettings = document.querySelectorAll('.server-settings');
    
    dbDriverSelect.addEventListener('change', function() {
        if (this.value === 'sqlite') {
            // Скрываем настройки сервера для SQLite
            serverSettings.forEach(el => el.style.display = 'none');
        } else {
            // Показываем настройки сервера для других БД
            serverSettings.forEach(el => el.style.display = '');
            
            // Обновляем порт по умолчанию в зависимости от выбранной БД
            const dbPortInput = document.getElementById('db-port');
            if (this.value === 'mysql') {
                dbPortInput.value = '3306';
            } else if (this.value === 'postgresql') {
                dbPortInput.value = '5432';
            }
        }
    });
    
    // Обработка формы настройки базы данных
    const databaseForm = document.getElementById('database-form');
    databaseForm.addEventListener('submit', function(e) {
        e.preventDefault();
        testDatabaseConnection();
    });
    
    // Обработка кнопки проверки соединения с БД
    const testDbConnectionBtn = document.getElementById('test-db-connection');
    testDbConnectionBtn.addEventListener('click', function() {
        testDatabaseConnection();
    });
    
    // Обработка формы создания администратора
    const adminForm = document.getElementById('admin-form');
    adminForm.addEventListener('submit', function(e) {
        e.preventDefault();
        createAdmin();
    });
    
    // Обработка формы настроек приложения
    const appForm = document.getElementById('app-form');
    appForm.addEventListener('submit', function(e) {
        e.preventDefault();
        saveAppSettings();
    });
    
    // Обработка кнопки завершения настройки
    const completeSetupBtn = document.getElementById('complete-setup');
    completeSetupBtn.addEventListener('click', function() {
        completeSetup();
    });
    
    // Загрузка существующих настроек при открытии страницы
    loadDatabaseSettings();
    loadAppSettings();
    refreshSetupStatusFromServer(true);
});

/** Состояние прохождения шагов мастера (синхронизируется с /api/setup/status) */
const setupWizardState = {
    dbVerified: false,
    adminCreated: false,
    appConfigured: false,
};

let pendingTabSwitchTimer = null;
let statusUpdateInProgress = false;
let lastStatusUpdateTime = 0;
const MIN_STATUS_UPDATE_INTERVAL = 5000;

/**
 * Переключает вкладку мастера, отменяя предыдущие отложенные переходы.
 * @param {string} tabId - id кнопки вкладки (database-tab, admin-tab, app-tab)
 * @param {number} delayMs - задержка перед переключением
 */
function switchSetupTab(tabId, delayMs = 0) {
    if (pendingTabSwitchTimer) {
        clearTimeout(pendingTabSwitchTimer);
        pendingTabSwitchTimer = null;
    }

    const activateTab = () => {
        const tabEl = document.getElementById(tabId);
        if (!tabEl || tabEl.disabled) {
            return;
        }
        if (window.bootstrap && window.bootstrap.Tab) {
            window.bootstrap.Tab.getOrCreateInstance(tabEl).show();
        } else {
            tabEl.click();
        }
    };

    if (delayMs > 0) {
        pendingTabSwitchTimer = setTimeout(() => {
            pendingTabSwitchTimer = null;
            activateTab();
        }, delayMs);
        return;
    }

    activateTab();
}

/**
 * Обновляет доступность вкладок и кнопки завершения настройки.
 */
function updateWizardControls() {
    const adminTab = document.getElementById('admin-tab');
    const appTab = document.getElementById('app-tab');
    const completeButton = document.getElementById('complete-setup');

    adminTab.disabled = !setupWizardState.dbVerified;
    appTab.disabled = !setupWizardState.adminCreated;

    const readyToComplete = (
        setupWizardState.dbVerified
        && setupWizardState.adminCreated
        && setupWizardState.appConfigured
    );
    completeButton.disabled = !readyToComplete;
    completeButton.title = readyToComplete
        ? ''
        : 'Завершите все шаги мастера настройки';
}

/**
 * Применяет статус шагов к индикаторам в UI.
 * @param {Object} status - ответ /api/setup/status
 */
function applySetupStatusUI(status) {
    setupWizardState.dbVerified = Boolean(status.db_connected);
    setupWizardState.adminCreated = Boolean(status.admin_exists);
    setupWizardState.appConfigured = Boolean(status.app_configured);

    const dbStatusIcon = document.getElementById('db-status-icon');
    const dbStatusBadge = document.getElementById('db-status-badge');
    const adminStatusIcon = document.getElementById('admin-status-icon');
    const adminStatusBadge = document.getElementById('admin-status-badge');
    const appStatusIcon = document.getElementById('app-status-icon');
    const appStatusBadge = document.getElementById('app-status-badge');

    if (status.db_connected) {
        dbStatusIcon.className = 'bi bi-database-check status-icon text-success';
        dbStatusBadge.className = 'badge bg-success';
        dbStatusBadge.textContent = 'Подключено';
    } else if (status.db_configured) {
        dbStatusIcon.className = 'bi bi-database-x status-icon text-warning';
        dbStatusBadge.className = 'badge bg-warning';
        dbStatusBadge.textContent = 'Ошибка подключения';
    } else {
        dbStatusIcon.className = 'bi bi-database-dash status-icon text-danger';
        dbStatusBadge.className = 'badge bg-danger';
        dbStatusBadge.textContent = 'Не настроено';
    }

    if (status.admin_exists) {
        adminStatusIcon.className = 'bi bi-person-check-fill status-icon text-success';
        adminStatusBadge.className = 'badge bg-success';
        adminStatusBadge.textContent = 'Создан';
    } else {
        adminStatusIcon.className = 'bi bi-person-x status-icon text-warning';
        adminStatusBadge.className = 'badge bg-warning';
        adminStatusBadge.textContent = 'Не создан';
    }

    if (status.app_configured) {
        appStatusIcon.className = 'bi bi-gear-fill status-icon text-success';
        appStatusBadge.className = 'badge bg-success';
        appStatusBadge.textContent = 'Настроено';
    } else {
        appStatusIcon.className = 'bi bi-gear status-icon text-warning';
        appStatusBadge.className = 'badge bg-warning';
        appStatusBadge.textContent = 'Не настроено';
    }

    updateWizardControls();
}

/**
 * Запрашивает агрегированный статус мастера с сервера (без сохранения формы и без смены вкладок).
 * @param {boolean} force - принудительное обновление
 * @returns {Promise<Object|null>}
 */
function refreshSetupStatusFromServer(force = false) {
    const currentTime = Date.now();
    if (statusUpdateInProgress || (!force && currentTime - lastStatusUpdateTime < MIN_STATUS_UPDATE_INTERVAL)) {
        return Promise.resolve(null);
    }

    statusUpdateInProgress = true;
    lastStatusUpdateTime = currentTime;

    return fetch('/api/setup/status')
        .then(response => {
            if (!response.ok) {
                throw new Error(`Ошибка HTTP: ${response.status}`);
            }
            return response.json();
        })
        .then(status => {
            if (status && status.success !== false) {
                applySetupStatusUI(status);
            }
            return status;
        })
        .catch(error => {
            console.error('Ошибка при получении статуса настройки:', error);
            return null;
        })
        .finally(() => {
            setTimeout(() => {
                statusUpdateInProgress = false;
            }, 1000);
        });
}

/** @deprecated Используйте refreshSetupStatusFromServer — не переключает вкладки */
function updateSetupStatus(force = false) {
    return refreshSetupStatusFromServer(force);
}

/**
 * Сохранение настроек базы данных
 * @param {Object} options - параметры сохранения
 * @param {boolean} options.showUi - показывать индикатор и результат в UI
 * @param {boolean} options.updateStatus - обновлять общий статус настройки
 * @returns {Promise} - промис, который разрешается при завершении сохранения
 */
function saveDatabaseSettings(options = {}) {
    const { showUi = true, updateStatus = true } = options;
    const dbConfig = collectDatabaseConfigFromForm();
    const resultDiv = document.querySelector('.connection-result');
    const alertDiv = resultDiv.querySelector('.alert');

    if (showUi) {
        resultDiv.style.display = 'block';
        alertDiv.className = 'alert alert-info';
        alertDiv.innerHTML = '<div class="spinner-border spinner-border-sm me-2" role="status"></div> Сохранение настроек...';
    }
    
    // Отправляем запрос на сервер и возвращаем промис
    return fetch('/api/db/config', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(dbConfig)
    })
    .then(response => {
        if (!response.ok) {
            throw new Error(`Ошибка HTTP: ${response.status}`);
        }
        return response.json();
    })
    .then(data => {
        if (showUi) {
            resultDiv.style.display = 'block';

            if (data.success) {
                alertDiv.className = 'alert alert-success';
                alertDiv.innerHTML = '<i class="bi bi-check-circle me-2"></i> Настройки базы данных успешно сохранены';
            } else {
                alertDiv.className = 'alert alert-danger';
                alertDiv.innerHTML = '<i class="bi bi-exclamation-triangle me-2"></i> ' + (data.message || 'Ошибка при сохранении настроек базы данных');
            }

            setTimeout(() => {
                resultDiv.style.display = 'none';
            }, 5000);
        }

        if (data.success && updateStatus) {
            refreshSetupStatusFromServer(true);
        }

        return data;
    })
    .catch(error => {
        console.error('Ошибка сохранения настроек БД:', error);

        if (showUi) {
            resultDiv.style.display = 'block';
            alertDiv.className = 'alert alert-danger';
            alertDiv.innerHTML = '<i class="bi bi-exclamation-triangle me-2"></i> Ошибка при отправке запроса: ' + error.message;

            setTimeout(() => {
                resultDiv.style.display = 'none';
            }, 5000);
        }

        throw error;
    });
}

/**
 * Собирает конфигурацию БД из формы
 * @returns {Object}
 */
function collectDatabaseConfigFromForm() {
    const form = document.getElementById('database-form');
    const formData = new FormData(form);
    const dbConfig = {};

    for (const [key, value] of formData.entries()) {
        dbConfig[key] = value;
    }

    if (dbConfig.port) {
        dbConfig.port = parseInt(dbConfig.port, 10);
    }

    if (dbConfig.driver === 'sqlite') {
        dbConfig.host = 'localhost';
        dbConfig.username = '';
        dbConfig.password = '';
    }

    return dbConfig;
}

/**
 * Проверка соединения с базой данных
 * @param {boolean} silent - если true, не будет показывать UI уведомления и переход на следующий шаг
 * @returns {Promise} - промис, который разрешается с результатом подключения
 */
function testDatabaseConnection(silent = false) {
    const dbConfig = collectDatabaseConfigFromForm();
    const resultDiv = document.querySelector('.connection-result');
    const alertDiv = resultDiv.querySelector('.alert');

    if (!silent) {
        resultDiv.style.display = 'block';
        alertDiv.className = 'alert alert-info';
        alertDiv.innerHTML = '<div class="spinner-border spinner-border-sm me-2" role="status"></div> Проверка соединения...';
    }

    return saveDatabaseSettings({ showUi: false, updateStatus: false })
        .then(saveResult => {
            if (!saveResult.success) {
                if (!silent) {
                    resultDiv.style.display = 'block';
                    alertDiv.className = 'alert alert-danger';
                    alertDiv.innerHTML = '<i class="bi bi-exclamation-triangle me-2"></i> ' + (saveResult.message || 'Ошибка при сохранении настроек базы данных');
                }
                return saveResult;
            }

            return fetch('/api/db/test', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(dbConfig)
            })
            .then(response => {
                if (!response.ok) {
                    throw new Error(`Ошибка HTTP: ${response.status}`);
                }
                return response.json();
            })
            .then(data => {
                if (!silent) {
                    resultDiv.style.display = 'block';

                    if (data.success) {
                        alertDiv.className = 'alert alert-success';
                        alertDiv.innerHTML = '<i class="bi bi-check-circle me-2"></i> Соединение с базой данных успешно установлено';
                        setupWizardState.dbVerified = true;
                        updateWizardControls();
                        refreshSetupStatusFromServer(true);
                        switchSetupTab('admin-tab', 1500);
                    } else {
                        alertDiv.className = 'alert alert-danger';
                        alertDiv.innerHTML = '<i class="bi bi-exclamation-triangle me-2"></i> ' + (data.message || 'Ошибка соединения с базой данных');
                    }

                    setTimeout(() => {
                        resultDiv.style.display = 'none';
                    }, 5000);
                }

                return data;
            });
        })
        .catch(error => {
            console.error('Ошибка проверки соединения:', error);

            if (!silent) {
                resultDiv.style.display = 'block';
                alertDiv.className = 'alert alert-danger';
                alertDiv.innerHTML = '<i class="bi bi-exclamation-triangle me-2"></i> Ошибка при отправке запроса: ' + error.message;

                setTimeout(() => {
                    resultDiv.style.display = 'none';
                }, 5000);
            }

            return { success: false, message: error.message };
        });
}

/**
 * Создание администратора
 */
function createAdmin() {
    const form = document.getElementById('admin-form');
    const formData = new FormData(form);
    const adminData = {};
    
    // Валидация формы
    const password = formData.get('password');
    const passwordConfirm = formData.get('password_confirm');
    
    if (password !== passwordConfirm) {
        const resultDiv = document.querySelector('.admin-result');
        const alertDiv = resultDiv.querySelector('.alert');
        
        resultDiv.style.display = 'block';
        alertDiv.className = 'alert alert-danger';
        alertDiv.innerHTML = '<i class="bi bi-exclamation-triangle me-2"></i> Пароли не совпадают';
        
        return;
    }
    
    // Показываем индикатор загрузки
    const resultDiv = document.querySelector('.admin-result');
    const alertDiv = resultDiv.querySelector('.alert');
    resultDiv.style.display = 'block';
    alertDiv.className = 'alert alert-info';
    alertDiv.innerHTML = '<div class="spinner-border spinner-border-sm me-2" role="status"></div> Создание администратора...';
    
    // Преобразуем данные формы в объект
    for (const [key, value] of formData.entries()) {
        if (key !== 'password_confirm') {
            adminData[key] = value;
        }
    }
    
    // Отправляем запрос на сервер
    fetch('/api/admin/create', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(adminData)
    })
    .then(response => {
        // Проверяем, что ответ пришел в формате JSON
        if (!response.ok) {
            throw new Error(`Ошибка HTTP: ${response.status}`);
        }
        return response.json();
    })
    .then(data => {
        const resultDiv = document.querySelector('.admin-result');
        const alertDiv = resultDiv.querySelector('.alert');
        
        resultDiv.style.display = 'block';
        
        if (data.success) {
            alertDiv.className = 'alert alert-success';
            alertDiv.innerHTML = '<i class="bi bi-check-circle me-2"></i> Администратор успешно создан';

            setupWizardState.adminCreated = true;
            updateWizardControls();
            refreshSetupStatusFromServer(true);
            switchSetupTab('app-tab', 1500);
        } else {
            alertDiv.className = 'alert alert-danger';
            alertDiv.innerHTML = '<i class="bi bi-exclamation-triangle me-2"></i> ' + (data.message || 'Ошибка при создании администратора');
            
            // Выводим сообщение в консоль для отладки
            console.error('Ошибка создания администратора:', data);
        }
    })
    .catch(error => {
        console.error('Ошибка запроса:', error);
        
        const resultDiv = document.querySelector('.admin-result');
        const alertDiv = resultDiv.querySelector('.alert');
        
        resultDiv.style.display = 'block';
        alertDiv.className = 'alert alert-danger';
        alertDiv.innerHTML = '<i class="bi bi-exclamation-triangle me-2"></i> Ошибка при отправке запроса: ' + error.message;
        
        // Останавливаем процесс обновления статуса, чтобы прервать возможный цикл
        setTimeout(() => {
            // Скрываем сообщение через некоторое время
            resultDiv.style.display = 'none';
        }, 5000);
    });
}

/**
 * Загрузка существующих настроек БД
 */
function loadDatabaseSettings() {
    fetch('/api/db/config')
    .then(response => response.json())
    .then(data => {
        // Заполняем форму значениями из конфигурации
        const form = document.getElementById('database-form');
        
        // Установка типа БД
        if (data.driver) {
            const driverSelect = form.querySelector('[name="driver"]');
            driverSelect.value = data.driver;
            
            // Триггерим событие изменения, чтобы обновить видимость полей
            const event = new Event('change');
            driverSelect.dispatchEvent(event);
        }
        
        // Заполняем остальные поля (пароль приложения не подставляем; root_password приходит пустым)
        for (const key in data) {
            const input = form.querySelector(`[name="${key}"]`);
            if (input && key !== 'driver' && key !== 'password') {
                input.value = data[key] != null ? data[key] : '';
            }
        }
    })
    .catch(error => {
        console.error('Ошибка при загрузке настроек БД:', error);
    });
}

/**
 * Сохранение настроек приложения
 */
function saveAppSettings() {
    const form = document.getElementById('app-form');
    const formData = new FormData(form);
    const appSettings = {};
    
    // Показываем индикатор загрузки
    const resultDiv = document.querySelector('.settings-result');
    const alertDiv = resultDiv.querySelector('.alert');
    resultDiv.style.display = 'block';
    alertDiv.className = 'alert alert-info';
    alertDiv.innerHTML = '<div class="spinner-border spinner-border-sm me-2" role="status"></div> Сохранение настроек...';
    
    // Преобразуем данные формы в объект с поддержкой вложенных ключей
    for (const [key, value] of formData.entries()) {
        if (key.includes('.')) {
            // Разделяем вложенные ключи (например, "app.name" -> { app: { name: value } })
            const parts = key.split('.');
            let current = appSettings;
            
            for (let i = 0; i < parts.length - 1; i++) {
                if (!current[parts[i]]) {
                    current[parts[i]] = {};
                }
                current = current[parts[i]];
            }
            
            current[parts[parts.length - 1]] = value;
        } else {
            appSettings[key] = value;
        }
    }
    
    // Преобразуем порт веб-сервера в число
    if (appSettings.web && appSettings.web.port) {
        appSettings.web.port = parseInt(appSettings.web.port, 10);
    }
    
    // Отправляем запрос на сервер
    fetch('/api/app/settings', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(appSettings)
    })
    .then(response => response.json())
    .then(data => {
        const resultDiv = document.querySelector('.settings-result');
        const alertDiv = resultDiv.querySelector('.alert');
        
        resultDiv.style.display = 'block';
        
        if (data.success) {
            alertDiv.className = 'alert alert-success';
            alertDiv.innerHTML = '<i class="bi bi-check-circle me-2"></i> Настройки приложения успешно сохранены';

            setupWizardState.appConfigured = true;
            updateWizardControls();
            refreshSetupStatusFromServer(true);
        } else {
            alertDiv.className = 'alert alert-danger';
            alertDiv.innerHTML = '<i class="bi bi-exclamation-triangle me-2"></i> ' + (data.message || 'Ошибка при сохранении настроек приложения');
        }
        
        // Скрываем сообщение через 5 секунд
        setTimeout(() => {
            resultDiv.style.display = 'none';
        }, 5000);
    })
    .catch(error => {
        const resultDiv = document.querySelector('.settings-result');
        const alertDiv = resultDiv.querySelector('.alert');
        
        resultDiv.style.display = 'block';
        alertDiv.className = 'alert alert-danger';
        alertDiv.innerHTML = '<i class="bi bi-exclamation-triangle me-2"></i> Ошибка при отправке запроса: ' + error.message;
        
        // Скрываем сообщение через 5 секунд
        setTimeout(() => {
            resultDiv.style.display = 'none';
        }, 5000);
    });
}

/**
 * Загрузка существующих настроек приложения
 */
function loadAppSettings() {
    fetch('/api/app/settings')
    .then(response => response.json())
    .then(data => {
        const form = document.getElementById('app-form');
        
        // Заполняем форму значениями из конфигурации
        // Обрабатываем вложенные объекты
        function processObject(obj, prefix = '') {
            for (const key in obj) {
                const value = obj[key];
                
                if (typeof value === 'object' && value !== null) {
                    // Рекурсивно обрабатываем вложенные объекты
                    processObject(value, prefix ? `${prefix}.${key}` : key);
                } else {
                    // Заполняем поле формы
                    const fieldName = prefix ? `${prefix}.${key}` : key;
                    const input = form.querySelector(`[name="${fieldName}"]`);
                    
                    if (input) {
                        input.value = value;
                    }
                }
            }
        }
        
        processObject(data);
    })
    .catch(error => {
        console.error('Ошибка при загрузке настроек приложения:', error);
    });
}

/**
 * Показывает Bootstrap-модальное окно мастера настройки.
 * @param {Object} options
 * @returns {Promise<boolean>} resolve(true) при подтверждении
 */
function showSetupModal(options) {
    const {
        title = 'Настройка приложения',
        bodyHtml = '',
        confirmText = 'Продолжить',
        cancelText = 'Отмена',
        confirmClass = 'btn-primary',
        showCancel = true,
        onConfirm = null,
    } = options;

    return new Promise((resolve) => {
        const modalElement = document.getElementById('setup-modal');
        const modalTitle = document.getElementById('setup-modal-title');
        const modalBody = document.getElementById('setup-modal-body');
        const modalConfirm = document.getElementById('setup-modal-confirm');
        const modalCancel = document.getElementById('setup-modal-cancel');
        const modal = bootstrap.Modal.getOrCreateInstance(modalElement);

        modalTitle.textContent = title;
        modalBody.innerHTML = bodyHtml;
        modalConfirm.textContent = confirmText;
        modalConfirm.className = `btn ${confirmClass}`;
        modalCancel.textContent = cancelText;
        modalCancel.style.display = showCancel ? '' : 'none';

        const cleanup = () => {
            modalConfirm.onclick = null;
            modalCancel.onclick = null;
            modalElement.removeEventListener('hidden.bs.modal', onHidden);
        };

        const onHidden = () => {
            cleanup();
            resolve(false);
        };

        modalConfirm.onclick = () => {
            cleanup();
            modal.hide();
            if (typeof onConfirm === 'function') {
                onConfirm();
            }
            resolve(true);
        };

        modalCancel.onclick = () => {
            cleanup();
            modal.hide();
            resolve(false);
        };

        modalElement.addEventListener('hidden.bs.modal', onHidden, { once: true });
        modal.show();
    });
}

/**
 * Ожидает готовности основного приложения и выполняет переход на login.
 * @param {string} loginUrl
 * @param {Function} onProgress
 */
function waitForMainAppAndRedirect(loginUrl, onProgress) {
    let attempts = 0;
    const maxAttempts = 45;

    const tryRedirect = () => {
        attempts += 1;
        if (typeof onProgress === 'function') {
            onProgress(attempts, maxAttempts);
        }

        fetch(loginUrl, { method: 'GET', cache: 'no-store', redirect: 'follow' })
            .then(response => {
                if (response.ok || response.redirected) {
                    window.location.href = loginUrl;
                    return;
                }
                scheduleNext();
            })
            .catch(() => scheduleNext());
    };

    const scheduleNext = () => {
        if (attempts >= maxAttempts) {
            return;
        }
        setTimeout(tryRedirect, 1000);
    };

    setTimeout(tryRedirect, 1500);
}

/**
 * Завершение настройки приложения
 */
function completeSetup() {
    if (!setupWizardState.dbVerified || !setupWizardState.adminCreated || !setupWizardState.appConfigured) {
        showSetupModal({
            title: 'Шаги не завершены',
            bodyHtml: '<p class="mb-0">Завершите все шаги мастера: база данных, администратор и параметры приложения.</p>',
            confirmText: 'Понятно',
            showCancel: false,
            confirmClass: 'btn-primary',
        });
        return;
    }

    showSetupModal({
        title: 'Завершить настройку',
        bodyHtml: '<p class="mb-0">Настройки будут сохранены. После завершения будет запущено основное приложение (если это возможно на сервере).</p>',
        confirmText: 'Завершить',
        cancelText: 'Отмена',
        confirmClass: 'btn-success',
    }).then(confirmed => {
        if (!confirmed) {
            return;
        }

        const completeButton = document.getElementById('complete-setup');
        const originalButtonText = completeButton.innerHTML;
        completeButton.disabled = true;
        completeButton.innerHTML = '<div class="spinner-border spinner-border-sm me-2" role="status"></div> Завершение настройки...';

        fetch('/api/setup/complete', { method: 'POST' })
            .then(response => response.json())
            .then(data => {
                if (!data.success) {
                    showSetupModal({
                        title: 'Ошибка завершения',
                        bodyHtml: `<p class="mb-0">${escapeSetupHtml(data.message || 'Неизвестная ошибка')}</p>`,
                        confirmText: 'Закрыть',
                        showCancel: false,
                        confirmClass: 'btn-danger',
                    });
                    updateWizardControls();
                    completeButton.innerHTML = originalButtonText;
                    return;
                }

                handleSetupCompleteSuccess(data, completeButton, originalButtonText);
            })
            .catch(error => {
                showSetupModal({
                    title: 'Ошибка запроса',
                    bodyHtml: `<p class="mb-0">${escapeSetupHtml(error.message)}</p>`,
                    confirmText: 'Закрыть',
                    showCancel: false,
                    confirmClass: 'btn-danger',
                });
                updateWizardControls();
                completeButton.innerHTML = originalButtonText;
            });
    });
}

/**
 * Экранирует текст для безопасной вставки в HTML модального окна.
 * @param {string} value
 * @returns {string}
 */
function escapeSetupHtml(value) {
    return String(value)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;');
}

/**
 * Обрабатывает успешное завершение настройки.
 */
function handleSetupCompleteSuccess(data, completeButton, originalButtonText) {
    const detailsHtml = Array.isArray(data.details) && data.details.length
        ? `<ul class="mb-0 ps-3">${data.details.map(item => `<li>${escapeSetupHtml(item)}</li>`).join('')}</ul>`
        : '';

    if (data.redirect && data.login_url) {
        showSetupModal({
            title: 'Настройка завершена',
            bodyHtml: `
                <p class="mb-2">${escapeSetupHtml(data.message || 'Настройка успешно завершена.')}</p>
                <p class="mb-2" id="setup-launch-status">
                    <span class="spinner-border spinner-border-sm me-2" role="status"></span>
                    Ожидание запуска основного приложения...
                </p>
                ${detailsHtml}
            `,
            confirmText: 'Открыть вход',
            cancelText: 'Остаться здесь',
            confirmClass: 'btn-primary',
            onConfirm: () => {
                window.location.href = data.login_url;
            },
        });

        waitForMainAppAndRedirect(data.login_url, (attempt, maxAttempts) => {
            const statusEl = document.getElementById('setup-launch-status');
            if (statusEl) {
                statusEl.innerHTML = `
                    <span class="spinner-border spinner-border-sm me-2" role="status"></span>
                    Ожидание запуска основного приложения (${attempt}/${maxAttempts})...
                `;
            }
        });

        completeButton.innerHTML = '<i class="bi bi-check-circle"></i> Настройка завершена';
        return;
    }

    const manualCommand = data.manual_start_command
        ? `<p class="mb-2"><code>${escapeSetupHtml(data.manual_start_command)}</code></p>`
        : '';

    showSetupModal({
        title: 'Настройка сохранена',
        bodyHtml: `
            <p class="mb-2">${escapeSetupHtml(data.message || 'Настройка сохранена, но автозапуск не выполнен.')}</p>
            ${manualCommand}
            ${detailsHtml}
            <p class="mb-0 text-muted">После ручного запуска откройте страницу входа основного приложения.</p>
        `,
        confirmText: data.login_url ? 'Скопировать URL входа' : 'Закрыть',
        showCancel: false,
        confirmClass: 'btn-primary',
        onConfirm: () => {
            if (data.login_url && navigator.clipboard) {
                navigator.clipboard.writeText(data.login_url);
            }
        },
    });

    updateWizardControls();
    completeButton.disabled = true;
    completeButton.innerHTML = '<i class="bi bi-check-circle"></i> Настройка завершена';
}