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

    window.AgentFrontendModules.createSettingsKnowledgeModule = function createSettingsKnowledgeModule(deps) {
        let uiBound = false;
        let learningCandidatesExpanded = false;

        function escSystemLogValue(value) {
            const node = document.createElement('div');
            node.textContent = String(value ?? '');
            return node.innerHTML;
        }

        async function loadWikiStatus() {
            const note = document.getElementById('wiki-status-note');
            const countBadge = document.getElementById('memory-context-count');
            try {
                const data = await deps.authFetchJson('/api/wiki/status');
                const pageCount = Number(data?.pageCount || 0);
                const total = Number(data?.entryTotal || data?.draftCounts?.published || 0);
                if (note) note.textContent = `${total} durable memor${total === 1 ? 'y' : 'ies'} across ${pageCount} wiki page${pageCount === 1 ? '' : 's'} for future dialogue.`;
                if (countBadge) countBadge.textContent = String(total);
            } catch (error) {
                if (note) note.textContent = `Failed to load durable memory: ${error.message || error}`;
                if (countBadge) countBadge.textContent = '0';
            }
        }

        async function loadWikiDrafts() {
            const list = document.getElementById('wiki-drafts-list');
            const empty = document.getElementById('wiki-drafts-empty');
            if (!list) return;
            list.innerHTML = '<p style="color:var(--text-secondary);font-size:.82rem">Loading durable memory…</p>';
            if (empty) empty.style.display = 'none';
            try {
                const data = await deps.authFetchJson('/api/wiki/drafts?status=published&limit=100');
                const drafts = Array.isArray(data?.drafts) ? data.drafts : [];
                if (!drafts.length) {
                    list.innerHTML = '';
                    if (empty) empty.style.display = '';
                    return;
                }
                list.innerHTML = drafts.map((draft) => {
                    const when = draft.updated_at
                        ? new Date(draft.updated_at).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' })
                        : '';
                    const section = String(draft.target_section || draft.knowledge_kind || '').replace(/_/g, ' ');
                    return `<div class="knowledge-entry-row" data-draft-id="${escSystemLogValue(draft.id || '')}">
                        <div class="knowledge-entry-copy">
                            <div class="knowledge-entry-top">
                                <div class="knowledge-entry-title">${escSystemLogValue(draft.title || '(untitled entry)')}</div>
                                <div class="knowledge-entry-date">${escSystemLogValue(when || section || 'Memory')}</div>
                            </div>
                            <div class="knowledge-entry-summary">${escSystemLogValue(draft.summary || '(no summary)')}</div>
                        </div>
                    </div>`;
                }).join('');
            } catch {
                list.innerHTML = '<p style="color:var(--text-secondary);font-size:.82rem">Failed to load durable memory.</p>';
            }
        }

        async function loadWikiKnowledgePanel() {
            await loadWikiStatus();
            await loadWikiDrafts();
        }

        function humanLearningImpact(impactType) {
            const map = {
                planner_rule: 'Planner rule',
                prompt_rule: 'Prompt rule',
                observation: 'Observation',
            };
            return map[String(impactType || '').trim()] || String(impactType || 'candidate').replace(/_/g, ' ');
        }

        function humanLearningStatus(status) {
            const map = {
                approved: 'Approved',
                rejected: 'Rejected',
                candidate: 'Pending',
            };
            return map[String(status || '').trim()] || String(status || 'unknown').replace(/_/g, ' ');
        }

        function syncLearningCandidatesVisibility(hasCandidates) {
            const list = document.getElementById('learning-candidates-list');
            const empty = document.getElementById('learning-candidates-empty');
            const toggle = document.getElementById('learning-candidates-toggle');
            const shouldShowList = !!hasCandidates && !!learningCandidatesExpanded;
            if (toggle) {
                toggle.style.display = hasCandidates ? '' : 'none';
                toggle.textContent = learningCandidatesExpanded ? '<' : '>';
                toggle.setAttribute('aria-expanded', learningCandidatesExpanded ? 'true' : 'false');
                toggle.setAttribute('aria-label', learningCandidatesExpanded ? 'Collapse automatic learnings' : 'Expand automatic learnings');
                toggle.title = learningCandidatesExpanded ? 'Collapse automatic learnings' : 'Expand automatic learnings';
            }
            if (list) {
                list.hidden = !shouldShowList;
                list.style.display = shouldShowList ? 'flex' : 'none';
            }
            if (empty) empty.style.display = hasCandidates ? 'none' : '';
        }

        async function reviewLearningCandidate(candidateId, approved, reason, button) {
            if (!candidateId) return false;
            const originalLabel = button ? button.textContent : '';
            if (button) {
                button.disabled = true;
                button.textContent = approved ? 'Approving…' : 'Rejecting…';
            }
            try {
                const response = await deps.authFetch('/api/learning/candidates/review', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        candidate_id: candidateId,
                        approved: !!approved,
                        reason,
                        reviewer: 'ui_systemlog',
                    }),
                });
                let payload = {};
                try { payload = await response.json(); } catch (_) {}
                if (!response.ok) throw new Error(payload.detail || `HTTP ${response.status}`);
                deps.helpers.showToast('success', approved ? 'Learning approved' : 'Learning rejected', 2500);
                await loadSystemLog();
                return true;
            } catch (error) {
                if (button) {
                    button.disabled = false;
                    button.textContent = originalLabel;
                }
                deps.helpers.showToast('error', `Failed to review learning: ${error.message || error}`, 5000);
                return false;
            }
        }

        async function loadLearningCandidates() {
            const list = document.getElementById('learning-candidates-list');
            const empty = document.getElementById('learning-candidates-empty');
            const count = document.getElementById('learning-candidates-count');
            const toggle = document.getElementById('learning-candidates-toggle');
            if (!list) return;
            list.innerHTML = '<p style="color:var(--text-secondary);font-size:.82rem">Loading reviewed learnings…</p>';
            if (empty) empty.style.display = 'none';
            if (count) count.style.display = 'none';
            if (toggle) toggle.style.display = 'none';
            try {
                const response = await deps.authFetch('/api/learning/candidates?status=reviewed&limit=50');
                const data = await response.json();
                const candidates = Array.isArray(data.candidates) ? data.candidates : [];
                if (!response.ok) throw new Error(data.detail || `HTTP ${response.status}`);
                if (!candidates.length) {
                    list.innerHTML = '';
                    syncLearningCandidatesVisibility(false);
                    return;
                }
                if (count) {
                    const approvedCount = candidates.filter((candidate) => String(candidate.status || '').trim() === 'approved').length;
                    const rejectedCount = candidates.filter((candidate) => String(candidate.status || '').trim() === 'rejected').length;
                    count.textContent = `${approvedCount} approved · ${rejectedCount} rejected`;
                    count.style.display = '';
                }
                if (toggle) {
                    toggle.onclick = () => {
                        learningCandidatesExpanded = !learningCandidatesExpanded;
                        syncLearningCandidatesVisibility(true);
                    };
                }
                list.innerHTML = candidates.map((candidate) => {
                    const impactType = String(candidate.impact_type || '').trim();
                    const status = String(candidate.status || '').trim() || 'unknown';
                    const source = String(candidate.source || '').trim() || 'unknown';
                    const kind = String(candidate.kind || '').trim() || 'candidate';
                    const taskType = String(candidate.task_type || '').trim() || 'generic';
                    const providerScope = String(candidate.provider_scope || '').trim() || 'default';
                    const timeFilter = String(candidate.time_filter || '').trim() || 'none';
                    const ruleText = String(candidate.rule_text || '').trim();
                    const context = String(candidate.context || '').trim();
                    const reasonText = String(candidate.review_reason || '').trim();
                    const reviewSource = String(candidate.review_source || '').trim();
                    const reviewModel = String(candidate.review_model || '').trim();
                    const timestamp = candidate.reviewed_at ? new Date(candidate.reviewed_at) : (candidate.timestamp ? new Date(candidate.timestamp) : null);
                    const when = timestamp && !Number.isNaN(timestamp.getTime())
                        ? timestamp.toLocaleString('nl-NL', { day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit' })
                        : '';
                    return `<div class="learning-review-card" data-candidate-id="${escSystemLogValue(candidate.id || '')}">
                        <div class="learning-review-card__top">
                            <div style="min-width:0;flex:1">
                                <div style="font-size:.84rem;font-weight:600;color:var(--text-1)">${escSystemLogValue(humanLearningImpact(impactType))}</div>
                                <div class="learning-review-card__meta">
                                    <span class="learning-review-chip learning-review-chip--${escSystemLogValue(status)}">${escSystemLogValue(humanLearningStatus(status))}</span>
                                    <span class="learning-review-chip">${escSystemLogValue(source)}</span>
                                    <span class="learning-review-chip">${escSystemLogValue(kind)}</span>
                                    <span class="learning-review-chip">${escSystemLogValue(taskType)} | ${escSystemLogValue(providerScope)} | ${escSystemLogValue(timeFilter)}</span>
                                    ${reviewModel ? `<span class="learning-review-chip">${escSystemLogValue(reviewModel)}</span>` : (reviewSource ? `<span class="learning-review-chip">${escSystemLogValue(reviewSource)}</span>` : '')}
                                </div>
                            </div>
                            <div style="flex-shrink:0;font-size:.72rem;color:var(--text-secondary);white-space:nowrap">${escSystemLogValue(when)}</div>
                        </div>
                        <div class="learning-review-card__rule">${escSystemLogValue(ruleText || '(empty rule)')}</div>
                        ${context || reasonText ? `<div class="learning-review-card__context">${reasonText ? `<strong>Decision</strong><br>${escSystemLogValue(reasonText)}` : ''}${reasonText && context ? '<br><br>' : ''}${context ? `<strong>Context</strong><br>${escSystemLogValue(context)}` : ''}</div>` : ''}
                    </div>`;
                }).join('');
                syncLearningCandidatesVisibility(true);
            } catch {
                list.innerHTML = '<p style="color:var(--text-secondary);font-size:.82rem">Failed to load reviewed learnings.</p>';
                if (count) count.style.display = 'none';
                if (toggle) toggle.style.display = 'none';
            }
        }

        async function loadSystemLog() {
            const list = document.getElementById('systemlog-list');
            const empty = document.getElementById('systemlog-empty');
            if (!list) return;
            loadLearningCandidates();
            list.innerHTML = '<p style="color:var(--text-secondary);font-size:.82rem">Loading…</p>';
            try {
                const response = await deps.authFetch('/api/system-log');
                const data = await response.json();
                const events = data.events || [];
                if (!events.length) {
                    list.innerHTML = '';
                    if (empty) empty.style.display = '';
                    return;
                }
                if (empty) empty.style.display = 'none';

                const catMeta = {
                    correction: { icon: '✏️', label: 'Correction' },
                    reflection: { icon: '🪞', label: 'Reflection' },
                    memory_aging: { icon: '🗂️', label: 'Memory Maintenance' },
                    briefing_feedback: { icon: '📋', label: 'Briefing Feedback' },
                    server: { icon: '🖥️', label: 'Server' },
                    hypothesis: { icon: '🧭', label: 'Hypothese' },
                    run_kpi: { icon: '📈', label: 'Run KPI' },
                    learning: { icon: '🧠', label: 'Learning' },
                };

                const humanKey = (key) => {
                    const map = {
                        uitleg: 'Uitleg',
                        run_id: 'Run',
                        event_id: 'Event',
                        tool: 'Tool',
                        outcome: 'Resultaat',
                        active_hypothesis: 'Actieve hypothese',
                        active_before: 'Actief vóór stap',
                        active_after: 'Actief na stap',
                        confidence_before: 'Confidence vóór',
                        confidence_after: 'Confidence na',
                        decision_mode: 'Beslisstand',
                        remediation_mode: 'Aanpassing',
                        step_index: 'Stap index',
                        goal_preview: 'Doelcontext',
                        switched_to: 'Gewisseld naar',
                        mode: 'Beslisstand',
                        completed: 'Afgerond',
                        halted: 'Gestopt',
                        steps: 'Stappen',
                        tool_calls: 'Tool-calls',
                        first_pass_success: 'First pass',
                        correction_rate: 'Correctieratio',
                        tool_call_efficiency: 'Tool-efficiëntie',
                        time_to_solution_ms: 'Tijd tot oplossing (ms)',
                        halt_reason: 'Stopreden',
                        playbook_key: 'Playbook sleutel',
                        playbook_status: 'Playbook status',
                        task_type: 'Taaktype',
                        attempts: 'Pogingen',
                        success_rate: 'Succesratio',
                        first_pass_rate: 'First pass ratio',
                        delta_steps: 'Delta stappen',
                        delta_tool_calls: 'Delta tool-calls',
                        delta_runtime_seconds: 'Delta runtime (s)',
                        delta_tokens: 'Delta tokens',
                        policy_mode: 'Policy modus',
                    };
                    return map[key] || String(key).replace(/_/g, ' ');
                };

                const renderSystemLogRow = (event, index) => {
                    const timestamp = new Date(event.ts);
                    const date = timestamp.toLocaleDateString('nl-NL', { day: '2-digit', month: 'short' });
                    const time = timestamp.toLocaleTimeString('nl-NL', { hour: '2-digit', minute: '2-digit' });
                    const meta = catMeta[event.cat] || { icon: '📌', label: escSystemLogValue(event.cat) };
                    const hasDetail = event.details && Object.keys(event.details).length > 0;
                    let detail = '';
                    if (hasDetail) {
                        const entries = Object.entries(event.details);
                        const explanation = String(event.details.uitleg || '').trim();
                        const parts = entries
                            .filter(([key]) => key !== 'uitleg')
                            .map(([key, value]) => {
                                const text = String(value);
                                return `<div style="margin-top:3px"><span style="color:var(--text-secondary);font-weight:500">${escSystemLogValue(humanKey(key))}</span><br><span style="white-space:pre-wrap;word-break:break-word">${escSystemLogValue(text)}</span></div>`;
                            });
                        const explanationBlock = explanation
                            ? `<div style="margin-top:2px;padding:6px 8px;background:rgba(16,185,129,.10);border:1px solid rgba(16,185,129,.25);border-radius:6px;color:var(--text-primary)"><span style="font-weight:600">Uitleg</span><br><span style="white-space:pre-wrap;word-break:break-word">${escSystemLogValue(explanation)}</span></div>`
                            : '';
                        detail = `<div class="syslog-detail" id="syslog-d${index}" style="display:none;margin-top:6px;padding:6px 8px;background:var(--bg-secondary);border-radius:6px;font-size:.75rem;color:var(--text-secondary)">${explanationBlock}${parts.join('')}</div>`;
                    }
                    const cursor = hasDetail ? 'cursor:pointer' : '';
                    const chevron = hasDetail
                        ? '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="var(--text-secondary)" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="flex-shrink:0;transition:transform .15s;margin-top:3px" class="syslog-chev"><polyline points="6 9 12 15 18 9"/></svg>'
                        : '';
                    return `<div class="syslog-row" ${hasDetail ? `data-detail="syslog-d${index}"` : ''} style="padding:7px 8px;border-bottom:1px solid var(--border);${cursor}">
                        <div style="display:flex;gap:10px;align-items:flex-start">
                            <span style="flex-shrink:0;font-size:1rem;line-height:1.4">${meta.icon}</span>
                            <div style="flex:1;min-width:0">
                                <div style="display:flex;justify-content:space-between;align-items:baseline;gap:8px">
                                    <span style="font-size:.82rem;font-weight:500">${meta.label}</span>
                                    <span style="font-size:.72rem;color:var(--text-secondary);white-space:nowrap">${date} ${time}</span>
                                </div>
                                <div style="font-size:.8rem;margin-top:1px">${escSystemLogValue(event.msg)}</div>
                            </div>
                            ${chevron}
                        </div>
                        ${detail}
                    </div>`;
                };

                const groupedEntries = [];
                for (let index = 0; index < events.length; index += 1) {
                    const event = events[index];
                    if (event && event.cat === 'learning') {
                        const learningEvents = [];
                        while (index < events.length && events[index] && events[index].cat === 'learning') {
                            learningEvents.push(events[index]);
                            index += 1;
                        }
                        index -= 1;
                        groupedEntries.push({ kind: 'learning-group', events: learningEvents });
                        continue;
                    }
                    groupedEntries.push({ kind: 'event', event });
                }

                let detailIndex = 0;
                const rows = groupedEntries.map((entry) => {
                    if (entry.kind !== 'learning-group') {
                        const row = renderSystemLogRow(entry.event, detailIndex);
                        detailIndex += 1;
                        return row;
                    }

                    const learningEvents = Array.isArray(entry.events) ? entry.events : [];
                    const latestEvent = learningEvents[0] || {};
                    const timestamp = new Date(latestEvent.ts || Date.now());
                    const date = timestamp.toLocaleDateString('nl-NL', { day: '2-digit', month: 'short' });
                    const time = timestamp.toLocaleTimeString('nl-NL', { hour: '2-digit', minute: '2-digit' });
                    const count = learningEvents.length;
                    const groupDetailId = `syslog-learning-group-${detailIndex}`;
                    detailIndex += 1;
                    const summaryText = count === 1
                        ? escSystemLogValue(String(latestEvent.msg || '1 learning item'))
                        : `${count} learning items`;
                    const learningRows = learningEvents.map((learningEvent) => {
                        const row = renderSystemLogRow(learningEvent, detailIndex);
                        detailIndex += 1;
                        return row;
                    }).join('');

                    return `<div class="syslog-learning-group syslog-row" data-detail="${groupDetailId}" style="padding:7px 8px;border-bottom:1px solid var(--border);cursor:pointer">
                        <div style="display:flex;gap:10px;align-items:flex-start">
                            <span style="flex-shrink:0;font-size:1rem;line-height:1.4">🧠</span>
                            <div style="flex:1;min-width:0">
                                <div style="display:flex;justify-content:space-between;align-items:baseline;gap:8px">
                                    <span style="font-size:.82rem;font-weight:500">Learning</span>
                                    <span style="font-size:.72rem;color:var(--text-secondary);white-space:nowrap">${date} ${time}</span>
                                </div>
                                <div style="font-size:.8rem;margin-top:1px">${summaryText}</div>
                                <div style="font-size:.72rem;color:var(--text-secondary);margin-top:3px">${count === 1 ? 'Expand to inspect this learning' : `Expand to inspect all ${count} learning items`}</div>
                            </div>
                            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="var(--text-secondary)" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="flex-shrink:0;transition:transform .15s;margin-top:3px" class="syslog-chev">
                                <polyline points="6 9 12 15 18 9"></polyline>
                            </svg>
                        </div>
                        <div class="syslog-detail" id="${groupDetailId}" style="display:none;margin-top:6px;padding:0 0 0 18px;background:rgba(255,255,255,.01);border-radius:6px;font-size:.75rem;color:var(--text-secondary)">
                            ${learningRows}
                        </div>
                    </div>`;
                }).join('');
                list.innerHTML = rows;

                list.querySelectorAll('.syslog-row[data-detail]').forEach((row) => {
                    row.addEventListener('click', () => {
                        const detailNode = document.getElementById(row.dataset.detail);
                        const chevron = row.querySelector('.syslog-chev');
                        if (!detailNode) return;
                        const open = detailNode.style.display !== 'none';
                        detailNode.style.display = open ? 'none' : '';
                        if (chevron) chevron.style.transform = open ? '' : 'rotate(180deg)';
                    });
                });
            } catch {
                list.innerHTML = '<p style="color:var(--text-secondary);font-size:.82rem">Failed to load system log.</p>';
            }
        }

        async function loadToolsPane() {
            const builtinList = document.getElementById('tools-builtin-list');
            const customList = document.getElementById('tools-custom-list');
            const mcpList = document.getElementById('tools-mcp-list');
            const emptyNote = document.getElementById('tools-empty-note');
            const mcpNote = document.getElementById('tools-mcp-note');
            if (!builtinList) return;

            async function persistToolToggle(name, enabled) {
                const appSettings = deps.state.getAppSettings();
                const map = (appSettings.tool_enabled_map && typeof appSettings.tool_enabled_map === 'object')
                    ? { ...appSettings.tool_enabled_map }
                    : {};
                const aliasNames = name === 'analyze_attachments'
                    ? ['analyze_attachments', 'analyze_non_pdf_attachments']
                    : [name];
                if (enabled) delete map[name];
                else map[name] = false;
                aliasNames.forEach((alias) => {
                    if (enabled) delete map[alias];
                    else if (alias !== name) delete map[alias];
                });
                appSettings.tool_enabled_map = map;
                try {
                    await deps.authFetch('/api/settings', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ tool_enabled_map: map }),
                    });
                    deps.helpers.showToast('success', `Skill ${enabled ? 'enabled' : 'disabled'}: ${name}`, 2000);
                } catch (error) {
                    deps.helpers.showToast('error', 'Failed to update skill: ' + (error.message || error), 4000);
                }
            }

            function renderTool(tool, options = {}) {
                const deletable = !!options.deletable;
                const allowToggle = options.allowToggle !== false;
                const card = document.createElement('div');
                card.className = 'tool-card';
                const safeName = deps.helpers.escapeHtml(tool.name);
                const isEnabled = tool.enabled !== false;
                if (!isEnabled) card.classList.add('tool-card-disabled');
                const sourceLabelMap = {
                    builtin: 'built-in',
                    custom: 'custom',
                    mcp_server: 'MCP server',
                    mcp_tool: 'MCP tool',
                };
                const statusBits = [];
                const sourceLabel = sourceLabelMap[String(tool.source || '')] || String(tool.source || 'skill');
                if (sourceLabel) statusBits.push(sourceLabel);
                if (Array.isArray(tool.domains) && tool.domains.length) statusBits.push(tool.domains.join('/'));
                statusBits.push(isEnabled ? 'enabled' : 'disabled');
                statusBits.push(tool.available === false ? 'unavailable' : 'available');
                if (tool.requires_approval) statusBits.push('approval');
                if (tool.side_effect) statusBits.push('side-effect');
                if (tool.metadata && tool.metadata.server) statusBits.push(`server: ${String(tool.metadata.server)}`);
                const metaHtml = deps.helpers.escapeHtml(statusBits.join(' | '));
                card.innerHTML = `
                    <div class="tool-card-header">
                        <span class="tool-card-name">${safeName}</span>
                        <div class="tool-card-actions">
                            ${allowToggle ? `<label class="toggle" title="Enable/disable skill">
                                <input type="checkbox" class="tool-enable-toggle" ${isEnabled ? 'checked' : ''}>
                                <span class="toggle-slider"></span>
                            </label>` : ''}
                        ${deletable ? `<button class="tool-source-btn" data-name="${safeName}" title="View source">👁</button>` : ''}
                        ${deletable ? `<button class="tool-delete-btn" data-name="${safeName}" title="Delete skill">
                            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6"/><path d="M14 11v6"/><path d="M9 6V4h6v2"/></svg>
                            </button>` : ''}
                        </div>
                    </div>
                    <div class="tool-card-desc">${deps.helpers.escapeHtml(tool.description || '(no description)')}</div>
                    <div class="tool-card-meta" style="margin-top:6px;font-size:.72rem;color:var(--text-secondary)">${metaHtml}</div>`;

                const toggle = card.querySelector('.tool-enable-toggle');
                if (toggle) {
                    toggle.addEventListener('change', async () => {
                        const enabled = !!toggle.checked;
                        card.classList.toggle('tool-card-disabled', !enabled);
                        try {
                            await persistToolToggle(tool.name, enabled);
                        } catch (error) {
                            toggle.checked = !enabled;
                            card.classList.toggle('tool-card-disabled', enabled);
                            alert(`Failed to update skill state for ${tool.name}: ${error.message}`);
                        }
                    });
                }

                if (deletable) {
                    card.querySelector('.tool-delete-btn').addEventListener('click', async () => {
                        if (!confirm(`Delete skill "${tool.name}"?`)) return;
                        await deps.authFetch(`/api/tools/${tool.name}`, { method: 'DELETE' });
                        const appSettings = deps.state.getAppSettings();
                        const map = (appSettings.tool_enabled_map && typeof appSettings.tool_enabled_map === 'object')
                            ? { ...appSettings.tool_enabled_map }
                            : {};
                        if (Object.prototype.hasOwnProperty.call(map, tool.name)) {
                            delete map[tool.name];
                            appSettings.tool_enabled_map = map;
                            await deps.authFetch('/api/settings', {
                                method: 'POST',
                                headers: { 'Content-Type': 'application/json' },
                                body: JSON.stringify({ tool_enabled_map: map }),
                            });
                        }
                        loadToolsPane();
                    });
                }

                const sourceBtn = card.querySelector('.tool-source-btn');
                if (sourceBtn) {
                    sourceBtn.addEventListener('click', async () => {
                        try {
                            const data = await deps.authFetchJson(`/api/tools/${encodeURIComponent(tool.name)}/source`);
                            document.getElementById('skill-source-title').textContent = data.name || tool.name;
                            document.getElementById('skill-source-desc').textContent = data.description || '';
                            document.getElementById('skill-source-args').textContent = data.args ? JSON.stringify(data.args, null, 2) : '';
                            document.getElementById('skill-source-code').textContent = data.source || '(source unavailable)';
                            const overlay = document.getElementById('skill-source-overlay');
                            if (overlay) overlay.style.display = 'flex';
                        } catch (error) {
                            alert(`Failed to load source: ${error.message}`);
                        }
                    });
                }

                return card;
            }

            try {
                const runtimeRes = await deps.authFetchJson('/api/tools/runtime');
                const runtimeTools = Array.isArray(runtimeRes.tools) ? [...runtimeRes.tools] : [];
                const builtinTools = runtimeTools.filter((tool) => String(tool.source || '') === 'builtin');
                const customTools = runtimeTools.filter((tool) => String(tool.source || '') === 'custom');
                const mcpTools = runtimeTools.filter((tool) => String(tool.source || '').startsWith('mcp'));

                builtinList.innerHTML = '';
                builtinTools
                    .sort((left, right) => String(left.name || '').localeCompare(String(right.name || '')))
                    .forEach((tool) => builtinList.appendChild(renderTool(tool, { deletable: false, allowToggle: true })));

                customList.innerHTML = '';
                const custom = customTools
                    .sort((left, right) => String(left.name || '').localeCompare(String(right.name || '')));
                custom.forEach((tool) => customList.appendChild(renderTool(tool, { deletable: true, allowToggle: true })));
                if (emptyNote) emptyNote.style.display = custom.length ? 'none' : 'block';

                if (mcpList) {
                    mcpList.innerHTML = '';
                    mcpTools
                        .sort((left, right) => String(left.name || '').localeCompare(String(right.name || '')))
                        .forEach((tool) => mcpList.appendChild(renderTool(tool, { deletable: false, allowToggle: false })));
                }
                if (mcpNote) mcpNote.style.display = mcpTools.length ? 'none' : 'block';
            } catch (error) {
                if (builtinList) builtinList.innerHTML = `<p class="settings-note err">❌ Failed to load skills: ${deps.helpers.escapeHtml(error.message)}</p>`;
                if (customList) customList.innerHTML = '';
                if (mcpList) mcpList.innerHTML = '';
            }
        }

        function bindUi() {
            if (uiBound) return;
            uiBound = true;

            document.querySelectorAll('.settings-nav .settings-nav-item[data-pane]').forEach((button) => {
                button.addEventListener('click', () => {
                    document.querySelectorAll('.settings-nav .settings-nav-item[data-pane]').forEach((item) => item.classList.remove('active'));
                    document.querySelectorAll('.settings-pane').forEach((pane) => pane.classList.remove('active'));
                    button.classList.add('active');
                    const pane = document.getElementById(button.dataset.pane);
                    if (pane) pane.classList.add('active');
                    if (button.dataset.pane === 'pane-tools') loadToolsPane();
                    if (button.dataset.pane === 'pane-models') {
                        deps.helpers.loadOllamaLibrary();
                        deps.helpers.loadOllamaInstalled();
                    }
                    if (button.dataset.pane === 'pane-systemlog') loadSystemLog();
                    if (button.dataset.pane === 'pane-context') loadWikiKnowledgePanel();
                });
            });

            document.querySelectorAll('.settings-sub-tab').forEach((tab) => {
                tab.addEventListener('click', () => {
                    const nav = tab.closest('.settings-sub-nav');
                    const pane = tab.closest('.settings-pane');
                    if (!nav || !pane) return;
                    nav.querySelectorAll('.settings-sub-tab').forEach((item) => item.classList.remove('active'));
                    pane.querySelectorAll('.settings-sub-pane').forEach((subPane) => subPane.classList.remove('active'));
                    tab.classList.add('active');
                    const sub = document.getElementById(tab.dataset.sub);
                    if (sub) sub.classList.add('active');
                    if (tab.dataset.sub === 'models-ollama') {
                        deps.helpers.loadOllamaLibrary();
                        deps.helpers.loadOllamaInstalled();
                    }
                });
            });

            const systemLogClearBtn = document.getElementById('systemlog-clear-btn');
            if (systemLogClearBtn) {
                systemLogClearBtn.addEventListener('click', async () => {
                    if (!confirm('Clear the entire system log?')) return;
                    const list = document.getElementById('systemlog-list');
                    if (list) list.innerHTML = '';
                    const empty = document.getElementById('systemlog-empty');
                    if (empty) empty.style.display = '';
                    try {
                        await deps.authFetch('/api/system-log', { method: 'DELETE' });
                    } catch {}
                });
            }

            const wikiRefreshBtn = document.getElementById('wiki-refresh-btn');
            if (wikiRefreshBtn) wikiRefreshBtn.addEventListener('click', () => loadWikiKnowledgePanel());

            const toolsSearch = document.getElementById('tools-search');
            if (toolsSearch) {
                toolsSearch.addEventListener('input', () => {
                    const query = toolsSearch.value.toLowerCase();
                    document.querySelectorAll('#tools-builtin-list .tool-card, #tools-custom-list .tool-card, #tools-mcp-list .tool-card').forEach((card) => {
                        const name = (card.querySelector('.tool-card-name')?.textContent || '').toLowerCase();
                        const desc = (card.querySelector('.tool-card-desc')?.textContent || '').toLowerCase();
                        const meta = (card.querySelector('.tool-card-meta')?.textContent || '').toLowerCase();
                        card.style.display = (!query || name.includes(query) || desc.includes(query) || meta.includes(query)) ? '' : 'none';
                    });
                });
            }

            const sourceOverlay = document.getElementById('skill-source-overlay');
            const sourceClose = document.getElementById('skill-source-close');
            if (sourceClose) sourceClose.addEventListener('click', () => { sourceOverlay.style.display = 'none'; });
            if (sourceOverlay) {
                sourceOverlay.addEventListener('click', (event) => {
                    if (event.target === sourceOverlay) sourceOverlay.style.display = 'none';
                });
            }
        }

        return {
            bindUi,
            loadWikiStatus,
        };
    };
})();