function isDesktopShell() {
    return Boolean(window.orgBoardDesktop?.isDesktop);
}

function getDesktopUpdateMessage(status) {
    if (!status) return 'Updates are checked automatically in packaged builds.';
    if (status.downloaded) return status.message || `Version ${status.version} is ready to install.`;
    if (status.checking) return status.message || 'Checking for updates...';
    if (status.available) return status.message || `Downloading ${status.version}...`;
    return status.message || 'You are on the latest version.';
}

function renderDesktopUpdateStatus() {
    const versionEl = document.getElementById('settingsAppVersion');
    const statusEl = document.getElementById('settingsUpdateStatus');
    const button = document.getElementById('checkUpdatesBtn');
    if (!versionEl || !statusEl || !button) return;

    if (!isDesktopShell()) {
        versionEl.textContent = 'Browser mode';
        statusEl.textContent = 'Desktop auto-updates are available in the packaged app.';
        button.disabled = true;
        button.classList.add('opacity-60', 'cursor-not-allowed');
        return;
    }

    const versionLabel = state.desktopUpdateStatus?.version || state.desktopAppVersion || '—';
    versionEl.textContent = `v${versionLabel}`;
    statusEl.textContent = getDesktopUpdateMessage(state.desktopUpdateStatus);
    button.disabled = Boolean(state.desktopUpdateStatus?.checking);
    button.classList.toggle('opacity-60', button.disabled);
    button.classList.toggle('cursor-not-allowed', button.disabled);
}

function getDesktopRecommendedChatModel() {
    return state.desktopStatus?.chatModel || 'llama3.1:8b';
}

function getDesktopEmbeddedRuntime() {
    return state.desktopStatus?.embeddedRuntime || null;
}

function getDesktopPreferredLocalRuntime() {
    return state.desktopStatus?.preferredLocalRuntime || 'ollama';
}

function getDesktopRecommendedLocalRuntimeModel() {
    const embedded = getDesktopEmbeddedRuntime();
    if (getDesktopPreferredLocalRuntime() === 'embedded' && embedded?.modelSlug) {
        return embedded.modelSlug;
    }
    return getDesktopRecommendedChatModel();
}

function getDesktopDefaultAiSetup() {
    const preferredRuntime = getDesktopPreferredLocalRuntime();
    const provider = preferredRuntime === 'embedded'
        ? 'embedded'
        : (state.desktopStatus?.ollamaInstalled ? 'ollama' : (state.settings?.ai_provider || 'openrouter'));
    const embeddingProvider = preferredRuntime === 'embedded' ? 'embedded' : 'ollama';
    const embeddingModel = preferredRuntime === 'embedded'
        ? getDesktopRecommendedLocalRuntimeModel()
        : getDesktopRecommendedEmbeddingModel();
    return {
        ai_provider: provider,
        ai_model: provider === 'embedded'
            ? getDesktopRecommendedLocalRuntimeModel()
            : provider === 'ollama'
                ? getDesktopRecommendedChatModel()
                : (state.settings?.ai_model || 'google/gemini-2.5-flash'),
        ai_api_key: provider === 'openrouter' ? (state.settings?.ai_api_key || '') : '',
        embedding_provider: embeddingProvider,
        embedding_model: embeddingModel,
        local_runtime: getDesktopPreferredLocalRuntime(),
        local_runtime_model: getDesktopRecommendedLocalRuntimeModel()
    };
}

function getDesktopRecommendedEmbeddingModel() {
    if (getDesktopPreferredLocalRuntime() === 'embedded') {
        return getDesktopRecommendedLocalRuntimeModel();
    }
    return state.desktopStatus?.embeddingModel || 'nomic-embed-text';
}

function getInstalledOllamaModels() {
    return Array.isArray(state.desktopStatus?.installedModels) ? state.desktopStatus.installedModels : [];
}

function getOpenRouterModelPresets() {
    return [
        'google/gemini-2.5-flash',
        'google/gemini-2.5-pro',
        'openai/gpt-4.1-mini',
        'anthropic/claude-sonnet-4'
    ];
}

function renderOnboardingOllamaModels() {
    const wrap = document.getElementById('onbOllamaModelWrap');
    const select = document.getElementById('onbOllamaModelSelect');
    const providerInput = document.getElementById('onbAiProvider');
    const label = document.getElementById('onbModelSelectLabel');
    if (!wrap || !select || !providerInput) return;

    const provider = providerInput.value === 'ollama' ? 'ollama' : 'openrouter';
    const models = provider === 'ollama' ? getInstalledOllamaModels() : getOpenRouterModelPresets();
    const show = provider === 'openrouter' || (provider === 'ollama' && isDesktopShell());
    wrap.classList.toggle('hidden', !show);
    if (!show) return;

    const currentValue = document.getElementById('onbAiModel')?.value?.trim() || '';
    const recommended = provider === 'ollama' ? getDesktopRecommendedChatModel() : 'google/gemini-2.5-flash';
    if (label) {
        label.textContent = provider === 'ollama' ? 'Installed Local Models' : 'Recommended Cloud Models';
    }
    const options = models.map((model) => `<option value="${escapeAttr(model)}">${escapeHtml(model)}</option>`).join('');
    select.innerHTML = `
        <option value="">${provider === 'ollama'
            ? (models.length ? 'Select an installed model' : 'No installed Ollama models found yet')
            : 'Select a recommended OpenRouter model'}</option>
        ${options}
        <option value="__recommended__">Use recommended: ${escapeHtml(recommended)}</option>
    `;

    if (models.includes(currentValue)) {
        select.value = currentValue;
    } else if (currentValue === recommended) {
        select.value = '__recommended__';
    } else {
        select.value = '';
    }
}

function getDesktopStatusTone(status) {
    if (status?.embeddedRuntime?.supported) return 'emerald';
    if (!status?.ollamaInstalled) return 'amber';
    if (!status?.ollamaRunning) return 'sky';
    return 'emerald';
}

function getDesktopStatusLabel(status) {
    if (status?.embeddedRuntime?.supported) return 'Org Board Runtime available';
    if (!status?.ollamaInstalled) return 'Ollama not installed';
    if (!status?.ollamaRunning) return 'Ollama installed, not running';
    return 'Ollama ready';
}

function getDesktopStatusBody(status) {
    if (status?.embeddedRuntime?.supported) {
        const runtimeStatus = state.localRuntimeStatus || {};
        const installState = runtimeStatus.packagesReady
            ? (runtimeStatus.installedModels?.length ? 'Runtime installed. Chat and embeddings use the same downloaded local model.' : 'Runtime installed. Download the recommended model to use it.')
            : 'Install the runtime once, then download the recommended model.';
        return `${escapeHtml(status.embeddedRuntime.label)} via ${escapeHtml(status.embeddedRuntime.engine.toUpperCase())}. ${escapeHtml(status.embeddedRuntime.summary)} ${escapeHtml(installState)}`;
    }
    if (!status?.ollamaInstalled) {
        return 'Install Ollama first, then this app can recommend and pull the right local model for this machine.';
    }
    if (!status?.ollamaRunning) {
        return 'Ollama is installed on this machine. Start it once, then pull the recommended chat and embedding models.';
    }
    return `Recommended for this machine: ${escapeHtml(getDesktopRecommendedChatModel())} + ${escapeHtml(getDesktopRecommendedEmbeddingModel())}.`;
}

function renderDesktopStatusPanel(targetId, options = {}) {
    const container = document.getElementById(targetId);
    if (!container) return;

    if (!isDesktopShell()) {
        container.innerHTML = '';
        container.classList.add('hidden');
        return;
    }

    const status = state.desktopStatus || {};
    const tone = getDesktopStatusTone(status);
    const embeddedRuntime = getDesktopEmbeddedRuntime();
    const toneMap = {
        amber: 'border-amber-500/20 bg-amber-500/5 text-amber-200',
        sky: 'border-sky-500/20 bg-sky-500/5 text-sky-200',
        emerald: 'border-emerald-500/20 bg-emerald-500/5 text-emerald-200'
    };
    const installedModels = Array.isArray(status.installedModels) && status.installedModels.length
        ? status.installedModels.map((model) => `<span class="inline-flex items-center px-2.5 py-1 rounded-full bg-white/5 border border-white/10 text-[11px] text-gray-300">${escapeHtml(model)}</span>`).join('')
        : '<span class="text-[11px] text-gray-500">No local models detected yet.</span>';
    const wrapperClass = toneMap[tone] || toneMap.sky;
    const runtimeStatus = state.localRuntimeStatus || {};
    const showAdvancedOllama = options.showAdvancedOllama !== false;

    container.classList.remove('hidden');
    container.innerHTML = `
        <div class="rounded-2xl border ${wrapperClass} p-4 flex flex-col gap-3">
            <div class="flex flex-col gap-1">
                <div class="flex items-center justify-between gap-3">
                    <p class="text-sm font-semibold">${escapeHtml(getDesktopStatusLabel(status))}</p>
                    <button class="text-[11px] px-2.5 py-1 rounded-full bg-white/5 border border-white/10 text-gray-300 hover:text-white transition" data-desktop-action="refresh-status">
                        Refresh
                    </button>
                </div>
                <p class="text-xs text-gray-300/80">${getDesktopStatusBody(status)}</p>
                <p class="text-[11px] text-gray-400">Machine profile: ${escapeHtml(status.platform || 'unknown')} · ${escapeHtml(String(status.totalMemoryGb || '?'))} GB RAM · ${escapeHtml(String(status.cpuCount || '?'))} CPU threads</p>
            </div>
            ${embeddedRuntime?.supported ? `
                <div class="rounded-2xl bg-black/20 border border-white/5 p-3 flex flex-col gap-2">
                    <div class="flex items-center justify-between gap-3">
                        <div>
                            <p class="text-xs uppercase tracking-[0.2em] text-emerald-300">Default local runtime</p>
                            <p class="text-sm font-semibold text-white mt-1">${escapeHtml(embeddedRuntime.label)}</p>
                        </div>
                        <span class="px-2.5 py-1 rounded-full bg-emerald-500/15 border border-emerald-400/20 text-[11px] font-semibold text-emerald-100">
                            ${escapeHtml(embeddedRuntime.engine.toUpperCase())}
                        </span>
                    </div>
                    <p class="text-[11px] text-gray-400">This is the default Apple Silicon path. Keep Ollama available below as an advanced fallback and test path.</p>
                    <div class="flex flex-wrap gap-2">
                        <button class="px-3 py-2 rounded-xl bg-emerald-500/15 border border-emerald-400/20 text-xs font-semibold text-emerald-100 hover:bg-emerald-500/25 transition" data-embedded-action="install-runtime">Install Runtime</button>
                        <button class="px-3 py-2 rounded-xl bg-indigo-500/15 border border-indigo-400/20 text-xs font-semibold text-indigo-100 hover:bg-indigo-500/25 transition" data-embedded-action="pull-model" data-model-slug="${escapeAttr(embeddedRuntime.modelSlug)}">Download ${escapeHtml(embeddedRuntime.label)}</button>
                    </div>
                    <div class="text-[11px] text-gray-500">Runtime: ${runtimeStatus.packagesReady ? 'installed' : 'not installed'} · Downloaded models: ${(runtimeStatus.installedModels || []).length} · Embeddings use the same local model automatically.</div>
                    ${runtimeStatus.lastError ? `<div class="text-[11px] text-rose-300/90 leading-relaxed">Runtime error: ${escapeHtml(runtimeStatus.lastError)}</div>` : ''}
                </div>
            ` : ''}
            ${showAdvancedOllama ? `
            <details class="rounded-2xl bg-black/20 border border-white/5 p-3">
                <summary class="cursor-pointer text-xs font-semibold uppercase tracking-[0.18em] text-gray-300">Advanced: Ollama tools</summary>
                <div class="flex flex-col gap-3 mt-3">
                    <div class="flex flex-wrap gap-2">
                        <button class="px-3 py-2 rounded-xl bg-white/5 border border-white/10 text-xs font-semibold text-gray-200 hover:bg-white/10 transition" data-desktop-action="install-ollama">Install Ollama</button>
                        <button class="px-3 py-2 rounded-xl bg-white/5 border border-white/10 text-xs font-semibold text-gray-200 hover:bg-white/10 transition" data-desktop-action="start-ollama">Start Ollama</button>
                        <button class="px-3 py-2 rounded-xl bg-indigo-500/15 border border-indigo-400/20 text-xs font-semibold text-indigo-100 hover:bg-indigo-500/25 transition" data-desktop-action="pull-chat-model" data-model="${escapeAttr(getDesktopRecommendedChatModel())}">
                            Pull ${escapeHtml(getDesktopRecommendedChatModel())}
                        </button>
                        <button class="px-3 py-2 rounded-xl bg-emerald-500/15 border border-emerald-400/20 text-xs font-semibold text-emerald-100 hover:bg-emerald-500/25 transition" data-desktop-action="pull-embedding-model" data-model="${escapeAttr(getDesktopRecommendedEmbeddingModel())}">
                            Pull ${escapeHtml(getDesktopRecommendedEmbeddingModel())}
                        </button>
                    </div>
                    <div class="flex flex-wrap gap-2 items-center">
                        <span class="text-[11px] uppercase tracking-[0.2em] text-gray-500">Installed models</span>
                        ${installedModels}
                    </div>
                    ${options.showRecommendationNote === false ? '' : '<p class="text-[11px] text-gray-500">If you select Ollama in this app, the recommended Ollama model will be prefilled automatically.</p>'}
                </div>
            </details>
            ` : ''}
        </div>
    `;
}

function syncDesktopRecommendedModels() {
    const settingsProvider = document.getElementById('aiProviderSelect');
    const settingsModel = document.getElementById('aiModelInput');
    const localRuntime = document.getElementById('settingsLocalRuntime');
    const localRuntimeModel = document.getElementById('settingsLocalRuntimeModel');
    const embeddingProvider = document.getElementById('embeddingProviderSelect');
    const embeddingModel = document.getElementById('embeddingModelInput');

    if (settingsProvider && settingsModel && settingsProvider.value === 'ollama' && !settingsModel.value.trim()) {
        settingsModel.value = getDesktopRecommendedChatModel();
    }
    if (localRuntime && localRuntimeModel && !localRuntimeModel.value.trim()) {
        localRuntimeModel.value = localRuntime.value === 'embedded'
            ? getDesktopRecommendedLocalRuntimeModel()
            : getDesktopRecommendedChatModel();
    }
    if (embeddingProvider && embeddingModel && !embeddingModel.value.trim()) {
        if (embeddingProvider.value === 'ollama' || embeddingProvider.value === 'embedded') {
            embeddingModel.value = getDesktopRecommendedEmbeddingModel();
        }
    }
}

async function refreshDesktopStatus(showFeedback = false) {
    if (!isDesktopShell()) return null;
    try {
        state.desktopStatus = await window.orgBoardDesktop.getSystemStatus();
        state.localRuntimeStatus = await api.getLocalRuntimeStatus().catch(() => null);
        renderDesktopStatusPanel('desktopOnboardingStatus', { showAdvancedOllama: false, showRecommendationNote: false });
        renderDesktopStatusPanel('desktopSettingsStatus', { showRecommendationNote: false });
        syncDesktopRecommendedModels();
        renderOnboardingOllamaModels();
        if (showFeedback) showToast('Desktop status refreshed.', 'success');
        return state.desktopStatus;
    } catch (error) {
        if (showFeedback) showToast(error.message || 'Desktop status refresh failed.', 'error');
        return null;
    }
}

async function runEmbeddedRuntimeAction(action, modelSlug = '') {
    try {
        if (action === 'install-runtime') {
            showToast('Installing local runtime. This can take a while...', 'info');
            await api.installLocalRuntime();
            showToast('Local runtime installed.', 'success');
        } else if (action === 'pull-model') {
            if (!modelSlug) throw new Error('Model slug missing');
            showToast(`Downloading ${modelSlug}. This can take a while...`, 'info');
            const result = await api.pullLocalRuntimeModel(modelSlug);
            showToast(result?.alreadyInstalled ? `${modelSlug} is already downloaded.` : `${modelSlug} downloaded.`, 'success');
        }
        await refreshDesktopStatus(false);
    } catch (error) {
        showToast(error.message || 'Embedded runtime action failed.', 'error');
    }
}

async function runDesktopAction(action, modelName = '') {
    if (!isDesktopShell()) return;
    try {
        if (action === 'install-ollama') {
            await window.orgBoardDesktop.openOllamaInstaller();
            showToast('Opened Ollama installer.', 'info');
        } else if (action === 'start-ollama') {
            await window.orgBoardDesktop.startOllama();
            showToast('Ollama started.', 'success');
        } else if (action === 'pull-chat-model' || action === 'pull-embedding-model') {
            if (!modelName) throw new Error('Model name missing');
            showToast(`Pulling ${modelName}. This can take a while...`, 'info');
            const result = await window.orgBoardDesktop.pullOllamaModel(modelName);
            showToast(result?.alreadyInstalled ? `${modelName} is already installed.` : `${modelName} downloaded.`, 'success');
        } else if (action === 'refresh-status') {
            await refreshDesktopStatus(true);
            return;
        }
        await refreshDesktopStatus(false);
    } catch (error) {
        showToast(error.message || 'Desktop action failed.', 'error');
        console.error('[desktop action failed]', action, modelName, error);
    }
}

async function initDesktopShell() {
    renderDesktopUpdateStatus();
    if (!isDesktopShell()) return;

    document.body.classList.add('desktop-shell');
    await refreshDesktopStatus(false);
    try {
        state.desktopAppVersion = await window.orgBoardDesktop.getAppVersion();
        state.desktopUpdateStatus = await window.orgBoardDesktop.getUpdateStatus();
    } catch (_error) {}
    renderDesktopUpdateStatus();

    document.getElementById('onbOllamaModelSelect')?.addEventListener('change', (event) => {
        const modelInput = document.getElementById('onbAiModel');
        if (!modelInput) return;
        const value = event.target.value;
        if (value === '__recommended__') {
            modelInput.value = getDesktopRecommendedChatModel();
        } else if (value) {
            modelInput.value = value;
        }
    });

    document.addEventListener('click', async (event) => {
        const actionBtn = event.target.closest('[data-desktop-action]');
        if (!actionBtn) return;
        await runDesktopAction(actionBtn.dataset.desktopAction, actionBtn.dataset.model || '');
    });

    document.addEventListener('click', async (event) => {
        const actionBtn = event.target.closest('[data-embedded-action]');
        if (!actionBtn) return;
        await runEmbeddedRuntimeAction(actionBtn.dataset.embeddedAction, actionBtn.dataset.modelSlug || '');
    });

    document.getElementById('checkUpdatesBtn')?.addEventListener('click', async () => {
        try {
            state.desktopUpdateStatus = await window.orgBoardDesktop.checkForUpdates();
            renderDesktopUpdateStatus();
            if (state.desktopUpdateStatus?.message && !state.desktopUpdateStatus?.checking) {
                showToast(state.desktopUpdateStatus.message, 'info');
            }
        } catch (error) {
            showToast(error.message || 'Update check failed.', 'error');
        }
    });

    window.orgBoardDesktop.onUpdateStatus((payload) => {
        state.desktopUpdateStatus = payload;
        renderDesktopUpdateStatus();
    });
}
