(function () {
    window.AgentFrontendModules = window.AgentFrontendModules || {};

    window.AgentFrontendModules.createSetupWizardModule = function createSetupWizardModule(deps) {
        const totalSteps = 7;
        let currentStep = 0;

        function wireSetupToggle(toggle, fieldsId) {
            if (!toggle) return;
            const fields = document.getElementById(fieldsId);
            toggle.addEventListener('change', () => {
                if (fields) fields.style.display = toggle.checked ? 'block' : 'none';
            });
        }

        async function validateFolder() {
            const value = deps.refs.setupCustomDir?.value.trim();
            if (!value) {
                if (deps.refs.setupDirStatus) {
                    deps.refs.setupDirStatus.textContent = 'Enter a folder path first.';
                    deps.refs.setupDirStatus.className = 'setup-field-hint setup-dir-err';
                }
                return;
            }
            if (deps.refs.setupDirStatus) {
                deps.refs.setupDirStatus.textContent = 'Validating...';
                deps.refs.setupDirStatus.className = 'setup-field-hint';
            }
            try {
                const response = await deps.authFetch('/api/setup/validate-folder', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ path: value }),
                });
                const data = await response.json();
                if (data.ok) {
                    deps.refs.setupDirStatus.textContent = data.exists ? '✓ Folder exists and is writable' : '✓ Folder will be created';
                    deps.refs.setupDirStatus.className = 'setup-field-hint setup-dir-ok';
                } else {
                    deps.refs.setupDirStatus.textContent = '✗ ' + (data.error || 'Invalid path');
                    deps.refs.setupDirStatus.className = 'setup-field-hint setup-dir-err';
                }
            } catch (_) {
                if (deps.refs.setupDirStatus) {
                    deps.refs.setupDirStatus.textContent = '✗ Validation failed';
                    deps.refs.setupDirStatus.className = 'setup-field-hint setup-dir-err';
                }
            }
        }

        function setupGoToStep(step) {
            currentStep = Math.max(0, Math.min(totalSteps - 1, step));
            deps.refs.setupSteps.forEach((item) => item.classList.remove('active'));
            deps.refs.setupDots.forEach((dot, index) => {
                dot.classList.remove('active', 'done');
                if (index < currentStep) dot.classList.add('done');
                if (index === currentStep) dot.classList.add('active');
            });
            const activeStep = document.querySelector(`.setup-step[data-step="${currentStep}"]`);
            if (activeStep) activeStep.classList.add('active');

            const progress = ((currentStep + 1) / totalSteps) * 100;
            if (deps.refs.setupProgressBar) deps.refs.setupProgressBar.style.width = progress + '%';
            if (deps.refs.setupBackBtn) deps.refs.setupBackBtn.style.visibility = currentStep === 0 ? 'hidden' : 'visible';

            if (deps.refs.setupNextBtn) {
                if (currentStep === 0) {
                    deps.refs.setupNextBtn.innerHTML = 'Get Started <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>';
                } else if (currentStep === totalSteps - 1) {
                    deps.refs.setupNextBtn.innerHTML = '🚀 Launch AgentOrchestrator';
                } else {
                    deps.refs.setupNextBtn.innerHTML = 'Next <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>';
                }
            }

            if (currentStep === totalSteps - 1) buildSetupSummary();
        }

        function buildSetupSummary() {
            const summaryEl = document.getElementById('setup-summary');
            if (!summaryEl) return;
            const item = (label, ok) => `<div class="setup-summary-item"><span class="setup-summary-icon ${ok ? 'ok' : 'skip'}">${ok ? '✓' : '—'}</span>${label}</div>`;
            const chosenDir = deps.refs.setupCustomDir?.value.trim() || deps.refs.setupInstallDir?.value || '(current)';
            const openaiOk = deps.refs.setupOpenaiToggle?.checked && deps.refs.setupOpenaiKey?.value.trim();
            const geminiOk = deps.refs.setupGeminiToggle?.checked && deps.refs.setupGeminiKey?.value.trim();
            const nvidiaOk = deps.refs.setupNvidiaToggle?.checked && deps.refs.setupNvidiaKey?.value.trim();
            const braveOk = deps.refs.setupBraveToggle?.checked && deps.refs.setupBraveKey?.value.trim();
            const googleOk = deps.refs.setupGoogleToggle?.checked && deps.refs.setupGoogleClientId?.value.trim();
            const slackOk = deps.refs.setupSlackToggle?.checked && deps.refs.setupSlackBot?.value.trim();
            const whatsappOk = deps.refs.setupWhatsappToggle?.checked;
            const telegramOk = deps.refs.setupTelegramToggle?.checked && deps.refs.setupTelegramToken?.value.trim();
            const outlookOk = deps.refs.setupOutlookToggle?.checked;

            summaryEl.innerHTML = `
                <div class="setup-summary-group">
                    <h4>Install Location</h4>
                    ${item(chosenDir, true)}
                </div>
                <div class="setup-summary-group">
                    <h4>AI Models</h4>
                    ${item('Recommended profile (glm-5.1:cloud / gpt-oss:20b-cloud / qwen3.5:9b)', true)}
                    ${item('OpenAI' + (openaiOk ? '' : ' — configure later'), openaiOk)}
                    ${item('Google Gemini' + (geminiOk ? '' : ' — configure later'), geminiOk)}
                    ${item('NVIDIA Cloud' + (nvidiaOk ? '' : ' — configure later'), nvidiaOk)}
                </div>
                <div class="setup-summary-group">
                    <h4>Search</h4>
                    ${item('Built-in search (DuckDuckGo)', true)}
                    ${item('Brave Search' + (braveOk ? '' : ' — configure later'), braveOk)}
                </div>
                <div class="setup-summary-group">
                    <h4>Channels</h4>
                    ${item('Slack' + (slackOk ? '' : ' — configure later'), slackOk)}
                    ${item('WhatsApp' + (whatsappOk ? ' — scan QR after launch' : ' — configure later'), whatsappOk)}
                    ${item('Telegram' + (telegramOk ? '' : ' — configure later'), telegramOk)}
                </div>
                <div class="setup-summary-group">
                    <h4>Integrations</h4>
                    ${item('Google Workspace' + (googleOk ? '' : ' — configure later'), googleOk)}
                    ${item('Outlook' + (outlookOk ? '' : ' — configure later'), outlookOk)}
                </div>`;
        }

        async function setupCheckOllama() {
            const statusDot = document.querySelector('#setup-ollama-status .setup-status-dot');
            const statusText = document.getElementById('setup-ollama-status-text');
            const detail = document.getElementById('setup-ollama-detail');
            try {
                const data = await deps.authFetchJson('/api/setup/status');
                if (deps.refs.setupInstallDir && !deps.refs.setupInstallDir.value) {
                    deps.refs.setupInstallDir.value = data.install_dir || data.cwd || '';
                }
                if (data.ollama_running) {
                    if (statusDot) statusDot.className = 'setup-status-dot ok';
                    if (statusText) statusText.textContent = 'Running';
                    const models = data.ollama_models || [];
                    const hasMain = models.includes(deps.recommendedOllamaProfile.main);
                    const hasFast = models.includes(deps.recommendedOllamaProfile.fast);
                    const hasFallback = models.includes(deps.recommendedOllamaProfile.fallback);
                    let detailHtml = '<p>';
                    if (hasMain && hasFast && hasFallback) {
                        detailHtml += '✅ Recommended model profile detected: <strong>glm-5.1:cloud</strong>, <strong>gpt-oss:20b-cloud</strong>, and <strong>qwen3.5:9b</strong>.';
                    } else {
                        detailHtml += '⚠ Recommended model profile is incomplete. Sign in with <code>ollama signin</code>, then make <code>glm-5.1:cloud</code>, <code>gpt-oss:20b-cloud</code>, and <code>qwen3.5:9b</code> available.';
                    }
                    if (models.length) detailHtml += `<br>Installed: ${models.slice(0, 8).join(', ')}${models.length > 8 ? '…' : ''}`;
                    detailHtml += '</p>';
                    if (detail) detail.innerHTML = detailHtml;
                } else {
                    if (statusDot) statusDot.className = 'setup-status-dot err';
                    if (statusText) statusText.textContent = 'Not running';
                    if (detail) detail.innerHTML = '<p>⚠ Ollama is not running. <a href="https://ollama.com/download" target="_blank" rel="noopener">Download Ollama</a>, install it, and start it before continuing.</p>';
                }
            } catch (_) {
                if (statusDot) statusDot.className = 'setup-status-dot err';
                if (statusText) statusText.textContent = 'Error';
            }
        }

        async function setupSave() {
            const body = { setup_complete: true };
            const customDir = deps.refs.setupCustomDir?.value.trim();
            const appSettings = deps.getAppSettings();
            if (customDir) body.install_dir = customDir;
            if (!appSettings.main_model) body.main_model = deps.recommendedOllamaProfile.main;
            if (!appSettings.fast_model) body.fast_model = deps.recommendedOllamaProfile.fast;
            if (!appSettings.fallback_model) body.fallback_model = deps.recommendedOllamaProfile.fallback;

            if (deps.refs.setupOpenaiToggle?.checked && deps.refs.setupOpenaiKey?.value.trim()) body.openai_api_key = deps.refs.setupOpenaiKey.value.trim();
            if (deps.refs.setupGeminiToggle?.checked && deps.refs.setupGeminiKey?.value.trim()) body.gemini_api_key = deps.refs.setupGeminiKey.value.trim();
            if (deps.refs.setupNvidiaToggle?.checked && deps.refs.setupNvidiaKey?.value.trim()) body.nvidia_api_key = deps.refs.setupNvidiaKey.value.trim();
            if (deps.refs.setupBraveToggle?.checked && deps.refs.setupBraveKey?.value.trim()) body.brave_api_key = deps.refs.setupBraveKey.value.trim();
            if (deps.refs.setupGoogleToggle?.checked) {
                body.google_enabled = true;
                if (deps.refs.setupGoogleClientId?.value.trim()) body.google_client_id = deps.refs.setupGoogleClientId.value.trim();
                if (deps.refs.setupGoogleClientSecret?.value.trim()) body.google_client_secret = deps.refs.setupGoogleClientSecret.value.trim();
            }
            if (deps.refs.setupSlackToggle?.checked) {
                body.slack_enabled = true;
                if (deps.refs.setupSlackBot?.value.trim()) body.slack_bot_token = deps.refs.setupSlackBot.value.trim();
                if (deps.refs.setupSlackApp?.value.trim()) body.slack_app_token = deps.refs.setupSlackApp.value.trim();
            }
            if (deps.refs.setupWhatsappToggle?.checked) body.whatsapp_enabled = true;
            if (deps.refs.setupTelegramToggle?.checked) {
                body.telegram_enabled = true;
                if (deps.refs.setupTelegramToken?.value.trim()) body.telegram_bot_token = deps.refs.setupTelegramToken.value.trim();
            }
            if (deps.refs.setupOutlookToggle?.checked) body.outlook_enabled = true;

            try {
                await deps.authFetch('/api/setup/complete', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(body),
                });
            } catch (error) {
                console.error('Setup save error:', error);
            }

            if (deps.refs.setupOverlay) deps.refs.setupOverlay.style.display = 'none';
            await deps.loadSettings();
            await deps.loadModels();
        }

        async function maybeShowSetupWizard() {
            try {
                const data = await deps.authFetchJson('/api/setup/status');
                if (!data.setup_complete) {
                    if (deps.refs.setupInstallDir) deps.refs.setupInstallDir.value = data.install_dir || data.cwd || '';
                    if (deps.refs.setupOverlay) deps.refs.setupOverlay.style.display = 'flex';
                    setupGoToStep(0);
                }
            } catch (_) {}
        }

        function hideStartupBlockers() {
            if (deps.refs.disclaimerOverlay) deps.refs.disclaimerOverlay.style.display = 'none';
            if (deps.refs.setupOverlay) deps.refs.setupOverlay.style.display = 'none';
            deps.hideOfflineOverlay();
        }

        async function bootstrapStartupGates() {
            const disclaimerAccepted = !!localStorage.getItem('ao_disclaimer_v2');
            try {
                const data = await deps.authFetchJson('/api/setup/status');
                if (data.setup_complete) {
                    if (!disclaimerAccepted) localStorage.setItem('ao_disclaimer_v2', '1');
                    hideStartupBlockers();
                    return;
                }
                if (!disclaimerAccepted) {
                    if (deps.refs.disclaimerOverlay) deps.refs.disclaimerOverlay.style.display = 'flex';
                    return;
                }
                maybeShowSetupWizard();
            } catch (error) {
                console.warn('loadSettings:', error);
            } finally {
                deps.setIsLoadingSettings(false);
            }
        }

        function bindUi() {
            wireSetupToggle(deps.refs.setupOpenaiToggle, 'setup-openai-fields');
            wireSetupToggle(deps.refs.setupGeminiToggle, 'setup-gemini-fields');
            wireSetupToggle(deps.refs.setupNvidiaToggle, 'setup-nvidia-fields');
            wireSetupToggle(deps.refs.setupBraveToggle, 'setup-brave-fields');
            wireSetupToggle(deps.refs.setupGoogleToggle, 'setup-google-fields');
            wireSetupToggle(deps.refs.setupSlackToggle, 'setup-slack-fields');
            wireSetupToggle(deps.refs.setupWhatsappToggle, 'setup-whatsapp-fields');
            wireSetupToggle(deps.refs.setupTelegramToggle, 'setup-telegram-fields');

            if (deps.refs.setupValidateBtn) deps.refs.setupValidateBtn.addEventListener('click', validateFolder);
            if (deps.refs.setupNextBtn) deps.refs.setupNextBtn.addEventListener('click', () => {
                if (currentStep < totalSteps - 1) {
                    setupGoToStep(currentStep + 1);
                    if (currentStep === 2) setupCheckOllama();
                } else {
                    deps.refs.setupNextBtn.disabled = true;
                    deps.refs.setupNextBtn.textContent = 'Saving…';
                    setupSave().then(() => {
                        deps.refs.setupNextBtn.disabled = false;
                    });
                }
            });
            if (deps.refs.setupBackBtn) deps.refs.setupBackBtn.addEventListener('click', () => {
                if (currentStep > 0) setupGoToStep(currentStep - 1);
            });
            if (deps.refs.setupCancelBtn) deps.refs.setupCancelBtn.addEventListener('click', async () => {
                if (!confirm('Cancel installation? This will shut down the server and you can run the installer again later.')) return;
                deps.refs.setupCancelBtn.disabled = true;
                deps.refs.setupCancelBtn.textContent = 'Shutting down…';
                try {
                    await deps.authFetch('/api/shutdown', { method: 'POST' });
                } catch (_) {}
                document.body.innerHTML = `
                    <div style="display:flex;align-items:center;justify-content:center;height:100vh;background:#0f172a;color:#94a3b8;font-family:Inter,sans-serif;flex-direction:column;gap:16px">
                        <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
                        <p style="font-size:1.1rem;font-weight:600;color:#f1f5f9;margin:0">Installation Cancelled</p>
                        <p style="font-size:.875rem;margin:0">The server has been shut down. Run the installer again when you’re ready.</p>
                        <p style="font-size:.75rem;margin:0">You may close this tab.</p>
                    </div>`;
            });
        }

        return {
            bindUi,
            maybeShowSetupWizard,
            bootstrapStartupGates,
        };
    };
})();