/**
 * Status Dot Feature - Health indicator
 */

import {
    get,
    getToolsStatus,
    post,
    resetIndex,
    getWatcherStatus,
    forceDeleteDb,
    listDbBackups,
    saveDbBackup,
    restoreDbBackup,
    vectorBackfill,
    unloadVectorModels,
} from "../../api/client.js";
import { ENDPOINTS } from "../../api/endpoints.js";
import { APP_CONFIG } from "../../app/config.js";
import { comfyConfirm } from "../../app/dialogs.js";
import { comfyToast, recordToastHistory } from "../../app/toast.js";
import { t } from "../../app/i18n.js";
import {
    getRuntimeEnrichmentState,
    setRuntimeEnrichmentState,
} from "../../stores/runtimeEnrichmentState.js";
import { loadMajoorSettings } from "../../app/settings.js";
import { EVENTS } from "../../app/events.js";

const TOOL_CAPABILITIES = [
    {
        key: "exiftool",
        labelKey: "tool.exiftool",
        hintKey: "tool.exiftool.hint",
    },
    {
        key: "ffprobe",
        labelKey: "tool.ffprobe",
        hintKey: "tool.ffprobe.hint",
    },
];

let _maintenanceActive = false;
let _dbRestoreStatusHandler: any = null;
let _runtimeStatusHandler: any = null;
const STATUS_CACHE_KEY = "__MJR_STATUS_DOT_CACHE__";
const STATUS_POLL_STATE = {
    ACTIVE: "active",
    COOLDOWN: "cooldown",
    IDLE: "idle",
};
const STATUS_POLL_INTERVALS_MS = {
    [STATUS_POLL_STATE.ACTIVE]: 2_000,
    [STATUS_POLL_STATE.COOLDOWN]: 10_000,
    [STATUS_POLL_STATE.IDLE]: 60_000,
};

function setMaintenanceActive(active: any) {
    _maintenanceActive = !!active;
    try {
        (globalThis as any)._mjrMaintenanceActive = _maintenanceActive;
    } catch (e) {
        console.debug?.(e);
    }
}

function formatBytes(bytes: any) {
    const n = Number(bytes);
    if (!Number.isFinite(n) || n <= 0) return "0 B";
    const units = ["B", "KB", "MB", "GB", "TB"];
    let value = n;
    let idx = 0;
    while (value >= 1024 && idx < units.length - 1) {
        value /= 1024;
        idx += 1;
    }
    const precision = value >= 100 ? 0 : value >= 10 ? 1 : 2;
    return `${value.toFixed(precision)} ${units[idx]}`;
}

function setStatusLines(statusText: any, lines: any, footerText: any = null) {
    if (!statusText) return;
    statusText.replaceChildren();

    const normalizedLines = Array.isArray(lines)
        ? lines.filter((l) => l != null && String(l).trim() !== "")
        : [];
    normalizedLines.forEach((line, index) => {
        if (index > 0) statusText.appendChild(document.createElement("br"));
        statusText.appendChild(document.createTextNode(String(line)));
    });

    if (footerText != null && String(footerText).trim() !== "") {
        statusText.appendChild(document.createElement("br"));
        const span = document.createElement("span");
        span.style.fontSize = "11px";
        span.style.opacity = "0.6";
        span.textContent = String(footerText);
        statusText.appendChild(span);
    }
}

function appendStatusProgressBars(statusText: any, items: any[] = []) {
    if (!statusText) return;
    const rows = Array.isArray(items)
        ? items.filter((item) => item && String(item.label || "").trim())
        : [];
    if (!rows.length) return;

    const wrap = document.createElement("div");
    wrap.className = "mjr-status-progress-list";
    wrap.style.cssText =
        "margin-top:8px;display:flex;flex-direction:column;gap:5px;min-width:220px;";

    for (const item of rows) {
        const percent = Math.max(0, Math.min(100, Number(item.percent) || 0));
        const row = document.createElement("div");
        row.className = "mjr-status-progress-row";
        row.style.cssText = "display:grid;grid-template-columns:minmax(72px,0.9fr) 1.8fr auto;gap:7px;align-items:center;";

        const label = document.createElement("span");
        label.className = "mjr-status-progress-label";
        label.textContent = String(item.label || "");
        label.style.cssText = "font-size:10px;opacity:0.72;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;";

        const bar = document.createElement("div");
        bar.className = "mjr-status-progress-bar";
        bar.style.cssText =
            "height:6px;border-radius:999px;background:rgba(255,255,255,0.12);overflow:hidden;";

        const fill = document.createElement("div");
        fill.className = "mjr-status-progress-fill";
        fill.style.cssText = `height:100%;width:${percent}%;border-radius:999px;background:${item.color || "var(--mjr-status-info, #64B5F6)"};`;
        bar.appendChild(fill);

        const value = document.createElement("span");
        value.className = "mjr-status-progress-value";
        value.textContent = String(item.value || `${Math.round(percent)}%`);
        value.style.cssText = "font-size:10px;opacity:0.72;white-space:nowrap;text-align:right;";

        row.appendChild(label);
        row.appendChild(bar);
        row.appendChild(value);
        wrap.appendChild(row);
    }

    statusText.appendChild(wrap);
}

function buildStatusProgressItems(counters: any, { totalAssets = 0, withWorkflows = 0, withGenerationData = 0 } = {}) {
    const total = Math.max(0, Number(totalAssets || counters?.total_assets || 0) || 0);
    if (total <= 0) return [];
    const pct = (value: any, denominator = total) => {
        const n = Math.max(0, Number(value || 0) || 0);
        const d = Math.max(1, Number(denominator || 0) || 1);
        return Math.round((n / d) * 100);
    };
    const images = Number(counters?.images || 0) || 0;
    const videos = Number(counters?.videos || 0) || 0;
    const audio = Number(counters?.audio || 0) || 0;
    const model3d = Number(counters?.model3d || counters?.by_kind?.model3d || 0) || 0;
    const enrichQueue = Math.max(0, Number(counters?.enrichment_queue_length || 0) || 0);
    const enrichDenominator = Math.max(total, total + enrichQueue);

    return [
        {
            label: "Images",
            percent: pct(images),
            value: `${images.toLocaleString()} / ${pct(images)}%`,
            color: "var(--mjr-badge-image, #2196F3)",
        },
        {
            label: "Videos",
            percent: pct(videos),
            value: `${videos.toLocaleString()} / ${pct(videos)}%`,
            color: "var(--mjr-badge-video, #F44336)",
        },
        audio || model3d
            ? {
                  label: "Other",
                  percent: pct(audio + model3d),
                  value: `${(audio + model3d).toLocaleString()} / ${pct(audio + model3d)}%`,
                  color: "var(--mjr-status-browser, #26A69A)",
              }
            : null,
        {
            label: "Workflows",
            percent: pct(withWorkflows),
            value: `${Number(withWorkflows || 0).toLocaleString()} / ${pct(withWorkflows)}%`,
            color: "var(--mjr-status-success, #4CAF50)",
        },
        {
            label: "Gen data",
            percent: pct(withGenerationData),
            value: `${Number(withGenerationData || 0).toLocaleString()} / ${pct(withGenerationData)}%`,
            color: "var(--mjr-status-warning, #FFA726)",
        },
        enrichQueue
            ? {
                  label: "Enrich queue",
                  percent: pct(enrichQueue, enrichDenominator),
                  value: `${enrichQueue.toLocaleString()} pending`,
                  color: "var(--mjr-status-info, #64B5F6)",
              }
            : null,
    ].filter(Boolean);
}

function setStatusWithHint(statusText: any, mainText: any, hintText: any) {
    if (!statusText) return;
    statusText.replaceChildren();
    statusText.appendChild(document.createTextNode(String(mainText || "")));
    statusText.appendChild(document.createElement("br"));
    const span = document.createElement("span");
    span.style.fontSize = "11px";
    span.style.opacity = "0.7";
    span.textContent = String(hintText || "");
    statusText.appendChild(span);
}

function applyStatusHighlight(section: any, tone = "neutral", options: Record<string, any> = {}) {
    if (!section) return;
    const notifyToast = options?.toast !== false;
    const map = {
        neutral: {
            bg: "var(--bg-color, #1a1a1a)",
            border: "var(--border-color, #333)",
            glow: "transparent",
        },
        info: {
            bg: "linear-gradient(135deg, rgba(33,150,243,0.14) 0%, rgba(100,181,246,0.08) 100%)",
            border: "rgba(33,150,243,0.55)",
            glow: "rgba(33,150,243,0.15)",
        },
        success: {
            bg: "linear-gradient(135deg, rgba(76,175,80,0.16) 0%, rgba(139,195,74,0.08) 100%)",
            border: "rgba(76,175,80,0.55)",
            glow: "rgba(76,175,80,0.16)",
        },
        warning: {
            bg: "linear-gradient(135deg, rgba(255,167,38,0.18) 0%, rgba(255,193,7,0.08) 100%)",
            border: "rgba(255,167,38,0.58)",
            glow: "rgba(255,167,38,0.18)",
        },
        error: {
            bg: "linear-gradient(135deg, rgba(244,67,54,0.18) 0%, rgba(239,83,80,0.08) 100%)",
            border: "rgba(244,67,54,0.62)",
            glow: "rgba(244,67,54,0.2)",
        },
        browser: {
            bg: "linear-gradient(135deg, rgba(0,150,136,0.18) 0%, rgba(38,166,154,0.08) 100%)",
            border: "rgba(0,150,136,0.58)",
            glow: "rgba(0,150,136,0.18)",
        },
        workflow: {
            bg: "linear-gradient(135deg, rgba(186,104,200,0.20) 0%, rgba(244,143,177,0.14) 100%)",
            border: "rgba(216,127,186,0.62)",
            glow: "rgba(198,120,194,0.22)",
        },
    };
    const style = (map as Record<string, any>)[tone] || map.neutral;
    const prevTone = String(section.dataset?.mjrStatusTone || "neutral");
    section.style.background = style.bg;
    section.style.borderColor = style.border;
    section.style.boxShadow = `0 0 0 1px ${style.glow} inset`;
    section.dataset.mjrStatusTone = tone;

    // Toast only when status tone changes, throttled to avoid polling spam.
    if (notifyToast && tone !== prevTone) {
        const now = Date.now();
        const lastAt = Number(section._mjrStatusToastAt || 0) || 0;
        if (now - lastAt >= 4000) {
            section._mjrStatusToastAt = now;
            const messages = {
                info: t("status.toast.info", "Index status: checking"),
                success: t("status.toast.success", "Index status: ready"),
                warning: t("status.toast.warning", "Index status: attention needed"),
                error: t("status.toast.error", "Index status: error"),
                browser: t("status.toast.browser", "Index status: browser scope"),
                workflow: t("status.toast.workflow", "Index status: workflow scope"),
            };
            const level =
                tone === "error"
                    ? "error"
                    : tone === "warning"
                      ? "warning"
                      : tone === "success"
                        ? "success"
                        : "info";
            try {
                comfyToast((messages as Record<string, any>)[tone] || messages.info, level, 1800, { noHistory: true });
            } catch (e) {
                console.debug?.(e);
            }
        }
    }
}

function formatWatcherScopeLabel(scope: any) {
    const s = String(scope || "").toLowerCase();
    if (s === "all") return t("scope.allFull", "All (Inputs + Outputs)");
    if (s === "input" || s === "inputs") return t("scope.input", "Inputs");
    if (s === "custom") return t("scope.custom", "Browser");
    if (s === "workflow") return t("scope.workflow", "Workflow");
    return t("scope.output", "Outputs");
}

function formatWatcherLine(watcher: any, desiredScope = "") {
    if (!watcher || typeof watcher !== "object") {
        if (desiredScope) {
            return t("status.watcher.disabledScoped", "Watcher: disabled ({scope})", {
                scope: formatWatcherScopeLabel(desiredScope),
            });
        }
        return t("status.watcher.disabled", "Watcher: disabled");
    }
    const enabled = !!watcher.enabled;
    const scope = watcher.scope ? String(watcher.scope) : "";
    if (!enabled) {
        if (scope || desiredScope) {
            const effective =
                desiredScope && scope && scope !== desiredScope
                    ? desiredScope
                    : scope || desiredScope;
            return t("status.watcher.disabledScoped", "Watcher: disabled ({scope})", {
                scope: formatWatcherScopeLabel(effective),
            });
        }
        return t("status.watcher.disabled", "Watcher: disabled");
    }
    if (scope) {
        return t("status.watcher.enabledScoped", `Watcher: enabled (${scope})`, {
            scope: formatWatcherScopeLabel(scope),
        });
    }
    return t("status.watcher.enabled", "Watcher: enabled");
}

function emitGlobalGridReload(reason = "status-action") {
    try {
        window?.dispatchEvent?.(
            new CustomEvent("mjr:reload-grid", {
                detail: { reason: String(reason || "status-action") },
            }),
        );
    } catch (e) {
        console.debug?.(e);
    }
}

function markGridDirty(reason = "status-action", detail = {}) {
    try {
        window?.dispatchEvent?.(
            new CustomEvent("mjr-grid-dirty", {
                detail: {
                    reason: String(reason || "status-action"),
                    ...detail,
                },
            }),
        );
    } catch (e) {
        console.debug?.(e);
    }
}

function requestOpenMessageHistory(reason = "") {
    try {
        window?.dispatchEvent?.(
            new CustomEvent(EVENTS.OPEN_MESSAGE_HISTORY, {
                detail: { reason: String(reason || "status-action") },
            }),
        );
    } catch (e) {
        console.debug?.(e);
    }
}

async function askKeepVectors(actionLabel = "") {
    return await comfyConfirm(
        t(
            "dialog.vectorsReset.keepQuestion",
            "Keep existing AI vectors?\n\nConfirm = keep vectors\nCancel = continue without vectors",
        ),
        actionLabel || t("dialog.vectorsReset.title", "AI vectors"),
    );
}

/**
 * Create status indicator section
 */
export function createStatusIndicator(options: Record<string, any> = {}): any {
    const getScanContext =
        typeof options?.getScanContext === "function" ? options.getScanContext : null;
    // Reset any stale local maintenance lock when panel is recreated.
    // Runtime state is re-detected from backend diagnostics during polling.
    setMaintenanceActive(false);
    const section = document.createElement("div");
    section.style.cssText =
        "margin-bottom: 20px; padding: 12px; background: var(--bg-color, #1a1a1a); border-radius: 6px; border: 1px solid var(--border-color, #333); cursor: pointer; transition: all 0.2s;";
    applyStatusHighlight(section, "info", { toast: false });

    // Header container
    const header = document.createElement("div");
    header.style.cssText = "display: flex; align-items: center; gap: 10px; margin-bottom: 8px;";

    // Status dot
    const statusDot = document.createElement("span");
    statusDot.id = "mjr-status-dot";
    statusDot.style.cssText =
        "width: 12px; height: 12px; border-radius: 50%; background: var(--mjr-status-info, #64B5F6); display: inline-block; cursor: pointer;";

    // Title container
    const titleSpan = document.createElement("span");
    titleSpan.id = "mjr-status-title";
    titleSpan.style.cssText = "font-weight: 500; font-size: 13px; cursor: pointer;";

    const indicator = document.createElement("span");
    indicator.id = "mjr-status-title-indicator";
    indicator.style.marginRight = "6px";
    indicator.textContent = "v";

    titleSpan.appendChild(indicator);
    titleSpan.appendChild(document.createTextNode(t("status.indexStatus", "Index Status")));

    header.appendChild(statusDot);
    header.appendChild(titleSpan);

    // Body container
    const body = document.createElement("div");
    body.id = "mjr-status-body";
    body.style.marginLeft = "22px";

    // Status text
    const statusText = document.createElement("div");
    statusText.id = "mjr-status-text";
    statusText.style.cssText = "font-size: 12px; opacity: 0.8;";
    statusText.textContent = t("status.checking");

    // Capabilities section
    const capabilities = document.createElement("div");
    capabilities.id = "mjr-status-capabilities";
    capabilities.style.cssText =
        "font-size: 11px; opacity: 0.75; margin-top: 10px; display: flex; gap: 6px; flex-wrap: wrap;";
    capabilities.textContent = t("status.discoveringTools");

    body.appendChild(statusText);
    body.appendChild(capabilities);

    const toolsStatus = document.createElement("div");
    toolsStatus.id = "mjr-tools-status";
    toolsStatus.style.cssText = "font-size: 11px; opacity: 0.7; margin-top: 10px;";
    toolsStatus.textContent = t("status.toolStatusChecking", "Tool status: checking...");
    body.appendChild(toolsStatus);

    const backupRow = document.createElement("div");
    backupRow.style.cssText =
        "margin-top: 10px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap;";

    const backupSelect = document.createElement("select");
    backupSelect.style.cssText = `
        min-width: 240px;
        padding: 4px 8px;
        font-size: 11px;
        border-radius: 6px;
        border: 1px solid rgba(255,255,255,0.2);
        background: rgba(255,255,255,0.04);
        color: inherit;
    `;
    backupSelect.title = t("status.dbBackupSelectHint", "Select a DB backup to restore");
    let _hasBackupChoices = false;
    let restoreDbBtn: any = null;
    const setSingleOption = (text: any) => {
        backupSelect.replaceChildren();
        const opt = document.createElement("option");
        opt.value = "";
        opt.textContent = String(text || "");
        opt.disabled = true;
        opt.selected = true;
        backupSelect.appendChild(opt);
        _hasBackupChoices = false;
        backupSelect.disabled = true;
        if (restoreDbBtn) restoreDbBtn.disabled = true;
    };
    setSingleOption(t("status.dbBackupLoading", "Loading DB backups..."));

    const refreshBackups = async (preferredName = "") => {
        try {
            const res = await listDbBackups();
            if (!res?.ok) {
                setSingleOption(t("status.dbBackupNone", "No DB backup found"));
                return;
            }
            const items = Array.isArray(res?.data?.items) ? res.data.items : [];
            if (!items.length) {
                setSingleOption(t("status.dbBackupNone", "No DB backup found"));
                return;
            }
            backupSelect.replaceChildren();
            let matched = false;
            for (const item of items) {
                const name = String(item?.name || "");
                if (!name) continue;
                const mtime = Number(item?.mtime || 0);
                const size = Number(item?.size_bytes || 0);
                const stamp = mtime > 0 ? new Date(mtime * 1000).toLocaleString() : "";
                const label = `${name}${stamp ? ` (${stamp}` : ""}${size > 0 ? `, ${formatBytes(size)}` : ""}${stamp ? ")" : ""}`;
                const opt = document.createElement("option");
                opt.value = name;
                opt.textContent = label;
                if (preferredName && preferredName === name) {
                    opt.selected = true;
                    matched = true;
                }
                backupSelect.appendChild(opt);
            }
            _hasBackupChoices = backupSelect.childNodes.length > 0;
            backupSelect.disabled = !_hasBackupChoices;
            if (_hasBackupChoices && !matched && backupSelect.childNodes[0]) {
                backupSelect.value = String((backupSelect.childNodes[0] as HTMLOptionElement)?.value || "");
            }
            if (restoreDbBtn) restoreDbBtn.disabled = !_hasBackupChoices;
        } catch {
            setSingleOption(t("status.dbBackupNone", "No DB backup found"));
        }
    };
    void refreshBackups();
    backupRow.appendChild(backupSelect);

    const saveDbBtn = document.createElement("button");
    saveDbBtn.type = "button";
    saveDbBtn.textContent = t("btn.dbSave", "Save DB");
    saveDbBtn.title = t("status.dbSaveHint", "Save a DB snapshot into archive folder");
    saveDbBtn.style.cssText = `
        padding: 5px 10px;
        font-size: 11px;
        border-radius: 6px;
        border: 1px solid rgba(120,200,255,0.35);
        background: transparent;
        color: inherit;
        cursor: pointer;
    `;
    saveDbBtn.onclick = async (event) => {
        event.stopPropagation();
        setMaintenanceActive(true);
        const original = saveDbBtn.textContent;
        const originalRestoreDisabled = !!restoreDbBtn?.disabled;
        saveDbBtn.disabled = true;
        if (restoreDbBtn) restoreDbBtn.disabled = true;
        saveDbBtn.textContent = t("btn.saving", "Saving...");
        statusDot.style.background = "var(--mjr-status-info, #64B5F6)";
        applyStatusHighlight(section, "info");
        try {
            const res = await saveDbBackup();
            if (res?.ok) {
                const savedName = String(res?.data?.name || "").trim();
                const sizeBytes = Number(res?.data?.size_bytes || 0);
                comfyToast(t("toast.dbSaveSuccess", "Database backup saved"), "success", 2200, {
                    history: {
                        title: t("btn.dbSave", "Save DB"),
                        detail: savedName
                            ? `${savedName}${sizeBytes > 0 ? ` | ${formatBytes(sizeBytes)}` : ""}`
                            : t("toast.dbSaveSuccess", "Database backup saved"),
                        operation: "save_db",
                        source: savedName || "archive",
                        forceStore: true,
                    },
                });
                await refreshBackups(savedName);
            } else {
                comfyToast(
                    res?.error || t("toast.dbSaveFailed", "Failed to save DB backup"),
                    "error",
                );
            }
        } catch (error: any) {
            comfyToast(
                error?.message || t("toast.dbSaveFailed", "Failed to save DB backup"),
                "error",
            );
        } finally {
            setMaintenanceActive(false);
            saveDbBtn.disabled = false;
            if (restoreDbBtn) restoreDbBtn.disabled = originalRestoreDisabled || !_hasBackupChoices;
            saveDbBtn.textContent = original;
            try {
                const target = getScanContext ? getScanContext() : null;
                await updateStatus(statusDot, statusText, capabilities, target, null, {
                    force: true,
                });
            } catch (e) {
                console.debug?.(e);
            }
        }
    };
    backupRow.appendChild(saveDbBtn);

    restoreDbBtn = document.createElement("button");
    restoreDbBtn.type = "button";
    restoreDbBtn.textContent = t("btn.dbRestore", "Restore");
    restoreDbBtn.title = t("status.dbRestoreHint", "Restore selected DB backup");
    restoreDbBtn.style.cssText = `
        padding: 5px 10px;
        font-size: 11px;
        border-radius: 6px;
        border: 1px solid rgba(255,180,80,0.35);
        background: transparent;
        color: inherit;
        cursor: pointer;
    `;
    restoreDbBtn.onclick = async (event: any) => {
        event.stopPropagation();
        const selected = String(backupSelect.value || "");
        if (!selected) {
            comfyToast(t("toast.dbRestoreSelect", "Select a DB backup first"), "warning", 2000);
            return;
        }
        const confirmed = await comfyConfirm(
            `${t(
                "dialog.dbRestore.confirm",
                "Restore selected DB backup? Current DB will be replaced.",
            )}\n\n${selected}`,
            t("btn.dbRestore", "Restore DB"),
        );
        if (!confirmed) return;
        comfyToast(t("toast.dbRestoreStarted", "DB restore started"), "info", 1800, {
            history: {
                trackId: "maintenance:restore_db",
                title: t("btn.dbRestore", "Restore DB"),
                detail: selected,
                operation: "restore_db",
                source: selected,
                status: "started",
                forceStore: true,
            },
        });
        setMaintenanceActive(true);
        const original = restoreDbBtn.textContent;
        const originalSaveDisabled = !!saveDbBtn.disabled;
        restoreDbBtn.disabled = true;
        saveDbBtn.disabled = true;
        backupSelect.disabled = true;
        restoreDbBtn.textContent = t("btn.restoring", "Restoring...");
        statusDot.style.background = "var(--mjr-status-warning, #FFA726)";
        applyStatusHighlight(section, "warning");
        try {
            const res = await restoreDbBackup({ name: selected, useLatest: false });
            if (res?.ok) {
                await refreshBackups(String(res?.data?.name || selected || ""));
            } else {
                comfyToast(
                    res?.error || t("toast.dbRestoreFailed", "Failed to restore DB backup"),
                    "error",
                );
            }
        } catch (error: any) {
            comfyToast(
                error?.message || t("toast.dbRestoreFailed", "Failed to restore DB backup"),
                "error",
            );
        } finally {
            setMaintenanceActive(false);
            restoreDbBtn.disabled = !_hasBackupChoices;
            saveDbBtn.disabled = originalSaveDisabled;
            backupSelect.disabled = !_hasBackupChoices;
            restoreDbBtn.textContent = original;
            emitGlobalGridReload("db-restore");
            try {
                const target = getScanContext ? getScanContext() : null;
                await updateStatus(statusDot, statusText, capabilities, target, null, {
                    force: true,
                });
            } catch (e) {
                console.debug?.(e);
            }
        }
    };
    backupRow.appendChild(restoreDbBtn);

    body.appendChild(backupRow);

    const actionsRow = document.createElement("div");
    actionsRow.style.cssText =
        "margin-top: 10px; display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap;";

    const actionLog = document.createElement("div");
    actionLog.style.cssText =
        "margin-top: 8px; font-size: 11px; opacity: 0.9; line-height: 1.35; white-space: pre-wrap;";
    actionLog.textContent = "";

    const setActionLog = (message: any, tone = "neutral") => {
        const text = String(message || "").trim();
        actionLog.textContent = text;
        if (!text) {
            actionLog.style.color = "inherit";
            actionLog.style.opacity = "0.9";
            return;
        }
        if (tone === "error") {
            actionLog.style.color = "var(--error-text-color, #ff8a80)";
            actionLog.style.opacity = "1";
            return;
        }
        if (tone === "success") {
            actionLog.style.color = "var(--success-text-color, #a5d6a7)";
            actionLog.style.opacity = "1";
            return;
        }
        if (tone === "info") {
            actionLog.style.color = "var(--input-text, #cfd8dc)";
            actionLog.style.opacity = "0.95";
            return;
        }
        actionLog.style.color = "inherit";
        actionLog.style.opacity = "0.9";
    };

    let memoryPurgeBtn: HTMLButtonElement;

    const resetBtn = document.createElement("button");
    resetBtn.type = "button";
    resetBtn.textContent = t("btn.resetIndex");
    resetBtn.title = t(
        "status.resetIndexHint",
        "Reset index cache (requires allowResetIndex in settings).",
    );
    resetBtn.style.cssText = `
        padding: 5px 12px;
        font-size: 11px;
        border-radius: 6px;
        border: 1px solid rgba(255,255,255,0.25);
        background: transparent;
        color: inherit;
        cursor: pointer;
        transition: border 0.2s, background 0.2s;
    `;
    resetBtn.onmouseenter = () => {
        resetBtn.style.borderColor = "rgba(255,255,255,0.6)";
        resetBtn.style.background = "rgba(255,255,255,0.08)";
    };
    resetBtn.onmouseleave = () => {
        resetBtn.style.borderColor = "rgba(255,255,255,0.25)";
        resetBtn.style.background = "transparent";
    };
    resetBtn.onclick = async (event) => {
        event.stopPropagation();
        const preserveVectors = await askKeepVectors(t("btn.resetIndex", "Reset index"));
        const confirmed = await comfyConfirm(
            preserveVectors
                ? t(
                      "dialog.resetIndex.confirmKeepVectors",
                      "This will reset index data and rescan files while keeping existing AI vectors.\n\nContinue?",
                  )
                : t(
                      "dialog.resetIndex.msg",
                      "This will delete the database and rescan all files. Continue?",
                  ),
            t("dialog.resetIndex.title", "Reset index?"),
        );
        if (!confirmed) return;
        requestOpenMessageHistory("reset-index");
        setMaintenanceActive(true);

        const originalText = resetBtn.textContent;
        resetBtn.disabled = true;
        memoryPurgeBtn.disabled = true;
        resetBtn.textContent = t("btn.resetting");

        // Status indicator feedback
        statusDot.style.background = "var(--mjr-status-info, #64B5F6)";
        applyStatusHighlight(section, "info");

        try {
            const ctx = getScanContext ? getScanContext() : {};
            const scope = String(ctx?.scope || "output").toLowerCase();
            const customRootId = ctx?.customRootId || ctx?.custom_root_id || ctx?.root_id || null;
            const isCustomBrowserMode = scope === "custom" && !customRootId;
            const isAll = scope === "all";
            const effectiveScope = isCustomBrowserMode ? "all" : scope;

            const res = await resetIndex({
                scope: effectiveScope,
                customRootId: isCustomBrowserMode ? null : customRootId,
                reindex: true,
                maintenance_force: true,
                hard_reset_db: isAll && !preserveVectors,
                clear_scan_journal: true,
                clear_metadata_cache: true,
                clear_asset_metadata: true,
                clear_assets: !preserveVectors,
                preserve_vectors: preserveVectors,
                rebuild_fts: true,
            });
            if (res?.ok) {
                statusDot.style.background = "var(--mjr-status-success, #4CAF50)";
                applyStatusHighlight(section, "success");
            } else {
                statusDot.style.background = "var(--mjr-status-error, #f44336)";
                applyStatusHighlight(section, "error");
            }
        } catch {
            statusDot.style.background = "var(--mjr-status-error, #f44336)";
            applyStatusHighlight(section, "error");
        } finally {
            setMaintenanceActive(false);
            resetBtn.disabled = false;
            memoryPurgeBtn.disabled = false;
            resetBtn.textContent = originalText;
            emitGlobalGridReload("index-reset");
            try {
                const target = getScanContext ? getScanContext() : null;
                await updateStatus(statusDot, statusText, capabilities, target, null, {
                    force: true,
                });
            } catch (e) {
                console.debug?.(e);
            }
        }
    };

    const backfillBtn = document.createElement("button");
    backfillBtn.type = "button";
    backfillBtn.textContent = "Backfill vectors";
    backfillBtn.title = "Compute missing AI vector embeddings for existing assets.";
    backfillBtn.style.cssText = `
        padding: 5px 12px;
        font-size: 11px;
        border-radius: 6px;
        border: 1px solid rgba(0, 188, 212, 0.45);
        background: transparent;
        color: inherit;
        cursor: pointer;
        transition: border 0.2s, background 0.2s;
    `;
    backfillBtn.onmouseenter = () => {
        backfillBtn.style.borderColor = "rgba(0, 188, 212, 0.8)";
        backfillBtn.style.background = "rgba(0, 188, 212, 0.12)";
    };
    backfillBtn.onmouseleave = () => {
        backfillBtn.style.borderColor = "rgba(0, 188, 212, 0.45)";
        backfillBtn.style.background = "transparent";
    };
    backfillBtn.onclick = async (event) => {
        event.stopPropagation();
        const ctx = getScanContext ? getScanContext() : {};
        const desiredScope = String(ctx?.scope || "output").toLowerCase();
        const desiredCustomRootId = String(
            ctx?.customRootId || ctx?.custom_root_id || ctx?.root_id || "",
        ).trim();
        const isCustomBrowserMode = desiredScope === "custom" && !desiredCustomRootId;
        if (isCustomBrowserMode) {
            comfyToast(
                t(
                    "status.customBrowserScanDisabledHint",
                    "Use Outputs, Inputs, or All to run indexing scans",
                ),
                "warning",
                2600,
            );
            setActionLog(
                "Backfill skipped - Browser scope has no selected custom root.",
                "warning",
            );
            return;
        }
        const backfillScope = desiredScope || "output";
        const backfillScopeLabel = formatWatcherScopeLabel(backfillScope);
        requestOpenMessageHistory("vector-backfill");
        const historyBase = {
            history: {
                trackId: `vector-backfill:status:${backfillScope}:${desiredCustomRootId || "default"}`,
                title: "Vector Backfill",
                source: backfillScopeLabel,
                operation: "vector_backfill",
                forceStore: true,
            },
        };
        setMaintenanceActive(true);

        const originalBackfillText = backfillBtn.textContent;
        const originalResetText = resetBtn.textContent;
        backfillBtn.disabled = true;
        resetBtn.disabled = true;
        memoryPurgeBtn.disabled = true;
        backfillBtn.textContent = "Backfilling...";
        setActionLog(`Backfill started (${backfillScopeLabel})...`, "info");
        recordToastHistory(
            { summary: "Vector Backfill", detail: `Started (${backfillScopeLabel})` },
            "info",
            0,
            {
                history: {
                    ...historyBase.history,
                    status: "started",
                    detail: `Started (${backfillScopeLabel})`,
                },
            },
        );

        statusDot.style.background = "var(--mjr-status-info, #64B5F6)";
        applyStatusHighlight(section, "info");
        try {
            const backfillOptions: Record<string, any> = {
                scope: backfillScope,
                onProgress: (payload: any) => {
                    const status = String(payload?.status || "").toLowerCase();
                    const progress = payload?.progress || payload?.result || {};
                    const candidates = Number(progress?.candidates || progress?.processed || 0);
                    const candidateTotal = Number(progress?.candidate_total || candidates || 0);
                    const totalAssets = Number(
                        progress?.eligible_total || progress?.total_assets || 0,
                    );
                    const indexed = Number(progress?.indexed || 0);
                    const skipped = Number(progress?.skipped || 0);
                    const errors = Number(progress?.errors || 0);
                    if (status === "queued") {
                        setActionLog("Backfill queued...", "info");
                        recordToastHistory(
                            {
                                summary: "Vector Backfill",
                                detail: `Queued (${backfillScopeLabel})`,
                            },
                            "info",
                            0,
                            {
                                history: {
                                    ...historyBase.history,
                                    status: "queued",
                                    detail: `Queued (${backfillScopeLabel})`,
                                    progress: { current: 0, total: 1, percent: 0, label: "queued" },
                                },
                            },
                        );
                        return;
                    }
                    if (
                        status === "running" ||
                        candidates > 0 ||
                        candidateTotal > 0 ||
                        totalAssets > 0 ||
                        indexed > 0 ||
                        skipped > 0 ||
                        errors > 0
                    ) {
                        const detailText =
                            totalAssets > 0
                                ? `Indexed ${indexed}/${totalAssets} assets, candidates ${candidateTotal}, skipped ${skipped}, errors ${errors}`
                                : `Candidates ${candidates}, indexed ${indexed}, skipped ${skipped}, errors ${errors}`;
                        setActionLog(
                            totalAssets > 0
                                ? `Backfill running - indexed ${indexed}/${totalAssets} assets, candidates ${candidateTotal}, skipped ${skipped}, errors ${errors}`
                                : `Backfill running - candidates ${candidates}, indexed ${indexed}, skipped ${skipped}, errors ${errors}`,
                            "info",
                        );
                        recordToastHistory(
                            { summary: "Vector Backfill", detail: detailText },
                            "info",
                            0,
                            {
                                history: {
                                    ...historyBase.history,
                                    status: "running",
                                    detail: detailText,
                                    progress: {
                                        current:
                                            totalAssets > 0 ? indexed : indexed + skipped + errors,
                                        total:
                                            totalAssets > 0
                                                ? totalAssets
                                                : Math.max(candidates, indexed + skipped + errors),
                                        percent:
                                            totalAssets > 0
                                                ? Math.round((indexed / totalAssets) * 100)
                                                : Math.max(candidates, indexed + skipped + errors) >
                                                    0
                                                  ? Math.round(
                                                        ((indexed + skipped + errors) /
                                                            Math.max(
                                                                candidates,
                                                                indexed + skipped + errors,
                                                            )) *
                                                            100,
                                                    )
                                                  : null,
                                        eligible_total: totalAssets > 0 ? totalAssets : undefined,
                                        candidate_total:
                                            candidateTotal > 0 ? candidateTotal : undefined,
                                        indexed,
                                        skipped,
                                        errors,
                                        label: "running",
                                    },
                                },
                            },
                        );
                    }
                },
            };
            if (backfillScope === "custom" && desiredCustomRootId) {
                backfillOptions.customRootId = desiredCustomRootId;
            }
            const res = await vectorBackfill(64, backfillOptions);
            if (res?.ok) {
                const state = String(res?.data?.status || "").toLowerCase();
                const pending =
                    !!res?.data?.pending || ["queued", "running", "pending"].includes(state);
                const progress = res?.data?.progress || {};
                const processed = Number(res?.data?.processed ?? progress?.candidates ?? 0);
                const indexed = Number(res?.data?.indexed ?? progress?.indexed ?? 0);
                const skipped = Number(res?.data?.skipped ?? progress?.skipped ?? 0);
                const errors = Number(res?.data?.errors ?? progress?.errors ?? 0);
                if (pending) {
                    const backfillId = String(res?.data?.backfill_id || "").trim();
                    const msg = t(
                        "toast.vectorBackfillRunning",
                        "Vector backfill still running in background{job}.",
                        { job: backfillId ? ` (${backfillId.slice(0, 8)})` : "" },
                    );
                    comfyToast(msg, "info", 4200, {
                        history: {
                            ...historyBase.history,
                            status: "running",
                            detail: `Running in background${backfillId ? ` (${backfillId.slice(0, 8)})` : ""}.`,
                            progress: {
                                current: indexed + skipped + errors,
                                total: Math.max(processed, indexed + skipped + errors),
                                percent:
                                    Math.max(processed, indexed + skipped + errors) > 0
                                        ? Math.round(
                                              ((indexed + skipped + errors) /
                                                  Math.max(processed, indexed + skipped + errors)) *
                                                  100,
                                          )
                                        : null,
                                indexed,
                                skipped,
                                errors,
                                label: "running",
                            },
                        },
                    });
                    setActionLog(
                        `Backfill running in background - candidates ${processed}, indexed ${indexed}, skipped ${skipped}, errors ${errors}`,
                        "info",
                    );
                    statusDot.style.background = "var(--mjr-status-info, #64B5F6)";
                    applyStatusHighlight(section, "info");
                } else {
                    comfyToast(
                        t(
                            "toast.vectorBackfillComplete",
                            "Vector backfill complete! Processed: {processed}, Indexed: {indexed}, Skipped: {skipped}",
                            { processed, indexed, skipped },
                        ),
                        "success",
                        3000,
                        {
                            history: {
                                ...historyBase.history,
                                status: "succeeded",
                                detail: `Processed ${processed}, indexed ${indexed}, skipped ${skipped}`,
                                progress: {
                                    current: processed,
                                    total: processed,
                                    percent: processed > 0 ? 100 : null,
                                    indexed,
                                    skipped,
                                    errors,
                                    label: "done",
                                },
                            },
                        },
                    );
                    setActionLog(
                        `Backfill OK - processed ${processed}, indexed ${indexed}, skipped ${skipped}`,
                        "success",
                    );
                    statusDot.style.background = "var(--mjr-status-success, #4CAF50)";
                    applyStatusHighlight(section, "success");
                }
            } else {
                const err = String(
                    res?.error || t("toast.vectorBackfillFailedGeneric", "Backfill failed"),
                );
                const code = String(res?.code || "").trim();
                const status = Number(res?.status || 0) || 0;
                const detail = [code ? `code=${code}` : "", status ? `status=${status}` : "", err]
                    .filter(Boolean)
                    .join(" | ");
                comfyToast(detail, "error", 4500, {
                    history: {
                        ...historyBase.history,
                        status: "failed",
                        detail,
                        progress: { label: "failed", errors: 1 },
                    },
                });
                setActionLog(`Backfill ? - ${detail}\nSee console for full payload.`, "error");
                console.error("[Majoor] Vector backfill failed response", res);
                statusDot.style.background = "var(--mjr-status-error, #f44336)";
                applyStatusHighlight(section, "error");
            }
        } catch (error: any) {
            const errText = String(error?.message || error || "Backfill failed");
            comfyToast(errText, "error", 4500, {
                history: {
                    ...historyBase.history,
                    status: "failed",
                    detail: errText,
                    progress: { label: "failed", errors: 1 },
                },
            });
            setActionLog(`Backfill EXCEPTION - ${errText}\nSee console for stack trace.`, "error");
            console.error("[Majoor] Vector backfill exception", error);
            statusDot.style.background = "var(--mjr-status-error, #f44336)";
            applyStatusHighlight(section, "error");
        } finally {
            setMaintenanceActive(false);
            backfillBtn.disabled = false;
            resetBtn.disabled = false;
            memoryPurgeBtn.disabled = false;
            backfillBtn.textContent = originalBackfillText;
            resetBtn.textContent = originalResetText;
            emitGlobalGridReload("vector-backfill");
            try {
                const target = getScanContext ? getScanContext() : null;
                await updateStatus(statusDot, statusText, capabilities, target, null, {
                    force: true,
                });
            } catch (e) {
                console.debug?.(e);
            }
        }
    };

    memoryPurgeBtn = document.createElement("button");
    memoryPurgeBtn.type = "button";
    memoryPurgeBtn.textContent = t("btn.memoryPurge", "Memory purge");
    memoryPurgeBtn.title = t(
        "tooltip.memoryPurge",
        "Unload Majoor AI models, ask ComfyUI to unload loaded models, and clear torch cache when idle.",
    );
    memoryPurgeBtn.style.cssText = `
        padding: 5px 12px;
        font-size: 11px;
        border-radius: 6px;
        border: 1px solid rgba(156, 204, 101, 0.45);
        background: transparent;
        color: inherit;
        cursor: pointer;
        transition: border 0.2s, background 0.2s;
    `;
    memoryPurgeBtn.onmouseenter = () => {
        memoryPurgeBtn.style.borderColor = "rgba(156, 204, 101, 0.85)";
        memoryPurgeBtn.style.background = "rgba(156, 204, 101, 0.12)";
    };
    memoryPurgeBtn.onmouseleave = () => {
        memoryPurgeBtn.style.borderColor = "rgba(156, 204, 101, 0.45)";
        memoryPurgeBtn.style.background = "transparent";
    };
    memoryPurgeBtn.onclick = async (event) => {
        event.stopPropagation();
        const originalText = memoryPurgeBtn.textContent;
        memoryPurgeBtn.disabled = true;
        backfillBtn.disabled = true;
        resetBtn.disabled = true;
        memoryPurgeBtn.textContent = t("btn.memoryPurging", "Purging...");
        setActionLog(t("status.memoryPurgeStarted", "Memory purge started..."), "info");
        statusDot.style.background = "var(--mjr-status-info, #64B5F6)";
        applyStatusHighlight(section, "info");
        try {
            const res = await unloadVectorModels();
            if (res?.ok) {
                const comfyPurged = !!res?.data?.comfy_models;
                const msg = comfyPurged
                    ? t(
                          "toast.memoryPurgeComplete",
                          "Memory purge complete. Majoor AI and ComfyUI model caches were released.",
                      )
                    : t(
                          "toast.memoryPurgeCompleteMajoorOnly",
                          "Memory purge complete. Majoor AI caches were released.",
                      );
                comfyToast(msg, "success", 3200);
                setActionLog(msg, "success");
                statusDot.style.background = "var(--mjr-status-success, #4CAF50)";
                applyStatusHighlight(section, "success");
            } else {
                const err = String(res?.error || "Memory purge failed");
                comfyToast(err, "error", 4500);
                setActionLog(err, "error");
                statusDot.style.background = "var(--mjr-status-error, #f44336)";
                applyStatusHighlight(section, "error");
            }
        } catch (error: any) {
            const err = String(error?.message || error || "Memory purge failed");
            comfyToast(err, "error", 4500);
            setActionLog(err, "error");
            statusDot.style.background = "var(--mjr-status-error, #f44336)";
            applyStatusHighlight(section, "error");
        } finally {
            memoryPurgeBtn.disabled = false;
            backfillBtn.disabled = false;
            resetBtn.disabled = false;
            memoryPurgeBtn.textContent = originalText;
            try {
                const target = getScanContext ? getScanContext() : null;
                await updateStatus(statusDot, statusText, capabilities, target, null, {
                    force: true,
                });
            } catch (e) {
                console.debug?.(e);
            }
        }
    };

    actionsRow.appendChild(backfillBtn);
    actionsRow.appendChild(memoryPurgeBtn);
    actionsRow.appendChild(resetBtn);
    body.appendChild(actionLog);

    const deleteDbBtn = document.createElement("button");
    deleteDbBtn.type = "button";
    deleteDbBtn.textContent = t("btn.deleteDb");
    deleteDbBtn.title = t("tooltip.deleteDb", "Force-delete database and rebuild from scratch");
    deleteDbBtn.style.cssText = `
        padding: 5px 12px;
        font-size: 11px;
        border-radius: 6px;
        border: 1px solid rgba(255,80,80,0.4);
        background: transparent;
        color: inherit;
        cursor: pointer;
        transition: border 0.2s, background 0.2s;
    `;
    deleteDbBtn.onmouseenter = () => {
        deleteDbBtn.style.borderColor = "rgba(255,80,80,0.8)";
        deleteDbBtn.style.background = "rgba(255,80,80,0.12)";
    };
    deleteDbBtn.onmouseleave = () => {
        deleteDbBtn.style.borderColor = "rgba(255,80,80,0.4)";
        deleteDbBtn.style.background = "transparent";
    };
    deleteDbBtn.onclick = async (event) => {
        event.stopPropagation();
        const preserveVectors = await askKeepVectors(t("btn.deleteDb", "Delete DB"));
        const confirmed = await comfyConfirm(
            preserveVectors
                ? t(
                      "dialog.dbDelete.keepVectorsConfirm",
                      "This will reset index data and keep existing AI vectors. Database files will not be force-deleted.\n\nContinue?",
                  )
                : t(
                      "dialog.dbDelete.confirm",
                      "This will permanently delete the index database and rebuild it from scratch. All ratings, tags, and cached metadata will be lost.\n\nContinue?",
                  ),
            t("btn.deleteDb", "Delete DB"),
        );
        if (!confirmed) return;
        setMaintenanceActive(true);

        const originalText = deleteDbBtn.textContent;
        deleteDbBtn.disabled = true;
        deleteDbBtn.textContent = preserveVectors
            ? t("btn.resetting", "Resetting...")
            : t("btn.deletingDb");
        resetBtn.disabled = true;
        memoryPurgeBtn.disabled = true;

        statusDot.style.background = "var(--mjr-status-info, #64B5F6)";
        applyStatusHighlight(section, "info");

        try {
            const res = preserveVectors
                ? await resetIndex({
                      scope: "all",
                      reindex: true,
                      maintenance_force: true,
                      hard_reset_db: false,
                      clear_scan_journal: true,
                      clear_metadata_cache: true,
                      clear_asset_metadata: true,
                      clear_assets: false,
                      preserve_vectors: true,
                      rebuild_fts: true,
                  })
                : await forceDeleteDb();
            if (res?.ok) {
                (globalThis as any)._mjrCorruptToastShown = false;
                statusDot.style.background = "var(--mjr-status-success, #4CAF50)";
                applyStatusHighlight(section, "success");
            } else {
                statusDot.style.background = "var(--mjr-status-error, #f44336)";
                applyStatusHighlight(section, "error");
            }
        } catch {
            statusDot.style.background = "var(--mjr-status-error, #f44336)";
            applyStatusHighlight(section, "error");
        } finally {
            setMaintenanceActive(false);
            deleteDbBtn.disabled = false;
            deleteDbBtn.textContent = originalText;
            resetBtn.disabled = false;
            memoryPurgeBtn.disabled = false;
            emitGlobalGridReload(
                preserveVectors ? "index-reset-preserve-vectors" : "db-force-delete",
            );
            try {
                const target = getScanContext ? getScanContext() : null;
                await updateStatus(statusDot, statusText, capabilities, target, null, {
                    force: true,
                });
            } catch (e) {
                console.debug?.(e);
            }
        }
    };

    actionsRow.appendChild(deleteDbBtn);
    body.appendChild(actionsRow);

    section.appendChild(header);
    section.appendChild(body);

    const title = section.querySelector("#mjr-status-title");
    if (title) {
        title.addEventListener("click", (event) => {
            event.stopPropagation();
            const body = section.querySelector("#mjr-status-body");
            if (!body) return;
            const collapsed = (body as HTMLElement).style.display === "none";
            setBodyCollapsed(section, !collapsed);
        });
    }

    setBodyCollapsed(section, true);
    // Add hover effect
    section.onmouseenter = () => {
        section.style.transform = "translateY(-1px)";
    };
    section.onmouseleave = () => {
        section.style.transform = "";
        applyStatusHighlight(section, section.dataset?.mjrStatusTone || "neutral", {
            toast: false,
        });
    };

    const onDbRestoreStatus = async (event: any) => {
        try {
            const detail = event?.detail || {};
            const step = String(detail?.step || "");
            if (!step) return;

            const isMaintenanceStep =
                step === "started" ||
                step === "stopping_workers" ||
                step === "resetting_db" ||
                step === "delete_db" ||
                step === "recreate_db" ||
                step === "replacing_files" ||
                step === "restarting_scan";

            // Keep global maintenance lock in sync even if the old panel was closed.
            if (isMaintenanceStep) {
                setMaintenanceActive(true);
            } else if (step === "failed" || step === "done") {
                setMaintenanceActive(false);
            }

            if (!section?.isConnected || !statusDot?.isConnected || !statusText?.isConnected)
                return;

            if (isMaintenanceStep) {
                statusDot.style.background = "var(--mjr-status-info, #64B5F6)";
                applyStatusHighlight(section, "info", { toast: false });
                setStatusWithHint(
                    statusText,
                    t("status.pending", "Pending..."),
                    t("status.dbRestoreInProgress", "Database restore in progress"),
                );
                return;
            }

            if (step === "failed") {
                statusDot.style.background = "var(--mjr-status-error, #f44336)";
                applyStatusHighlight(section, "error", { toast: false });
                setStatusLines(statusText, [
                    t("status.error", "Error"),
                    String(
                        detail?.message ||
                            t("toast.dbRestoreFailed", "Failed to restore DB backup"),
                    ),
                ]);
                return;
            }

            if (step === "done") {
                statusDot.style.background = "var(--mjr-status-success, #4CAF50)";
                applyStatusHighlight(section, "success", { toast: false });
                const op = String(detail?.operation || "");
                const doneHint =
                    op === "delete_db"
                        ? t(
                              "toast.dbDeleteSuccess",
                              "Database deleted and rebuilt. Files are being reindexed.",
                          )
                        : op === "reset_index"
                          ? t(
                                "toast.resetStarted",
                                "Index reset started. Files will be reindexed in the background.",
                            )
                          : t("toast.dbRestoreSuccess", "Database backup restored");
                setStatusWithHint(statusText, t("status.ready", "Ready"), doneHint);
                try {
                    const target = getScanContext ? getScanContext() : null;
                    setTimeout(() => {
                        void updateStatus(statusDot, statusText, capabilities, target, null, {
                            force: true,
                        });
                    }, 600);
                } catch (e) {
                    console.debug?.(e);
                }
            }
        } catch (e) {
            console.debug?.(e);
        }
    };
    try {
        const old = _dbRestoreStatusHandler;
        if (typeof old === "function") {
            window.removeEventListener("mjr-db-restore-status", old);
        }
        _dbRestoreStatusHandler = onDbRestoreStatus;
        (section as any)._mjrDbRestoreStatusHandler = onDbRestoreStatus;
        window.addEventListener("mjr-db-restore-status", onDbRestoreStatus);
    } catch (e) {
        console.debug?.(e);
    }

    const onRuntimeStatus = (event: any) => {
        try {
            const detail = event?.detail || {};
            const queueRemaining = Number(detail?.queue_remaining);
            const progressValue = Number(detail?.progress_value);
            const progressMax = Number(detail?.progress_max);
            const cachedNodes = Array.isArray(detail?.cached_nodes)
                ? detail.cached_nodes.length
                : 0;
            const activePromptId = String(detail?.active_prompt_id || "").trim();
            const progressLine =
                Number.isFinite(progressValue) && Number.isFinite(progressMax) && progressMax > 0
                    ? t("status.runtimeProgress", "Runtime progress: {value}/{max}", {
                          value: progressValue,
                          max: progressMax,
                      })
                    : "";
            const queueLine = Number.isFinite(queueRemaining)
                ? t("status.queueRemaining", "Queue remaining: {count}", {
                      count: Math.max(0, queueRemaining),
                  })
                : "";
            const cachedLine =
                cachedNodes > 0
                    ? t("status.executionCached", "Cached nodes reused: {count}", {
                          count: cachedNodes,
                      })
                    : "";
            const promptLine = activePromptId
                ? t("status.activePrompt", "Active prompt: {id}", { id: activePromptId })
                : "";
            const liveLines = [progressLine, queueLine, cachedLine, promptLine].filter(Boolean);
            if (!liveLines.length) return;
            const footer = statusText?.querySelector?.("span");
            if (footer) {
                footer.textContent = liveLines.join("  |  ");
            } else {
                setStatusWithHint(statusText, t("status.ready", "Ready"), liveLines.join("  |  "));
            }
        } catch (e) {
            console.debug?.(e);
        }
    };
    try {
        const old = _runtimeStatusHandler;
        if (typeof old === "function") {
            window.removeEventListener(EVENTS.RUNTIME_STATUS, old);
        }
        _runtimeStatusHandler = onRuntimeStatus;
        window.addEventListener(EVENTS.RUNTIME_STATUS, onRuntimeStatus);
    } catch (e) {
        console.debug?.(e);
    }

    return section;
}

/**
 * Trigger a scan
 */
export async function triggerScan(
    statusDot: any,
    statusText: any,
    capabilitiesSection: any = null,
    scanTarget: any = null,
): Promise<void> {
    if (_maintenanceActive) {
        comfyToast(
            t("status.maintenanceBusy", "Database maintenance in progress. Please wait."),
            "warning",
            2200,
        );
        return;
    }
    const section =
        statusText?.closest?.("#mjr-status-body")?.parentElement || statusText?.closest?.("div");
    const desiredScope = String(scanTarget?.scope || "output").toLowerCase();
    const desiredCustomRootId =
        scanTarget?.customRootId || scanTarget?.custom_root_id || scanTarget?.root_id || null;
    const isCustomBrowserMode = desiredScope === "custom" && !desiredCustomRootId;
    if (isCustomBrowserMode) {
        statusDot.style.background = "var(--mjr-status-info, #64B5F6)";
        applyStatusHighlight(section, "info");
        setStatusWithHint(
            statusText,
            t("status.customBrowserScanDisabled", "Custom browser mode: scan is disabled"),
            t(
                "status.customBrowserScanDisabledHint",
                "Use Outputs, Inputs, or All to run indexing scans",
            ),
        );
        return;
    }

    // Prevent overlapping scans (manual or polling-triggered).
    try {
        const now = Date.now();
        const inflight = (globalThis as any)?._mjrScanInFlight;
        if (inflight && typeof inflight === "object") {
            const ageMs = now - Number(inflight.at || 0);
            if (ageMs >= 0 && ageMs < 10 * 60_000) {
                setStatusWithHint(
                    statusText,
                    t("status.scanInProgress", "Scan already running..."),
                    t("status.scanInProgressHint", "Please wait for the current scan to finish"),
                );
                return;
            }
        }
        (globalThis as any)._mjrScanInFlight = {
            at: now,
            scope: desiredScope,
            root_id: desiredCustomRootId || null,
        };
    } catch (e) {
        console.debug?.(e);
    }

    const clearScanInFlight = () => {
        try {
            if ((globalThis as any)?._mjrScanInFlight) {
                (globalThis as any)._mjrScanInFlight = null;
            }
        } catch (e) {
            console.debug?.(e);
        }
    };

    // Incremental is always favored.
    // Shift+Click logic is handled by caller (if applicable), but here we default to true.
    const shouldIncremental = true;

    // Fetch roots so we can show meaningful paths
    let roots = null;
    try {
        const rootsResult = await get(ENDPOINTS.ROOTS);
        if (rootsResult.ok) roots = rootsResult.data;
    } catch (e) {
        console.debug?.(e);
    }

    // Fallback to config for output directory if roots endpoint is unavailable
    if (!roots) {
        const configResult = await get(ENDPOINTS.CONFIG);
        if (!configResult.ok) {
            statusDot.style.background = "var(--mjr-status-error, #f44336)";
            applyStatusHighlight(section, "error");
            statusText.textContent = t("status.errorGetConfig");
            clearScanInFlight();
            return;
        }
        roots = { output_directory: configResult.data.output_directory };
    }

    const scopeLabel =
        desiredScope === "all"
            ? t("scope.all", "Inputs + Outputs")
            : desiredScope === "input"
              ? t("scope.input", "Inputs")
              : desiredScope === "custom"
                ? t("scope.custom", "Custom")
                : desiredScope === "workflow"
                  ? t("scope.workflow", "Workflow")
                : t("scope.output", "Outputs");

    let detail = "";
    if (desiredScope === "input")
        detail = roots?.input_directory ? ` (${roots.input_directory})` : "";
    else if (desiredScope === "custom") {
        const list = Array.isArray(roots?.custom_roots) ? roots.custom_roots : [];
        const picked = desiredCustomRootId ? list.find((r: any) => r?.id === desiredCustomRootId) : null;
        detail = picked?.path ? ` (${picked.path})` : "";
    } else if (desiredScope === "output")
        detail = roots?.output_directory ? ` (${roots.output_directory})` : "";

    // Show scanning status
    statusDot.style.background = "var(--mjr-status-info, #64B5F6)";
    applyStatusHighlight(section, "info");
    setStatusWithHint(
        statusText,
        t("status.scanningScope", `Scanning ${scopeLabel}${detail}...`, {
            scope: scopeLabel,
            detail,
        }),
        t("status.scanningHint", "This may take a while"),
    );

    const settings = loadMajoorSettings();
    const fastModeEnabled = !!(settings?.scan?.fastMode ?? true);

    const payload: Record<string, any> = {
        scope: desiredScope,
        recursive: true,
        incremental: shouldIncremental,
        fast: fastModeEnabled,
        background_metadata: true,
    };
    if (desiredScope === "custom") {
        if (!desiredCustomRootId) {
            statusDot.style.background = "var(--mjr-status-error, #f44336)";
            applyStatusHighlight(section, "error");
            statusText.textContent = t("status.selectCustomFolder");
            clearScanInFlight();
            return;
        }
        payload.custom_root_id = desiredCustomRootId;
    }

    let scanResult;
    try {
        // Trigger scan
        scanResult = await post(ENDPOINTS.SCAN, payload);
    } finally {
        clearScanInFlight();
    }

    if (scanResult?.ok) {
        const stats = scanResult.data;
        statusDot.style.background = "var(--mjr-status-success, #4CAF50)"; // Green
        applyStatusHighlight(section, "success");
        setStatusWithHint(
            statusText,
            t("toast.scanComplete"),
            t(
                "status.scanStats",
                `Added: ${stats.added || 0}  -  Updated: ${stats.updated || 0}  -  Skipped: ${stats.skipped || 0}`,
                {
                    added: stats.added || 0,
                    updated: stats.updated || 0,
                    skipped: stats.skipped || 0,
                },
            ),
        );
        markGridDirty("scan-complete", {
            stats: {
                added: stats.added || 0,
                updated: stats.updated || 0,
                skipped: stats.skipped || 0,
            },
        });

        // Refresh status after 2 seconds
        setTimeout(() => {
            updateStatus(statusDot, statusText, capabilitiesSection);
        }, 2000);
    } else {
        statusDot.style.background = "var(--mjr-status-error, #f44336)"; // Red
        applyStatusHighlight(section, "error");
        setStatusLines(statusText, [
            t("toast.scanFailed") + `: ${scanResult?.error || "Unknown error"}`,
        ]);

        // Restore status after 3 seconds
        setTimeout(() => {
            updateStatus(statusDot, statusText, capabilitiesSection);
        }, 3000);
    }
}

function createCapabilityBadge(label: any, available: any, hint: any) {
    const badge = document.createElement("span");
    badge.style.cssText = `
        display: inline-flex;
        align-items: center;
        gap: 4px;
        padding: 2px 6px;
        border-radius: 999px;
        background: rgba(255, 255, 255, 0.05);
        border: 1px solid rgba(255, 255, 255, 0.1);
    `;
    badge.textContent = `${available ? "OK" : "ERR"} ${label}`;
    badge.title = available
        ? t("status.toolAvailable", `${label} available`, { tool: label })
        : hint || t("status.toolUnavailable", `${label} unavailable`, { tool: label });
    badge.style.opacity = available ? "1" : "0.75";
    return badge;
}

function renderCapabilities(section: any, toolAvailability: Record<string, any> = {}, toolPaths: Record<string, any> = {}) {
    if (!section) return;
    section.replaceChildren();
    if (!toolAvailability || Object.keys(toolAvailability).length === 0) {
        section.textContent = t("status.discoveringTools");
        return;
    }

    const wrapper = document.createElement("div");
    wrapper.style.display = "flex";
    wrapper.style.flexWrap = "wrap";
    wrapper.style.gap = "10px";
    wrapper.style.alignItems = "flex-start";

    TOOL_CAPABILITIES.forEach(({ key, labelKey, hintKey }) => {
        const available = Boolean(toolAvailability[key]);
        const path = toolPaths[key];
        const label = t(labelKey, key);
        const hint = t(hintKey, "");
        wrapper.appendChild(createCapabilityNode({ label, hint }, available, path));
    });

    section.appendChild(wrapper);
}

function renderToolsStatusLine(section: any, toolStatus: any = null, fallbackAvailability: Record<string, any> = {}) {
    if (!section) return;
    const parent = section.parentElement;
    if (!parent) return;
    const container = parent.querySelector("#mjr-tools-status");
    if (!container) return;

    const hasFallback = fallbackAvailability && Object.keys(fallbackAvailability).length > 0;
    if (!toolStatus && !hasFallback) {
        container.textContent = t("status.toolStatusChecking", "Tool status: checking...");
        return;
    }

    const segments = TOOL_CAPABILITIES.map(({ key, labelKey }) => {
        const label = t(labelKey, key);
        const availability = toolStatus && key in toolStatus ? toolStatus[key] : undefined;
        const fallback = key in fallbackAvailability ? fallbackAvailability[key] : undefined;
        const available = availability !== undefined ? availability : fallback;
        const statusText =
            available === null || available === undefined
                ? t("status.unknown", "unknown")
                : available
                  ? t("status.available", "available")
                  : t("status.missing", "missing");
        const version = toolStatus?.versions?.[key];
        return version ? `${label}: ${statusText} - ${version}` : `${label}: ${statusText}`;
    });
    container.textContent = segments.join("  |  ");
}

function createCapabilityNode({ label, hint }: { label: any; hint: any }, available: any, path: any) {
    const container = document.createElement("div");
    container.style.cssText = `
        display: flex;
        flex-direction: column;
        gap: 3px;
        padding: 6px 8px;
        border-radius: 8px;
        background: rgba(255, 255, 255, 0.03);
        border: 1px solid rgba(255, 255, 255, 0.08);
        min-width: 170px;
    `;

    const badge = createCapabilityBadge(label, available, hint);
    badge.style.fontWeight = "500";
    container.appendChild(badge);

    const pathLine = document.createElement("span");
    pathLine.style.fontSize = "10px";
    pathLine.style.opacity = "0.7";
    pathLine.style.wordBreak = "break-all";
    pathLine.textContent =
        t("status.path", "Path") +
        `: ${path ? path : t("status.pathAuto", "auto / not configured")}`;
    container.appendChild(pathLine);

    return container;
}

function setBodyCollapsed(section: any, collapsed: any) {
    const body = section.querySelector("#mjr-status-body");
    const indicator = section.querySelector("#mjr-status-title-indicator");
    if (!body || !indicator) return;
    if (collapsed) {
        body.style.display = "none";
        indicator.textContent = ">";
    } else {
        body.style.display = "";
        indicator.textContent = "v";
    }
}
function buildDbHealthLine(healthData: any, dbDiagData: any) {
    const dbAvailable = Boolean(healthData?.database?.available);
    const diagnostics = dbDiagData?.diagnostics || {};
    const malformed = Boolean(diagnostics?.malformed);
    const locked = Boolean(diagnostics?.locked);

    if (!dbAvailable || malformed) {
        return t("status.dbHealthError", "DB health: error");
    }
    if (locked) {
        return t("status.dbHealthLocked", "DB health: locked");
    }
    return t("status.dbHealthOk", "DB health: ok");
}

function buildIndexHealthLine(counters: any, desiredScope: any) {
    const totalAssets = Number(counters?.total_assets || 0);
    const lastIndexEnd = counters?.last_index_end;
    const lastScanEnd = counters?.last_scan_end;
    const scopeLabel =
        desiredScope === "all"
            ? t("scope.all", "Inputs + Outputs")
            : desiredScope === "input"
              ? t("scope.input", "Inputs")
              : desiredScope === "custom"
                ? t("scope.custom", "Custom")
                : desiredScope === "workflow"
                  ? t("scope.workflow", "Workflow")
                : t("scope.output", "Outputs");

    if (!Number.isFinite(totalAssets) || totalAssets <= 0) {
        return `${t("status.indexHealthEmpty", "Index health: empty")} (${scopeLabel})`;
    }
    if (!lastIndexEnd && !lastScanEnd) {
        return `${t("status.indexHealthPartial", "Index health: partial")} (${scopeLabel})`;
    }
    return `${t("status.indexHealthOk", "Index health: ok")} (${scopeLabel})`;
}

export async function updateStatus(
    statusDot: any,
    statusText: any,
    capabilitiesSection: any = null,
    scanTarget: any = null,
    meta: any = null,
    options: Record<string, any> = {},
) {
    const section =
        statusText?.closest?.("#mjr-status-body")?.parentElement || statusText?.closest?.("div");
    const signal = options?.signal || null;
    const force = !!options?.force;
    try {
    } catch (e) {
        console.debug?.(e);
    }
    try {
        if (!statusDot?.isConnected || !statusText?.isConnected) return null;
    } catch (e) {
        console.debug?.(e);
    }
    try {
        if (!force && _maintenanceActive) return null;
    } catch (e) {
        console.debug?.(e);
    }
    // Optional: caller-provided object to read the last HTTP error details from.
    // (Used by the polling loop to avoid relying on string matching.)
    if (meta && typeof meta === "object") {
        meta.lastCode = null;
        meta.lastStatus = null;
    }

    const desiredScope = String(scanTarget?.scope || "output").toLowerCase();
    const requestedScope = desiredScope === "workflow" ? "all" : desiredScope;
    const desiredCustomRootId =
        scanTarget?.customRootId || scanTarget?.custom_root_id || scanTarget?.root_id || null;
    const isCustomBrowserMode = desiredScope === "custom" && !desiredCustomRootId;
    const url = isCustomBrowserMode
        ? `${ENDPOINTS.HEALTH_COUNTERS}?scope=all`
        : requestedScope === "custom"
          ? `${ENDPOINTS.HEALTH_COUNTERS}?scope=custom&custom_root_id=${encodeURIComponent(String(desiredCustomRootId || ""))}`
          : `${ENDPOINTS.HEALTH_COUNTERS}?scope=${encodeURIComponent(requestedScope || "output")}`;
    const lightweight = !!options?.lightweight;
    const scanAuxBackoffActive =
        !force &&
        meta &&
        typeof meta === "object" &&
        Number(meta._scanAuxBackoffUntil || 0) > Date.now();
    const shouldFetchAux =
        !scanAuxBackoffActive &&
        (force || !lightweight || !(meta && typeof meta === "object" && meta._auxCached));

    let result;
    let healthResult;
    let dbDiagResult;
    let toolStatusData = null;

    if (shouldFetchAux) {
        const [countersRes, healthRes, dbRes] = await Promise.all([
            get(url, signal ? { signal } : undefined),
            get(ENDPOINTS.HEALTH, signal ? { signal } : undefined),
            get(ENDPOINTS.HEALTH_DB, signal ? { signal } : undefined),
        ]);
        result = countersRes;
        healthResult = healthRes;
        dbDiagResult = dbRes;
        try {
            const toolsResult = await getToolsStatus(signal ? { signal } : undefined);
            if (toolsResult?.ok) toolStatusData = toolsResult.data;
        } catch (e) {
            console.debug?.(e);
        }
        if (meta && typeof meta === "object") {
            meta._auxCached = true;
            meta._healthCache = healthResult;
            meta._dbDiagCache = dbDiagResult;
            meta._toolsCache = toolStatusData;
        }
    } else {
        result = await get(url, signal ? { signal } : undefined);
        healthResult = meta?._healthCache || null;
        dbDiagResult = meta?._dbDiagCache || null;
        toolStatusData = meta?._toolsCache || null;
    }
    try {
        if (signal?.aborted) return null;
    } catch (e) {
        console.debug?.(e);
    }
    try {
        if (!statusDot?.isConnected || !statusText?.isConnected) return null;
    } catch (e) {
        console.debug?.(e);
    }

    if (meta && typeof meta === "object") {
        meta.lastCode = result?.code || null;
        meta.lastStatus = typeof result?.status === "number" ? result.status : null;
    }

    if (result.ok) {
        const counters = result.data;
        if (meta && typeof meta === "object") {
            meta._scanAuxBackoffUntil = counters?.scan_active ? Date.now() + 30_000 : 0;
        }
        const totalAssets = counters.total_assets || 0;
        const withWorkflows = counters.with_workflows - 0;
        const withGenerationData = counters.with_generation_data - 0;
        const workflowCount = Math.max(0, Number(withWorkflows || 0) || 0);
        const lastScanRaw = counters.last_scan_end;
        const lastScanText = lastScanRaw ? new Date(lastScanRaw).toLocaleString() : "N/A";
        const toolAvailability = counters.tool_availability || {};
        const toolPaths = counters.tool_paths || {};
        const dbSizeLine = t("status.dbSize", "Database size: {size}", {
            size: formatBytes(counters.db_size_bytes || 0),
        });
        const vectorDiag =
            healthResult?.ok && healthResult?.data ? healthResult.data.vector || {} : {};
        const vectorEnabled = vectorDiag?.enabled !== false;
        const vectorLoaded = !!vectorDiag?.loaded;
        const vectorDegraded = !!vectorDiag?.degraded;
        const vectorLastError = String(vectorDiag?.last_error || "").trim();
        const vectorLine = !vectorEnabled
            ? "AI vector: disabled"
            : vectorDegraded
              ? `AI vector: degraded${vectorLastError ? ` (${vectorLastError})` : ""}`
              : vectorLoaded
                ? "AI vector: loaded"
                : "AI vector: initializing";
        const dbHealthLine = buildDbHealthLine(
            healthResult?.data || null,
            dbDiagResult?.data || null,
        );
        const indexHealthLine = buildIndexHealthLine(
            counters,
            isCustomBrowserMode ? "all" : desiredScope,
        );
        const dbAvailable = Boolean(healthResult?.ok && healthResult?.data?.database?.available);
        const dbDiagnostics = dbDiagResult?.ok ? dbDiagResult?.data?.diagnostics || {} : {};
        const dbMalformed = Boolean(dbDiagnostics?.malformed);
        const dbLocked = Boolean(dbDiagnostics?.locked);
        const dbMaintenance = Boolean(dbDiagnostics?.maintenance_active);
        setMaintenanceActive(dbMaintenance);
        const enrichmentQueueLength = Math.max(
            0,
            Number(counters?.enrichment_queue_length || 0) || 0,
        );
        const runtimeEnrichment = getRuntimeEnrichmentState();
        const enrichmentActive = runtimeEnrichment.active || enrichmentQueueLength > 0;
        setRuntimeEnrichmentState(enrichmentActive, enrichmentQueueLength);
        const hasIndexedAssets = Number(totalAssets) > 0;
        const hasIndexTimestamp = Boolean(counters?.last_index_end || counters?.last_scan_end);
        const indexHealthy = hasIndexedAssets && hasIndexTimestamp;

        let healthTone = "success";
        if (dbMaintenance || enrichmentActive) {
            healthTone = "info";
        } else if (!dbAvailable || dbMalformed) {
            healthTone = "error";
        } else if (dbLocked || !indexHealthy) {
            healthTone = "warning";
        } else if (vectorDegraded) {
            healthTone = "warning";
        }
                const isWorkflowScope = desiredScope === "workflow";
                const displayTone =
                        isCustomBrowserMode && healthTone !== "error"
                                ? "browser"
                                : isWorkflowScope && healthTone !== "error"
                                    ? "workflow"
                                    : healthTone;
        let watcherInfo = counters.watcher;
        try {
            if (!watcherInfo || typeof watcherInfo.enabled !== "boolean") {
                const wres = await getWatcherStatus(signal ? { signal } : undefined);
                if (wres?.ok && wres.data) {
                    watcherInfo = {
                        enabled: !!wres.data.enabled,
                        scope: counters?.watcher?.scope || desiredScope,
                        custom_root_id: desiredCustomRootId || null,
                    };
                }
            }
        } catch (e) {
            console.debug?.(e);
        }
        const watcherLine = isWorkflowScope
            ? t("status.watcher.disabledScoped", "Watcher: disabled ({scope})", {
                  scope: t("scope.workflow", "Workflow"),
              })
            : isCustomBrowserMode
            ? t("status.watcher.disabledScoped", "Watcher: disabled ({scope})", {
                  scope: t("scope.customBrowser", "Browser"),
              })
            : formatWatcherLine(watcherInfo, desiredScope);
        const enrichmentLine = enrichmentActive
            ? t("status.enrichmentQueue", "Metadata enrichment queue: {count}", {
                  count: enrichmentQueueLength,
              })
            : t("status.enrichmentIdle", "Metadata enrichment: idle");

        renderCapabilities(capabilitiesSection, toolAvailability, toolPaths);
        renderToolsStatusLine(capabilitiesSection, toolStatusData, toolAvailability);

        const scopeLabel =
            desiredScope === "all"
                ? t("scope.allFull", "All (Inputs + Outputs)")
                : desiredScope === "input"
                  ? t("scope.input", "Inputs")
                  : desiredScope === "custom"
                    ? t("scope.customBrowser", "Browser")
                    : desiredScope === "workflow"
                      ? t("scope.workflow", "Workflow")
                    : t("scope.output", "Outputs");

        if (healthTone === "error") {
            statusDot.style.background = "var(--mjr-status-error, #f44336)";
            applyStatusHighlight(section, "error");
            setStatusWithHint(
                statusText,
                t("status.dbCorrupted", "Database appears corrupted or unavailable."),
                [dbHealthLine, indexHealthLine, dbSizeLine, watcherLine]
                    .filter(Boolean)
                    .join("  |  "),
            );
            return counters;
        }

        if (isCustomBrowserMode) {
            statusDot.style.background = "var(--mjr-status-browser, #26A69A)";
            applyStatusHighlight(section, "browser");
            setStatusWithHint(
                statusText,
                t("status.ready", "Ready"),
                [
                    t(
                        "status.browserMetricsHidden",
                        "Browser mode: global DB/index metrics hidden",
                    ),
                    watcherLine,
                ]
                    .filter(Boolean)
                    .join("  |  "),
            );
            return counters;
        }

        if (isWorkflowScope) {
            statusDot.style.background = "#d481c3";
            applyStatusHighlight(section, displayTone);
            setStatusLines(
                statusText,
                [
                    t(
                        "status.workflowsIndexed",
                        `${workflowCount.toLocaleString()} workflows indexed (${scopeLabel})`,
                        { count: workflowCount.toLocaleString(), scope: scopeLabel },
                    ),
                    t(
                        "status.assetsCountReference",
                        `Asset records in DB: ${totalAssets.toLocaleString()}`,
                        { count: totalAssets.toLocaleString() },
                    ),
                    enrichmentLine,
                    vectorLine,
                    dbHealthLine,
                    indexHealthLine,
                    dbSizeLine,
                    watcherLine,
                ],
                t("status.lastScan", `Last scan: ${lastScanText}`, { date: lastScanText }),
            );
            return counters;
        }

        if (totalAssets === 0) {
            statusDot.style.background =
                displayTone === "browser"
                    ? "var(--mjr-status-browser, #26A69A)"
                    : healthTone === "info"
                      ? "var(--mjr-status-info, #64B5F6)"
                      : healthTone === "warning"
                        ? "var(--mjr-status-warning, #FFA726)"
                        : "var(--mjr-status-success, #4CAF50)";
            applyStatusHighlight(section, displayTone);
            setStatusWithHint(
                statusText,
                t("status.noAssets", `No assets indexed yet (${scopeLabel})`, {
                    scope: scopeLabel,
                }),
                [
                    t("status.clickToScan", "Click the dot to start a scan"),
                    vectorLine,
                    dbHealthLine,
                    indexHealthLine,
                    dbSizeLine,
                    watcherLine,
                ]
                    .filter(Boolean)
                    .join("  |  "),
            );
        } else {
            statusDot.style.background =
                displayTone === "browser"
                    ? "var(--mjr-status-browser, #26A69A)"
                    : healthTone === "info"
                      ? "var(--mjr-status-info, #64B5F6)"
                      : healthTone === "warning"
                        ? "var(--mjr-status-warning, #FFA726)"
                        : "var(--mjr-status-success, #4CAF50)";
            applyStatusHighlight(section, displayTone);
            setStatusLines(
                statusText,
                [
                    t(
                        "status.assetsIndexed",
                        `${totalAssets.toLocaleString()} assets indexed (${scopeLabel})`,
                        { count: totalAssets.toLocaleString(), scope: scopeLabel },
                    ),
                    _buildKindCountsLine(counters),
                    t(
                        "status.withWorkflows",
                        `With workflows: ${withWorkflows}  -  Generation data: ${withGenerationData}`,
                        { workflows: withWorkflows, gendata: withGenerationData },
                    ),
                    enrichmentLine,
                    vectorLine,
                    dbHealthLine,
                    indexHealthLine,
                    dbSizeLine,
                    watcherLine,
                ],
                t("status.lastScan", `Last scan: ${lastScanText}`, { date: lastScanText }),
            );
            appendStatusProgressBars(
                statusText,
                buildStatusProgressItems(counters, {
                    totalAssets,
                    withWorkflows,
                    withGenerationData,
                }),
            );
        }
        return counters;
    } else {
        // Error - red
        renderCapabilities(capabilitiesSection, {}, {});
        renderToolsStatusLine(capabilitiesSection, toolStatusData);
        statusDot.style.background = "var(--mjr-status-error, #f44336)";
        applyStatusHighlight(section, "error");
        if (result?.code === "INVALID_RESPONSE" && result?.status === 404) {
            setStatusWithHint(
                statusText,
                t("status.apiNotFound", "Majoor API endpoints not found (404)"),
                t(
                    "status.apiNotFoundHint",
                    "Backend routes are not loaded. Restart ComfyUI and check the terminal for Majoor import errors.",
                ),
            );
        } else {
            const errMsg = String(result?.error || "").toLowerCase();
            const isCorrupt =
                errMsg.includes("malform") ||
                errMsg.includes("corrupt") ||
                errMsg.includes("disk image");
            if (isCorrupt) {
                setStatusWithHint(statusText, t("status.dbCorrupted"), t("status.dbCorruptedHint"));
                if (!(globalThis as any)._mjrCorruptToastShown) {
                    (globalThis as any)._mjrCorruptToastShown = true;
                    comfyToast(t("toast.resetFailedCorrupt"), "error", 8000);
                }
            } else {
                setStatusLines(statusText, [
                    result.error || t("status.errorChecking", "Error checking status"),
                ]);
            }
        }
        if (result.code === "SERVICE_UNAVAILABLE") {
            const retryBtn = createRetryButton(
                statusDot,
                statusText,
                capabilitiesSection,
                scanTarget,
            );
            statusText.appendChild(document.createElement("br"));
            statusText.appendChild(retryBtn);
        }
    }
    return null;
}

function createRetryButton(statusDot: any, statusText: any, capabilitiesSection = null, scanTarget = null) {
    const button = document.createElement("button");
    button.textContent = t("btn.retryServices");
    button.style.cssText = `
        padding: 4px 10px;
        margin-top: 6px;
        font-size: 11px;
        border-radius: 4px;
        border: 1px solid rgba(255,255,255,0.3);
        background: transparent;
        color: white;
        cursor: pointer;
    `;

    button.onclick = async () => {
        button.disabled = true;
        button.textContent = t("btn.retrying");
        const retryResult = await post(ENDPOINTS.RETRY_SERVICES, {});
        button.disabled = false;
        button.textContent = t("btn.retryServices");
        if (retryResult.ok) {
            updateStatus(statusDot, statusText, capabilitiesSection, scanTarget);
        } else {
            setStatusLines(statusText, [
                retryResult.error || t("status.retryFailed", "Retry failed"),
            ]);
            statusText.appendChild(document.createElement("br"));
            statusText.appendChild(button);
        }
    };

    return button;
}

function _readCachedStatusCounters() {
    try {
        const raw = localStorage?.getItem?.(STATUS_CACHE_KEY);
        if (!raw) return null;
        const parsed = JSON.parse(raw);
        return parsed && typeof parsed === "object" ? parsed : null;
    } catch (e) {
        console.debug?.(e);
        return null;
    }
}

function _writeCachedStatusCounters(counters: any) {
    try {
        if (!counters || typeof counters !== "object") return;
        localStorage?.setItem?.(STATUS_CACHE_KEY, JSON.stringify(counters));
    } catch (e) {
        console.debug?.(e);
    }
}

function _collectProgressValues(status: any) {
    const values: any[] = [];
    const visit = (node: any, depth = 0) => {
        if (!node || depth > 2) return;
        if (typeof node === "number" && Number.isFinite(node)) {
            values.push(node);
            return;
        }
        if (Array.isArray(node)) {
            for (const item of node) visit(item, depth + 1);
            return;
        }
        if (typeof node !== "object") return;
        for (const [key, value] of Object.entries(node)) {
            const normalizedKey = String(key || "").toLowerCase();
            if (
                normalizedKey.includes("queue") ||
                normalizedKey.includes("progress") ||
                normalizedKey.includes("pending") ||
                normalizedKey.includes("running") ||
                normalizedKey.includes("active") ||
                normalizedKey.includes("scan") ||
                normalizedKey.includes("index")
            ) {
                visit(value, depth + 1);
            }
        }
    };
    visit(status, 0);
    return values;
}

function _statusHasActiveWork(counters: any) {
    if (!counters || typeof counters !== "object") return false;
    if (_maintenanceActive) return true;
    try {
        if (getRuntimeEnrichmentState()?.active) return true;
    } catch (e) {
        console.debug?.(e);
    }
    const values = _collectProgressValues(counters);
    return values.some((value) => Number(value) > 0);
}

function _buildKindCountsLine(counters: any) {
    const parts = [];
    if (counters.images) parts.push(`Images: ${counters.images}`);
    if (counters.videos) parts.push(`Videos: ${counters.videos}`);
    if (counters.audio) parts.push(`Audio: ${counters.audio}`);
    const model3d = counters.model3d || counters.by_kind?.model3d || 0;
    if (model3d) parts.push(`3D: ${model3d}`);
    return parts.length ? parts.join("  -  ") : `Images: 0  -  Videos: 0`;
}

function _buildStatusSignature(counters: any) {
    if (!counters || typeof counters !== "object") return "";
    const pick = (value: any) => {
        if (value == null) return null;
        if (typeof value === "number") return Number.isFinite(value) ? value : null;
        if (typeof value === "boolean") return value;
        if (typeof value === "string") return value;
        return null;
    };
    return JSON.stringify({
        total_assets: pick(counters.total_assets),
        last_scan_end: pick(counters.last_scan_end),
        last_index_end: pick(counters.last_index_end),
        enrichment_queue_length: pick(counters.enrichment_queue_length),
        images: pick(counters.images),
        videos: pick(counters.videos),
        audio: pick(counters.audio),
        model3d: pick(counters.model3d ?? counters.by_kind?.model3d),
        watcher: {
            enabled: pick(counters?.watcher?.enabled),
            scope: pick(counters?.watcher?.scope),
        },
    });
}

function _hydrateStatusFromCache(statusDot: any, statusText: any, capabilitiesSection: any) {
    const cached = _readCachedStatusCounters();
    if (!cached) return false;
    try {
        renderCapabilities(
            capabilitiesSection,
            cached.tool_availability || {},
            cached.tool_paths || {},
        );
    } catch (e) {
        console.debug?.(e);
    }
    try {
        statusDot.style.background = "var(--mjr-status-info, #64B5F6)";
        setStatusWithHint(
            statusText,
            t("status.cached", "Last known status"),
            t("status.checking", "Checking status..."),
        );
        return true;
    } catch (e) {
        console.debug?.(e);
        return false;
    }
}

function _advancePollState(currentState: any, counters: any, pollStateMeta: any) {
    const signature = _buildStatusSignature(counters);
    const hasChange = signature && signature !== String(pollStateMeta?.lastSignature || "");
    const hasActiveWork = _statusHasActiveWork(counters);

    let nextState = currentState || STATUS_POLL_STATE.ACTIVE;
    let cooldownStablePolls = Number(pollStateMeta?.cooldownStablePolls || 0) || 0;

    if (hasActiveWork) {
        nextState = STATUS_POLL_STATE.ACTIVE;
        cooldownStablePolls = 0;
    } else if (hasChange) {
        nextState = STATUS_POLL_STATE.ACTIVE;
        cooldownStablePolls = 0;
    } else if (nextState === STATUS_POLL_STATE.ACTIVE) {
        nextState = STATUS_POLL_STATE.COOLDOWN;
        cooldownStablePolls = 0;
    } else if (nextState === STATUS_POLL_STATE.COOLDOWN) {
        cooldownStablePolls += 1;
        if (cooldownStablePolls >= 3) {
            nextState = STATUS_POLL_STATE.IDLE;
            cooldownStablePolls = 0;
        }
    } else {
        nextState = hasChange ? STATUS_POLL_STATE.ACTIVE : STATUS_POLL_STATE.IDLE;
        cooldownStablePolls = 0;
    }

    return {
        nextState,
        signature,
        hasChange,
        hasActiveWork,
        cooldownStablePolls,
    };
}

/**
 * Setup status polling
 */
export function setupStatusPolling(
    statusDot: any,
    statusText: any,
    section: any,
    capabilitiesSection: any = null,
    onCountersUpdate: ((data: any) => void) | null = null,
    getScanTarget: (() => any) | null = null,
) {
    const GLOBAL_POLL_KEY = "__MJR_STATUS_POLL_DISPOSE__";
    const pollMeta = { lastCode: null, lastStatus: null, _pollTick: 0, _auxCached: false };
    const pollStateMeta = {
        mode: STATUS_POLL_STATE.ACTIVE,
        cooldownStablePolls: 0,
        lastSignature: "",
    };

    const pollingAC = typeof AbortController !== "undefined" ? new AbortController() : null;
    const handleUpdate = async () => {
        try {
            if (pollingAC?.signal?.aborted) return null;
        } catch (e) {
            console.debug?.(e);
        }
        pollMeta._pollTick = Number(pollMeta._pollTick || 0) + 1;
        const lightweight = pollMeta._pollTick > 1 && pollMeta._pollTick % 4 !== 0;
        const target = typeof getScanTarget === "function" ? getScanTarget() : null;
        const counters = await updateStatus(
            statusDot,
            statusText,
            capabilitiesSection,
            target,
            pollMeta,
            {
                signal: pollingAC?.signal || null,
                lightweight,
                // Keep status updates alive while maintenance is active (or stale).
                force: !!_maintenanceActive || pollMeta._pollTick <= 1,
            },
        );
        if (counters && typeof counters === "object") {
            _writeCachedStatusCounters(counters);
            const transition = _advancePollState(pollStateMeta.mode, counters, pollStateMeta);
            pollStateMeta.mode = transition.nextState;
            pollStateMeta.lastSignature = transition.signature;
            pollStateMeta.cooldownStablePolls = transition.cooldownStablePolls;
        }
        if (counters && typeof onCountersUpdate === "function") {
            try {
                await onCountersUpdate(counters);
            } catch (e) {
                console.debug?.(e);
            }
        }
        return counters;
    };

    // Show last known state immediately, then refresh in background.
    _hydrateStatusFromCache(statusDot, statusText, capabilitiesSection);
    handleUpdate();

    try {
        section._mjrStatusPollDispose?.();
    } catch (e) {
        console.debug?.(e);
    }

    // Ensure only one polling loop exists globally (panel rerenders can otherwise duplicate timers).
    try {
        const oldGlobalDispose = (window as any)?.[GLOBAL_POLL_KEY];
        if (typeof oldGlobalDispose === "function") oldGlobalDispose();
    } catch (e) {
        console.debug?.(e);
    }

    // Poll using a dynamic interval so settings changes apply without reload.
    let pollTimerId: any = null;
    let consecutiveFailures = 0;
    let lastWasMissingEndpoint = false;
    const getIdleMultiplier = () => {
        try {
            const hidden = typeof document !== "undefined" && !!document.hidden;
            const unfocused =
                typeof document !== "undefined" &&
                typeof document.hasFocus === "function" &&
                !document.hasFocus();
            if (hidden || unfocused) return 4;
        } catch (e) {
            console.debug?.(e);
        }
        return 1;
    };

    const scheduleNext = () => {
        const baseMs =
            STATUS_POLL_INTERVALS_MS[pollStateMeta.mode as keyof typeof STATUS_POLL_INTERVALS_MS] ||
            Math.max(250, Number(APP_CONFIG.STATUS_POLL_INTERVAL) || 2000);
        const rawWaitMs = lastWasMissingEndpoint
            ? Math.max(30_000, baseMs)
            : consecutiveFailures > 0
              ? Math.min(60_000, Math.round(baseMs * Math.min(8, 1 + consecutiveFailures)))
              : baseMs;
        const waitMs = Math.min(120_000, Math.round(rawWaitMs * getIdleMultiplier()));

        pollTimerId = setTimeout(async () => {
            try {
                if (pollingAC?.signal?.aborted) return;
            } catch (e) {
                console.debug?.(e);
            }
            const counters = await handleUpdate();

            // If the backend routes aren't loaded, ComfyUI returns an HTML 404 page (non-JSON).
            // Back off to avoid spamming the console/network.
            lastWasMissingEndpoint =
                pollMeta.lastCode === "INVALID_RESPONSE" && pollMeta.lastStatus === 404;
            if (counters) {
                consecutiveFailures = 0;
            } else if (lastWasMissingEndpoint) {
                consecutiveFailures = Math.min(999, consecutiveFailures + 1);
            } else {
                consecutiveFailures = Math.min(999, consecutiveFailures + 1);
                pollStateMeta.mode = STATUS_POLL_STATE.ACTIVE;
                pollStateMeta.cooldownStablePolls = 0;
            }

            // After a few consecutive 404s, stop polling entirely until reload.
            if (lastWasMissingEndpoint && consecutiveFailures >= 3) {
                try {
                    section._mjrStatusPollDispose?.();
                } catch (e) {
                    console.debug?.(e);
                }
                return;
            }
            scheduleNext();
        }, waitMs);
    };
    section._mjrStatusPollDispose = () => {
        try {
            pollingAC?.abort?.();
        } catch (e) {
            console.debug?.(e);
        }
        if (pollTimerId) clearTimeout(pollTimerId);
        pollTimerId = null;
    };
    try {
        window[GLOBAL_POLL_KEY as any] = section._mjrStatusPollDispose;
    } catch (e) {
        console.debug?.(e);
    }
    scheduleNext();

    const statusDotEl = section.querySelector("#mjr-status-dot");
    if (statusDotEl) {
        statusDotEl.onclick = (event: any) => {
            event.stopPropagation();
            const target = typeof getScanTarget === "function" ? getScanTarget() : null;
            triggerScan(statusDot, statusText, capabilitiesSection, target);
        };
        statusDotEl.title = t("status.clickToScan", "Click to scan");
    }
}
