import type { DesktopSettings } from '@/lib/desktop';
import { createProjectIdFromPath } from '@/lib/projectId';
import { useUIStore } from '@/stores/useUIStore';
import { isMonoFontOption, isUiFontOption } from '@/lib/fontOptions';
import { useMessageQueueStore } from '@/stores/messageQueueStore';
import { setDirectoryShowHidden } from '@/lib/directoryShowHidden';
import { setFilesViewShowGitignored } from '@/lib/filesViewShowGitignored';
import { loadAppearancePreferences, applyAppearancePreferences } from '@/lib/appearancePersistence';
import { getRegisteredRuntimeAPIs } from '@/contexts/runtimeAPIRegistry';
import { normalizeMobileKeyboardMode, setStoredMobileKeyboardMode } from '@/lib/mobileKeyboardMode';

const persistToLocalStorage = (settings: DesktopSettings) => {
  if (typeof window === 'undefined') {
    return;
  }

  if (settings.themeId) {
    localStorage.setItem('selectedThemeId', settings.themeId);
  }
  if (settings.themeVariant) {
    localStorage.setItem('selectedThemeVariant', settings.themeVariant);
  }
  if (settings.lightThemeId) {
    localStorage.setItem('lightThemeId', settings.lightThemeId);
  }
  if (settings.darkThemeId) {
    localStorage.setItem('darkThemeId', settings.darkThemeId);
  }
  if (typeof settings.useSystemTheme === 'boolean') {
    localStorage.setItem('useSystemTheme', String(settings.useSystemTheme));
  }
  if (settings.lastDirectory) {
    localStorage.setItem('lastDirectory', settings.lastDirectory);
  }
  if (settings.homeDirectory) {
    localStorage.setItem('homeDirectory', settings.homeDirectory);
    // Electron's preload exposes __OPENCHAMBER_HOME__ as a read-only
    // contextBridge property; assignment throws TypeError there. In VSCode
    // webview and plain web runtime the property is writable. Swallow the
    // error in Electron — preload already seeded the value correctly.
    try {
      window.__OPENCHAMBER_HOME__ = settings.homeDirectory;
    } catch {
      /* read-only contextBridge property — leave preload-seeded value */
    }
  }
  if (Array.isArray(settings.projects) && settings.projects.length > 0) {
    localStorage.setItem('projects', JSON.stringify(settings.projects));
  } else {
    localStorage.removeItem('projects');
  }
  if (settings.activeProjectId) {
    localStorage.setItem('activeProjectId', settings.activeProjectId);
  } else {
    localStorage.removeItem('activeProjectId');
  }
  if (Array.isArray(settings.pinnedDirectories) && settings.pinnedDirectories.length > 0) {
    localStorage.setItem('pinnedDirectories', JSON.stringify(settings.pinnedDirectories));
  } else {
    localStorage.removeItem('pinnedDirectories');
  }

  if (Array.isArray(settings.projects) && settings.projects.length > 0) {
    const collapsed = settings.projects
      .filter((project) => (project as unknown as { sidebarCollapsed?: boolean }).sidebarCollapsed === true)
      .map((project) => project.id)
      .filter((id): id is string => typeof id === 'string' && id.length > 0);
    if (collapsed.length > 0) {
      localStorage.setItem('oc.sessions.projectCollapse', JSON.stringify(collapsed));
    } else {
      localStorage.removeItem('oc.sessions.projectCollapse');
    }
  }
  if (typeof settings.gitmojiEnabled === 'boolean') {
    localStorage.setItem('gitmojiEnabled', String(settings.gitmojiEnabled));
  } else {
    localStorage.removeItem('gitmojiEnabled');
  }
  if (typeof settings.directoryShowHidden === 'boolean') {
    localStorage.setItem('directoryTreeShowHidden', settings.directoryShowHidden ? 'true' : 'false');
  }
  if (typeof settings.filesViewShowGitignored === 'boolean') {
    localStorage.setItem('filesViewShowGitignored', settings.filesViewShowGitignored ? 'true' : 'false');
  }
  if (typeof settings.openInAppId === 'string' && settings.openInAppId.length > 0) {
    localStorage.setItem('openInAppId', settings.openInAppId);
  }
  if (typeof settings.pwaAppName === 'string') {
    const normalized = settings.pwaAppName.trim().replace(/\s+/g, ' ').slice(0, 64);
    if (normalized.length > 0) {
      localStorage.setItem('openchamber.pwaName', normalized);
    } else {
      localStorage.removeItem('openchamber.pwaName');
    }
  }
  if (typeof settings.mobileKeyboardMode === 'string') {
    setStoredMobileKeyboardMode(settings.mobileKeyboardMode);
  }
  if (settings.sttProvider === 'browser' || settings.sttProvider === 'server') {
    localStorage.setItem('sttProvider', settings.sttProvider);
  }
  if (typeof settings.sttServerUrl === 'string') {
    localStorage.setItem('sttServerUrl', settings.sttServerUrl);
  }
  if (typeof settings.sttModel === 'string') {
    localStorage.setItem('sttModel', settings.sttModel);
  }
  if (typeof settings.sttLanguage === 'string') {
    localStorage.setItem('sttLanguage', settings.sttLanguage);
  }
  if (typeof settings.sttSilenceThresholdDb === 'number' && Number.isFinite(settings.sttSilenceThresholdDb)) {
    localStorage.setItem('sttSilenceThresholdDb', String(settings.sttSilenceThresholdDb));
  }
  if (typeof settings.sttSilenceHoldMs === 'number' && Number.isFinite(settings.sttSilenceHoldMs)) {
    localStorage.setItem('sttSilenceHoldMs', String(settings.sttSilenceHoldMs));
  }
  if (typeof settings.sttTranscribeOnStop === 'boolean') {
    localStorage.setItem('sttTranscribeOnStop', String(settings.sttTranscribeOnStop));
  }
};

type PersistApi = {
  hasHydrated?: () => boolean;
  onFinishHydration?: (callback: () => void) => (() => void) | undefined;
};

const sanitizeSkillCatalogs = (value: unknown): DesktopSettings['skillCatalogs'] | undefined => {
  if (!Array.isArray(value)) {
    return undefined;
  }

  const result: NonNullable<DesktopSettings['skillCatalogs']> = [];
  const seen = new Set<string>();

  for (const entry of value) {
    if (!entry || typeof entry !== 'object') continue;
    const candidate = entry as Record<string, unknown>;

    const id = typeof candidate.id === 'string' ? candidate.id.trim() : '';
    const label = typeof candidate.label === 'string' ? candidate.label.trim() : '';
    const source = typeof candidate.source === 'string' ? candidate.source.trim() : '';
    const subpath = typeof candidate.subpath === 'string' ? candidate.subpath.trim() : '';
    const gitIdentityId = typeof candidate.gitIdentityId === 'string' ? candidate.gitIdentityId.trim() : '';

    if (!id || !label || !source) continue;
    if (seen.has(id)) continue;
    seen.add(id);

    result.push({
      id,
      label,
      source,
      ...(subpath ? { subpath } : {}),
      ...(gitIdentityId ? { gitIdentityId } : {}),
    });
  }

  return result;
};

const HEX_COLOR_PATTERN = /^#(?:[\da-fA-F]{3}|[\da-fA-F]{6})$/;

const normalizeIconBackground = (value: unknown): string | null => {
  if (typeof value !== 'string') {
    return null;
  }
  const trimmed = value.trim();
  if (!trimmed) {
    return null;
  }
  return HEX_COLOR_PATTERN.test(trimmed) ? trimmed.toLowerCase() : null;
};

const sanitizeProjects = (value: unknown): DesktopSettings['projects'] | undefined => {
  if (!Array.isArray(value)) {
    return undefined;
  }

  const result: NonNullable<DesktopSettings['projects']> = [];
  const seenIds = new Set<string>();
  const seenPaths = new Set<string>();

  for (const entry of value) {
    if (!entry || typeof entry !== 'object') continue;
    const candidate = entry as Record<string, unknown>;

    const rawPath = typeof candidate.path === 'string' ? candidate.path.trim() : '';
    if (!rawPath) continue;

    const normalizedPath = rawPath === '/' ? rawPath : rawPath.replace(/\\/g, '/').replace(/\/+$/, '');
    if (!normalizedPath) continue;

    const id = createProjectIdFromPath(normalizedPath);
    if (!id) continue;

    if (seenIds.has(id) || seenPaths.has(normalizedPath)) continue;
    seenIds.add(id);
    seenPaths.add(normalizedPath);

    const project: NonNullable<DesktopSettings['projects']>[number] = {
      id,
      path: normalizedPath,
    };

    if (typeof candidate.label === 'string' && candidate.label.trim().length > 0) {
      project.label = candidate.label.trim();
    }
    if (typeof candidate.icon === 'string' && candidate.icon.trim().length > 0) {
      project.icon = candidate.icon.trim();
    }
    if (candidate.iconImage === null) {
      (project as unknown as Record<string, unknown>).iconImage = null;
    } else if (candidate.iconImage && typeof candidate.iconImage === 'object') {
      const iconImage = candidate.iconImage as Record<string, unknown>;
      const mime = typeof iconImage.mime === 'string' ? iconImage.mime.trim() : '';
      const updatedAt = typeof iconImage.updatedAt === 'number' && Number.isFinite(iconImage.updatedAt)
        ? Math.max(0, Math.round(iconImage.updatedAt))
        : 0;
      const source = iconImage.source === 'custom' || iconImage.source === 'auto'
        ? iconImage.source
        : null;
      if (mime && updatedAt > 0 && source) {
        (project as unknown as Record<string, unknown>).iconImage = { mime, updatedAt, source };
      }
    }
    if (typeof candidate.color === 'string' && candidate.color.trim().length > 0) {
      project.color = candidate.color.trim();
    }
    if (candidate.iconBackground === null) {
      (project as unknown as Record<string, unknown>).iconBackground = null;
    } else {
      const iconBackground = normalizeIconBackground(candidate.iconBackground);
      if (iconBackground) {
        (project as unknown as Record<string, unknown>).iconBackground = iconBackground;
      }
    }
    if (typeof candidate.addedAt === 'number' && Number.isFinite(candidate.addedAt) && candidate.addedAt >= 0) {
      project.addedAt = candidate.addedAt;
    }
    if (
      typeof candidate.lastOpenedAt === 'number' &&
      Number.isFinite(candidate.lastOpenedAt) &&
      candidate.lastOpenedAt >= 0
    ) {
      project.lastOpenedAt = candidate.lastOpenedAt;
    }
    if (typeof candidate.sidebarCollapsed === 'boolean') {
      (project as unknown as Record<string, unknown>).sidebarCollapsed = candidate.sidebarCollapsed;
    }
    result.push(project);
  }

  return result.length > 0 ? result : undefined;
};

const sanitizeManagedRemoteTunnelPresets = (value: unknown): DesktopSettings['managedRemoteTunnelPresets'] | undefined => {
  if (!Array.isArray(value)) {
    return undefined;
  }

  const result: NonNullable<DesktopSettings['managedRemoteTunnelPresets']> = [];
  const seenIds = new Set<string>();
  const seenHostnames = new Set<string>();

  for (const entry of value) {
    if (!entry || typeof entry !== 'object') continue;
    const candidate = entry as Record<string, unknown>;

    const id = typeof candidate.id === 'string' ? candidate.id.trim() : '';
    const name = typeof candidate.name === 'string' ? candidate.name.trim() : '';
    const hostname = typeof candidate.hostname === 'string' ? candidate.hostname.trim().toLowerCase() : '';

    if (!id || !name || !hostname) continue;
    if (seenIds.has(id) || seenHostnames.has(hostname)) continue;
    seenIds.add(id);
    seenHostnames.add(hostname);

    result.push({ id, name, hostname });
  }

  return result;
};

const sanitizeManagedRemoteTunnelPresetTokens = (value: unknown): DesktopSettings['managedRemoteTunnelPresetTokens'] | undefined => {
  if (!value || typeof value !== 'object' || Array.isArray(value)) {
    return undefined;
  }

  const candidate = value as Record<string, unknown>;
  const result: Record<string, string> = {};
  for (const [key, tokenValue] of Object.entries(candidate)) {
    const id = key.trim();
    const token = typeof tokenValue === 'string' ? tokenValue.trim() : '';
    if (!id || !token) continue;
    result[id] = token;
  }

  return Object.keys(result).length > 0 ? result : undefined;
};

const sanitizeModelRefs = (value: unknown, limit: number): Array<{ providerID: string; modelID: string }> | undefined => {
  if (!Array.isArray(value)) {
    return undefined;
  }

  const result: Array<{ providerID: string; modelID: string }> = [];
  const seen = new Set<string>();

  for (const entry of value) {
    if (!entry || typeof entry !== 'object') continue;
    const candidate = entry as Record<string, unknown>;
    const providerID = typeof candidate.providerID === 'string' ? candidate.providerID.trim() : '';
    const modelID = typeof candidate.modelID === 'string' ? candidate.modelID.trim() : '';
    if (!providerID || !modelID) continue;
    const key = `${providerID}/${modelID}`;
    if (seen.has(key)) continue;
    seen.add(key);
    result.push({ providerID, modelID });
    if (result.length >= limit) break;
  }

  return result;
};

const getPersistApi = (): PersistApi | undefined => {
  const candidate = (useUIStore as unknown as { persist?: PersistApi }).persist;
  if (candidate && typeof candidate === 'object') {
    return candidate;
  }
  return undefined;
};

const getRuntimeSettingsAPI = () => getRegisteredRuntimeAPIs()?.settings ?? null;

const applyDesktopUiPreferences = (settings: DesktopSettings) => {
  const store = useUIStore.getState();
  const configStore = typeof window !== 'undefined'
    ? window.__zustand_config_store__?.getState?.() ?? null
    : null;
  const configStoreApi = typeof window !== 'undefined'
    ? window.__zustand_config_store__ ?? null
    : null;
  const queueStore = useMessageQueueStore.getState();

  if (typeof settings.showReasoningTraces === 'boolean' && settings.showReasoningTraces !== store.showReasoningTraces) {
    store.setShowReasoningTraces(settings.showReasoningTraces);
  }
  if (typeof settings.collapsibleThinkingBlocks === 'boolean' && settings.collapsibleThinkingBlocks !== store.collapsibleThinkingBlocks) {
    store.setCollapsibleThinkingBlocks(settings.collapsibleThinkingBlocks);
  }
  if (typeof settings.autoDeleteEnabled === 'boolean' && settings.autoDeleteEnabled !== store.autoDeleteEnabled) {
    store.setAutoDeleteEnabled(settings.autoDeleteEnabled);
  }
  if (typeof settings.autoDeleteAfterDays === 'number' && Number.isFinite(settings.autoDeleteAfterDays)) {
    const normalized = Math.max(1, Math.min(365, settings.autoDeleteAfterDays));
    if (normalized !== store.autoDeleteAfterDays) {
      store.setAutoDeleteAfterDays(normalized);
    }
  }
  if (settings.sessionRetentionAction === 'archive' || settings.sessionRetentionAction === 'delete') {
    if (settings.sessionRetentionAction !== store.sessionRetentionAction) {
      store.setSessionRetentionAction(settings.sessionRetentionAction);
    }
  }

  if (typeof settings.queueModeEnabled === 'boolean' && settings.queueModeEnabled !== queueStore.queueModeEnabled) {
    queueStore.setQueueMode(settings.queueModeEnabled);
  }

  if (typeof settings.showDeletionDialog === 'boolean' && settings.showDeletionDialog !== store.showDeletionDialog) {
    store.setShowDeletionDialog(settings.showDeletionDialog);
  }
  if (typeof settings.nativeNotificationsEnabled === 'boolean' && settings.nativeNotificationsEnabled !== store.nativeNotificationsEnabled) {
    store.setNativeNotificationsEnabled(settings.nativeNotificationsEnabled);
  }
  if (typeof settings.notificationMode === 'string' && (settings.notificationMode === 'always' || settings.notificationMode === 'hidden-only')) {
    if (settings.notificationMode !== store.notificationMode) {
      store.setNotificationMode(settings.notificationMode);
    }
  }
  if (typeof settings.notifyOnSubtasks === 'boolean' && settings.notifyOnSubtasks !== store.notifyOnSubtasks) {
    store.setNotifyOnSubtasks(settings.notifyOnSubtasks);
  }
  if (typeof settings.notifyOnCompletion === 'boolean' && settings.notifyOnCompletion !== store.notifyOnCompletion) {
    store.setNotifyOnCompletion(settings.notifyOnCompletion);
  }
  if (typeof settings.notifyOnError === 'boolean' && settings.notifyOnError !== store.notifyOnError) {
    store.setNotifyOnError(settings.notifyOnError);
  }
  if (typeof settings.notifyOnQuestion === 'boolean' && settings.notifyOnQuestion !== store.notifyOnQuestion) {
    store.setNotifyOnQuestion(settings.notifyOnQuestion);
  }
  if (settings.notificationTemplates && typeof settings.notificationTemplates === 'object') {
    store.setNotificationTemplates(settings.notificationTemplates);
  }
  if (typeof settings.summarizeLastMessage === 'boolean' && settings.summarizeLastMessage !== store.summarizeLastMessage) {
    store.setSummarizeLastMessage(settings.summarizeLastMessage);
  }
  if (typeof settings.summaryThreshold === 'number' && Number.isFinite(settings.summaryThreshold)) {
    store.setSummaryThreshold(settings.summaryThreshold);
  }
  if (typeof settings.summaryLength === 'number' && Number.isFinite(settings.summaryLength)) {
    store.setSummaryLength(settings.summaryLength);
  }
  if (typeof settings.maxLastMessageLength === 'number' && Number.isFinite(settings.maxLastMessageLength)) {
    store.setMaxLastMessageLength(settings.maxLastMessageLength);
  }
  if (typeof settings.inputSpellcheckEnabled === 'boolean' && settings.inputSpellcheckEnabled !== store.inputSpellcheckEnabled) {
    store.setInputSpellcheckEnabled(settings.inputSpellcheckEnabled);
  }
  if (typeof settings.showToolFileIcons === 'boolean' && settings.showToolFileIcons !== store.showToolFileIcons) {
    store.setShowToolFileIcons(settings.showToolFileIcons);
  }
  if (typeof settings.showExpandedBashTools === 'boolean' && settings.showExpandedBashTools !== store.showExpandedBashTools) {
    store.setShowExpandedBashTools(settings.showExpandedBashTools);
  }
  if (typeof settings.showExpandedEditTools === 'boolean' && settings.showExpandedEditTools !== store.showExpandedEditTools) {
    store.setShowExpandedEditTools(settings.showExpandedEditTools);
  }
  if (typeof settings.timeFormatPreference === 'string'
    && (settings.timeFormatPreference === 'auto' || settings.timeFormatPreference === '12h' || settings.timeFormatPreference === '24h')) {
    if (settings.timeFormatPreference !== store.timeFormatPreference) {
      store.setTimeFormatPreference(settings.timeFormatPreference);
    }
  }
  if (typeof settings.weekStartPreference === 'string'
    && (settings.weekStartPreference === 'auto' || settings.weekStartPreference === 'sunday' || settings.weekStartPreference === 'monday')) {
    if (settings.weekStartPreference !== store.weekStartPreference) {
      store.setWeekStartPreference(settings.weekStartPreference);
    }
  }
  if (typeof settings.chatRenderMode === 'string'
    && (settings.chatRenderMode === 'sorted' || settings.chatRenderMode === 'live')) {
    if (settings.chatRenderMode !== store.chatRenderMode) {
      store.setChatRenderMode(settings.chatRenderMode);
    }
  }
  if (typeof settings.activityRenderMode === 'string'
    && (settings.activityRenderMode === 'collapsed' || settings.activityRenderMode === 'summary')) {
    if (settings.activityRenderMode !== store.activityRenderMode) {
      store.setActivityRenderMode(settings.activityRenderMode);
    }
  }
  if (typeof settings.mermaidRenderingMode === 'string'
    && (settings.mermaidRenderingMode === 'svg' || settings.mermaidRenderingMode === 'ascii')) {
    if (settings.mermaidRenderingMode !== store.mermaidRenderingMode) {
      store.setMermaidRenderingMode(settings.mermaidRenderingMode);
    }
  }
  if (typeof settings.userMessageRenderingMode === 'string'
    && (settings.userMessageRenderingMode === 'markdown' || settings.userMessageRenderingMode === 'plain')) {
    if (settings.userMessageRenderingMode !== store.userMessageRenderingMode) {
      store.setUserMessageRenderingMode(settings.userMessageRenderingMode);
    }
  }
  if (typeof settings.messageStreamTransport === 'string'
    && (settings.messageStreamTransport === 'auto' || settings.messageStreamTransport === 'ws' || settings.messageStreamTransport === 'sse')) {
    if (configStore && settings.messageStreamTransport !== configStore.settingsMessageStreamTransport) {
      configStore.setSettingsMessageStreamTransport(settings.messageStreamTransport);
    }
  }
  if (typeof settings.stickyUserHeader === 'boolean' && settings.stickyUserHeader !== store.stickyUserHeader) {
    store.setStickyUserHeader(settings.stickyUserHeader);
  }
  if (typeof settings.wideChatLayoutEnabled === 'boolean' && settings.wideChatLayoutEnabled !== store.wideChatLayoutEnabled) {
    store.setWideChatLayoutEnabled(settings.wideChatLayoutEnabled);
  }
  if (
    typeof settings.showSplitAssistantMessageActions === 'boolean'
    && settings.showSplitAssistantMessageActions !== store.showSplitAssistantMessageActions
  ) {
    store.setShowSplitAssistantMessageActions(settings.showSplitAssistantMessageActions);
  }
  if (typeof settings.reportUsage === 'boolean' && settings.reportUsage !== store.reportUsage) {
    store.setReportUsage(settings.reportUsage);
  }
  if (typeof settings.fontSize === 'number' && Number.isFinite(settings.fontSize) && settings.fontSize !== store.fontSize) {
    store.setFontSize(settings.fontSize);
  }
  if (typeof settings.terminalFontSize === 'number' && Number.isFinite(settings.terminalFontSize) && settings.terminalFontSize !== store.terminalFontSize) {
    store.setTerminalFontSize(settings.terminalFontSize);
  }
  if (isUiFontOption(settings.uiFont) && settings.uiFont !== store.uiFont) {
    store.setUiFont(settings.uiFont);
  }
  if (isMonoFontOption(settings.monoFont) && settings.monoFont !== store.monoFont) {
    store.setMonoFont(settings.monoFont);
  }
  if (typeof settings.padding === 'number' && Number.isFinite(settings.padding) && settings.padding !== store.padding) {
    store.setPadding(settings.padding);
  }
  if (typeof settings.cornerRadius === 'number' && Number.isFinite(settings.cornerRadius) && settings.cornerRadius !== store.cornerRadius) {
    store.setCornerRadius(settings.cornerRadius);
  }
  if (typeof settings.inputBarOffset === 'number' && Number.isFinite(settings.inputBarOffset) && settings.inputBarOffset !== store.inputBarOffset) {
    store.setInputBarOffset(settings.inputBarOffset);
  }
  if (typeof settings.mobileKeyboardMode === 'string') {
    const mode = normalizeMobileKeyboardMode(settings.mobileKeyboardMode, store.mobileKeyboardMode);
    if (mode !== store.mobileKeyboardMode) {
      store.setMobileKeyboardMode(mode);
    }
  }
  if (configStoreApi && configStore) {
    const nextConfigState: Partial<typeof configStore> = {};
    if ((settings.sttProvider === 'browser' || settings.sttProvider === 'server') && settings.sttProvider !== configStore.sttProvider) {
      nextConfigState.sttProvider = settings.sttProvider;
    }
    if (typeof settings.sttServerUrl === 'string' && settings.sttServerUrl !== configStore.sttServerUrl) {
      nextConfigState.sttServerUrl = settings.sttServerUrl;
    }
    if (typeof settings.sttModel === 'string' && settings.sttModel !== configStore.sttModel) {
      nextConfigState.sttModel = settings.sttModel;
    }
    if (typeof settings.sttLanguage === 'string' && settings.sttLanguage !== configStore.sttLanguage) {
      nextConfigState.sttLanguage = settings.sttLanguage;
    }
    if (typeof settings.sttSilenceThresholdDb === 'number' && Number.isFinite(settings.sttSilenceThresholdDb) && settings.sttSilenceThresholdDb !== configStore.sttSilenceThresholdDb) {
      nextConfigState.sttSilenceThresholdDb = settings.sttSilenceThresholdDb;
    }
    if (typeof settings.sttSilenceHoldMs === 'number' && Number.isFinite(settings.sttSilenceHoldMs) && settings.sttSilenceHoldMs !== configStore.sttSilenceHoldMs) {
      nextConfigState.sttSilenceHoldMs = settings.sttSilenceHoldMs;
    }
    if (typeof settings.sttTranscribeOnStop === 'boolean' && settings.sttTranscribeOnStop !== configStore.sttTranscribeOnStop) {
      nextConfigState.sttTranscribeOnStop = settings.sttTranscribeOnStop;
    }
    if (Object.keys(nextConfigState).length > 0) {
      configStoreApi.setState(nextConfigState);
    }
  }

  if (Array.isArray(settings.favoriteModels)) {
    const current = store.favoriteModels;
    const next = settings.favoriteModels;
    const same =
      current.length === next.length &&
      current.every((item, idx) => item.providerID === next[idx]?.providerID && item.modelID === next[idx]?.modelID);
    if (!same) {
      useUIStore.setState({ favoriteModels: next });
    }
  }

  if (Array.isArray(settings.recentModels)) {
    const current = store.recentModels;
    const next = settings.recentModels;
    const same =
      current.length === next.length &&
      current.every((item, idx) => item.providerID === next[idx]?.providerID && item.modelID === next[idx]?.modelID);
    if (!same) {
      useUIStore.setState({ recentModels: next });
    }
  }
  if (typeof settings.diffLayoutPreference === 'string'
    && (settings.diffLayoutPreference === 'dynamic' || settings.diffLayoutPreference === 'inline' || settings.diffLayoutPreference === 'side-by-side')) {
    if (settings.diffLayoutPreference !== store.diffLayoutPreference) {
      store.setDiffLayoutPreference(settings.diffLayoutPreference);
    }
  }
  if (typeof settings.diffViewMode === 'string'
    && (settings.diffViewMode === 'single' || settings.diffViewMode === 'stacked')) {
    if (settings.diffViewMode !== store.diffViewMode) {
      store.setDiffViewMode(settings.diffViewMode);
    }
  }
  if (typeof settings.gitChangesViewMode === 'string'
    && (settings.gitChangesViewMode === 'flat' || settings.gitChangesViewMode === 'tree')) {
    if (settings.gitChangesViewMode !== store.gitChangesViewMode) {
      store.setGitChangesViewMode(settings.gitChangesViewMode);
    }
  }
  if (typeof settings.directoryShowHidden === 'boolean') {
    setDirectoryShowHidden(settings.directoryShowHidden, { persist: false });
  }
  if (typeof settings.filesViewShowGitignored === 'boolean') {
    setFilesViewShowGitignored(settings.filesViewShowGitignored, { persist: false });
  }
};

const sanitizeWebSettings = (payload: unknown): DesktopSettings | null => {
  if (!payload || typeof payload !== 'object') {
    return null;
  }

  const candidate = payload as Record<string, unknown>;
  const result: DesktopSettings = {};

  if (typeof candidate.themeId === 'string' && candidate.themeId.length > 0) {
    result.themeId = candidate.themeId;
  }
  if (candidate.useSystemTheme === true || candidate.useSystemTheme === false) {
    result.useSystemTheme = candidate.useSystemTheme;
  }
  if (typeof candidate.themeVariant === 'string' && (candidate.themeVariant === 'light' || candidate.themeVariant === 'dark')) {
    result.themeVariant = candidate.themeVariant;
  }
  if (typeof candidate.lightThemeId === 'string' && candidate.lightThemeId.length > 0) {
    result.lightThemeId = candidate.lightThemeId;
  }
  if (typeof candidate.darkThemeId === 'string' && candidate.darkThemeId.length > 0) {
    result.darkThemeId = candidate.darkThemeId;
  }
  if (typeof candidate.lastDirectory === 'string' && candidate.lastDirectory.length > 0) {
    result.lastDirectory = candidate.lastDirectory;
  }
  if (typeof candidate.homeDirectory === 'string' && candidate.homeDirectory.length > 0) {
    result.homeDirectory = candidate.homeDirectory;
  }

  if (typeof candidate.opencodeBinary === 'string') {
    const trimmed = candidate.opencodeBinary.trim();
    result.opencodeBinary = trimmed.length > 0 ? trimmed : undefined;
  }
  if (typeof candidate.desktopLanAccessEnabled === 'boolean') {
    result.desktopLanAccessEnabled = candidate.desktopLanAccessEnabled;
  }

  const projects = sanitizeProjects(candidate.projects);
  if (projects) {
    result.projects = projects;
  }
  if (typeof candidate.activeProjectId === 'string' && candidate.activeProjectId.length > 0) {
    result.activeProjectId = candidate.activeProjectId;
  }

  if (Array.isArray(candidate.approvedDirectories)) {
    result.approvedDirectories = candidate.approvedDirectories.filter(
      (entry): entry is string => typeof entry === 'string' && entry.length > 0
    );
  }
  if (Array.isArray(candidate.securityScopedBookmarks)) {
    result.securityScopedBookmarks = candidate.securityScopedBookmarks.filter(
      (entry): entry is string => typeof entry === 'string' && entry.length > 0
    );
  }
  if (Array.isArray(candidate.pinnedDirectories)) {
    result.pinnedDirectories = Array.from(
      new Set(
        candidate.pinnedDirectories.filter((entry): entry is string => typeof entry === 'string' && entry.length > 0)
      )
    );
  }
  if (typeof candidate.showReasoningTraces === 'boolean') {
    result.showReasoningTraces = candidate.showReasoningTraces;
  }
  if (typeof candidate.collapsibleThinkingBlocks === 'boolean') {
    result.collapsibleThinkingBlocks = candidate.collapsibleThinkingBlocks;
  }
  if (typeof candidate.autoDeleteEnabled === 'boolean') {
    result.autoDeleteEnabled = candidate.autoDeleteEnabled;
  }
  if (typeof candidate.autoDeleteAfterDays === 'number' && Number.isFinite(candidate.autoDeleteAfterDays)) {
    result.autoDeleteAfterDays = candidate.autoDeleteAfterDays;
  }
  if (candidate.sessionRetentionAction === 'archive' || candidate.sessionRetentionAction === 'delete') {
    result.sessionRetentionAction = candidate.sessionRetentionAction;
  }
  if (typeof candidate.tunnelProvider === 'string') {
    const provider = candidate.tunnelProvider.trim().toLowerCase();
    if (provider.length > 0) {
      result.tunnelProvider = provider;
    }
  }
  if (typeof candidate.tunnelMode === 'string') {
    const mode = candidate.tunnelMode.trim().toLowerCase();
    if (mode === 'quick' || mode === 'managed-remote' || mode === 'managed-local') {
      result.tunnelMode = mode;
    }
  }
  if (candidate.tunnelBootstrapTtlMs === null) {
    result.tunnelBootstrapTtlMs = null;
  } else if (typeof candidate.tunnelBootstrapTtlMs === 'number' && Number.isFinite(candidate.tunnelBootstrapTtlMs)) {
    result.tunnelBootstrapTtlMs = candidate.tunnelBootstrapTtlMs;
  }
  if (typeof candidate.tunnelSessionTtlMs === 'number' && Number.isFinite(candidate.tunnelSessionTtlMs)) {
    result.tunnelSessionTtlMs = candidate.tunnelSessionTtlMs;
  }
  if (candidate.managedLocalTunnelConfigPath === null) {
    result.managedLocalTunnelConfigPath = null;
  } else if (typeof candidate.managedLocalTunnelConfigPath === 'string') {
    const trimmed = candidate.managedLocalTunnelConfigPath.trim();
    result.managedLocalTunnelConfigPath = trimmed.length > 0 ? trimmed : null;
  }
  if (typeof candidate.managedRemoteTunnelHostname === 'string') {
    result.managedRemoteTunnelHostname = candidate.managedRemoteTunnelHostname.trim();
  }
  if (candidate.managedRemoteTunnelToken === null) {
    result.managedRemoteTunnelToken = null;
  } else if (typeof candidate.managedRemoteTunnelToken === 'string') {
    result.managedRemoteTunnelToken = candidate.managedRemoteTunnelToken.trim();
  }
  const managedRemoteTunnelPresets = sanitizeManagedRemoteTunnelPresets(candidate.managedRemoteTunnelPresets);
  if (managedRemoteTunnelPresets) {
    result.managedRemoteTunnelPresets = managedRemoteTunnelPresets;
  }
  if (typeof candidate.managedRemoteTunnelSelectedPresetId === 'string') {
    const trimmed = candidate.managedRemoteTunnelSelectedPresetId.trim();
    result.managedRemoteTunnelSelectedPresetId = trimmed.length > 0 ? trimmed : undefined;
  }
  const managedRemoteTunnelPresetTokens = sanitizeManagedRemoteTunnelPresetTokens(candidate.managedRemoteTunnelPresetTokens);
  if (managedRemoteTunnelPresetTokens) {
    result.managedRemoteTunnelPresetTokens = managedRemoteTunnelPresetTokens;
  }
  if (typeof candidate.defaultModel === 'string' && candidate.defaultModel.length > 0) {
    result.defaultModel = candidate.defaultModel;
  }
  if (typeof candidate.defaultVariant === 'string' && candidate.defaultVariant.length > 0) {
    result.defaultVariant = candidate.defaultVariant;
  }
  if (typeof candidate.defaultAgent === 'string' && candidate.defaultAgent.length > 0) {
    result.defaultAgent = candidate.defaultAgent;
  }
  if (typeof candidate.autoCreateWorktree === 'boolean') {
    result.autoCreateWorktree = candidate.autoCreateWorktree;
  }
  if (typeof candidate.gitmojiEnabled === 'boolean') {
    result.gitmojiEnabled = candidate.gitmojiEnabled;
  }
  if (typeof candidate.queueModeEnabled === 'boolean') {
    result.queueModeEnabled = candidate.queueModeEnabled;
  }
  if (typeof candidate.showDeletionDialog === 'boolean') {
    result.showDeletionDialog = candidate.showDeletionDialog;
  }
  if (typeof candidate.nativeNotificationsEnabled === 'boolean') {
    result.nativeNotificationsEnabled = candidate.nativeNotificationsEnabled;
  }
  if (typeof candidate.notificationMode === 'string' && (candidate.notificationMode === 'always' || candidate.notificationMode === 'hidden-only')) {
    result.notificationMode = candidate.notificationMode;
  }
  if (typeof candidate.notifyOnSubtasks === 'boolean') {
    result.notifyOnSubtasks = candidate.notifyOnSubtasks;
  }
  if (typeof candidate.notifyOnCompletion === 'boolean') {
    result.notifyOnCompletion = candidate.notifyOnCompletion;
  }
  if (typeof candidate.notifyOnError === 'boolean') {
    result.notifyOnError = candidate.notifyOnError;
  }
  if (typeof candidate.notifyOnQuestion === 'boolean') {
    result.notifyOnQuestion = candidate.notifyOnQuestion;
  }
  if (candidate.notificationTemplates && typeof candidate.notificationTemplates === 'object') {
    const templates = candidate.notificationTemplates as Record<string, unknown>;
    const validateTemplate = (key: string): { title: string; message: string } | undefined => {
      const value = templates[key];
      if (!value || typeof value !== 'object') return undefined;
      const obj = value as Record<string, unknown>;
      const title = typeof obj.title === 'string' ? obj.title : '';
      const message = typeof obj.message === 'string' ? obj.message : '';
      return { title, message };
    };
    const completion = validateTemplate('completion');
    const error = validateTemplate('error');
    const question = validateTemplate('question');
    const subtask = validateTemplate('subtask');
    if (completion || error || question || subtask) {
      result.notificationTemplates = {
        completion: completion ?? { title: 'Task Complete', message: 'Your task has finished.' },
        error: error ?? { title: 'Error Occurred', message: 'An error occurred while processing your task.' },
        question: question ?? { title: 'Input Needed', message: 'Please provide input to continue.' },
        subtask: subtask ?? { title: 'Subtask Complete', message: 'A subtask has finished.' },
      };
    }
  }
  if (typeof candidate.summarizeLastMessage === 'boolean') {
    result.summarizeLastMessage = candidate.summarizeLastMessage;
  }
  if (typeof candidate.summaryThreshold === 'number' && Number.isFinite(candidate.summaryThreshold)) {
    result.summaryThreshold = Math.max(0, Math.round(candidate.summaryThreshold));
  }
  if (typeof candidate.summaryLength === 'number' && Number.isFinite(candidate.summaryLength)) {
    result.summaryLength = Math.max(10, Math.round(candidate.summaryLength));
  }
  if (typeof candidate.maxLastMessageLength === 'number' && Number.isFinite(candidate.maxLastMessageLength)) {
    result.maxLastMessageLength = Math.max(10, Math.round(candidate.maxLastMessageLength));
  }
  if (typeof candidate.usageAutoRefresh === 'boolean') {
    result.usageAutoRefresh = candidate.usageAutoRefresh;
  }
  if (typeof candidate.usageRefreshIntervalMs === 'number' && Number.isFinite(candidate.usageRefreshIntervalMs)) {
    result.usageRefreshIntervalMs = candidate.usageRefreshIntervalMs;
  }
  if (candidate.usageDisplayMode === 'usage' || candidate.usageDisplayMode === 'remaining') {
    result.usageDisplayMode = candidate.usageDisplayMode;
  }
  if (Array.isArray(candidate.usageDropdownProviders)) {
    result.usageDropdownProviders = candidate.usageDropdownProviders.filter(
      (entry): entry is string => typeof entry === 'string' && entry.length > 0
    );
  }

  // Parse usageSelectedModels (Record<string, string[]>)
  if (candidate.usageSelectedModels && typeof candidate.usageSelectedModels === 'object') {
    const selectedModels: Record<string, string[]> = {};
    for (const [providerId, models] of Object.entries(candidate.usageSelectedModels)) {
      if (Array.isArray(models)) {
        selectedModels[providerId] = models.filter((m): m is string => typeof m === 'string');
      }
    }
    if (Object.keys(selectedModels).length > 0) {
      result.usageSelectedModels = selectedModels;
    }
  }

  // Parse usageCollapsedFamilies (Record<string, string[]>)
  if (candidate.usageCollapsedFamilies && typeof candidate.usageCollapsedFamilies === 'object') {
    const collapsedFamilies: Record<string, string[]> = {};
    for (const [providerId, families] of Object.entries(candidate.usageCollapsedFamilies)) {
      if (Array.isArray(families)) {
        collapsedFamilies[providerId] = families.filter((f): f is string => typeof f === 'string');
      }
    }
    if (Object.keys(collapsedFamilies).length > 0) {
      result.usageCollapsedFamilies = collapsedFamilies;
    }
  }

  // Parse usageExpandedFamilies (Record<string, string[]>) - inverted collapsed logic for header dropdown
  if (candidate.usageExpandedFamilies && typeof candidate.usageExpandedFamilies === 'object') {
    const expandedFamilies: Record<string, string[]> = {};
    for (const [providerId, families] of Object.entries(candidate.usageExpandedFamilies)) {
      if (Array.isArray(families)) {
        expandedFamilies[providerId] = families.filter((f): f is string => typeof f === 'string');
      }
    }
    if (Object.keys(expandedFamilies).length > 0) {
      result.usageExpandedFamilies = expandedFamilies;
    }
  }

  // Parse usageModelGroups - custom model groups configuration per provider
  if (candidate.usageModelGroups && typeof candidate.usageModelGroups === 'object') {
    const modelGroups: Record<string, {
      customGroups?: Array<{id: string; label: string; models: string[]; order: number}>;
      modelAssignments?: Record<string, string>;
      renamedGroups?: Record<string, string>;
    }> = {};
    for (const [providerId, config] of Object.entries(candidate.usageModelGroups)) {
      if (config && typeof config === 'object') {
        const typedConfig = config as Record<string, unknown>;
        const providerConfig: {
          customGroups?: Array<{id: string; label: string; models: string[]; order: number}>;
          modelAssignments?: Record<string, string>;
          renamedGroups?: Record<string, string>;
        } = {};

        // Parse customGroups
        if (Array.isArray(typedConfig.customGroups)) {
          providerConfig.customGroups = typedConfig.customGroups
            .filter((g): g is Record<string, unknown> => g && typeof g === 'object')
            .map((g) => ({
              id: String(g.id ?? ''),
              label: String(g.label ?? ''),
              models: Array.isArray(g.models)
                ? g.models.filter((m): m is string => typeof m === 'string')
                : [],
              order: typeof g.order === 'number' ? g.order : 0,
            }));
        }

        // Parse modelAssignments
        if (typedConfig.modelAssignments && typeof typedConfig.modelAssignments === 'object') {
          providerConfig.modelAssignments = Object.fromEntries(
            Object.entries(typedConfig.modelAssignments as Record<string, unknown>)
              .filter(([, v]) => typeof v === 'string')
              .map(([k, v]) => [k, String(v)])
          );
        }

        // Parse renamedGroups
        if (typedConfig.renamedGroups && typeof typedConfig.renamedGroups === 'object') {
          providerConfig.renamedGroups = Object.fromEntries(
            Object.entries(typedConfig.renamedGroups as Record<string, unknown>)
              .filter(([, v]) => typeof v === 'string')
              .map(([k, v]) => [k, String(v)])
          );
        }

        if (Object.keys(providerConfig).length > 0) {
          modelGroups[providerId] = providerConfig;
        }
      }
    }
    if (Object.keys(modelGroups).length > 0) {
      result.usageModelGroups = modelGroups;
    }
  }

  if (typeof candidate.inputSpellcheckEnabled === 'boolean') {
    result.inputSpellcheckEnabled = candidate.inputSpellcheckEnabled;
  }
  if (typeof candidate.showToolFileIcons === 'boolean') {
    result.showToolFileIcons = candidate.showToolFileIcons;
  }
  if (typeof candidate.showExpandedBashTools === 'boolean') {
    result.showExpandedBashTools = candidate.showExpandedBashTools;
  }
  if (typeof candidate.showExpandedEditTools === 'boolean') {
    result.showExpandedEditTools = candidate.showExpandedEditTools;
  }
  if (typeof candidate.timeFormatPreference === 'string'
    && (candidate.timeFormatPreference === 'auto' || candidate.timeFormatPreference === '12h' || candidate.timeFormatPreference === '24h')) {
    result.timeFormatPreference = candidate.timeFormatPreference;
  }
  if (typeof candidate.weekStartPreference === 'string'
    && (candidate.weekStartPreference === 'auto' || candidate.weekStartPreference === 'sunday' || candidate.weekStartPreference === 'monday')) {
    result.weekStartPreference = candidate.weekStartPreference;
  }
  if (typeof candidate.chatRenderMode === 'string'
    && (candidate.chatRenderMode === 'sorted' || candidate.chatRenderMode === 'live')) {
    result.chatRenderMode = candidate.chatRenderMode;
  }
  if (typeof candidate.messageStreamTransport === 'string'
    && (candidate.messageStreamTransport === 'auto' || candidate.messageStreamTransport === 'ws' || candidate.messageStreamTransport === 'sse')) {
    result.messageStreamTransport = candidate.messageStreamTransport;
  }
  if (typeof candidate.activityRenderMode === 'string'
    && (candidate.activityRenderMode === 'collapsed' || candidate.activityRenderMode === 'summary')) {
    result.activityRenderMode = candidate.activityRenderMode;
  }
  if (typeof candidate.mermaidRenderingMode === 'string'
    && (candidate.mermaidRenderingMode === 'svg' || candidate.mermaidRenderingMode === 'ascii')) {
    result.mermaidRenderingMode = candidate.mermaidRenderingMode;
  }
  if (typeof candidate.userMessageRenderingMode === 'string'
    && (candidate.userMessageRenderingMode === 'markdown' || candidate.userMessageRenderingMode === 'plain')) {
    result.userMessageRenderingMode = candidate.userMessageRenderingMode;
  }
  if (typeof candidate.stickyUserHeader === 'boolean') {
    result.stickyUserHeader = candidate.stickyUserHeader;
  }
  if (typeof candidate.wideChatLayoutEnabled === 'boolean') {
    result.wideChatLayoutEnabled = candidate.wideChatLayoutEnabled;
  }
  if (typeof candidate.showSplitAssistantMessageActions === 'boolean') {
    result.showSplitAssistantMessageActions = candidate.showSplitAssistantMessageActions;
  }
  if (typeof candidate.fontSize === 'number' && Number.isFinite(candidate.fontSize)) {
    result.fontSize = candidate.fontSize;
  }
  if (typeof candidate.terminalFontSize === 'number' && Number.isFinite(candidate.terminalFontSize)) {
    result.terminalFontSize = candidate.terminalFontSize;
  }
  if (isUiFontOption(candidate.uiFont)) {
    result.uiFont = candidate.uiFont;
  }
  if (isMonoFontOption(candidate.monoFont)) {
    result.monoFont = candidate.monoFont;
  }
  if (typeof candidate.padding === 'number' && Number.isFinite(candidate.padding)) {
    result.padding = candidate.padding;
  }
  if (typeof candidate.cornerRadius === 'number' && Number.isFinite(candidate.cornerRadius)) {
    result.cornerRadius = candidate.cornerRadius;
  }
  if (typeof candidate.inputBarOffset === 'number' && Number.isFinite(candidate.inputBarOffset)) {
    result.inputBarOffset = candidate.inputBarOffset;
  }
  if (typeof candidate.mobileKeyboardMode === 'string') {
    const mode = normalizeMobileKeyboardMode(candidate.mobileKeyboardMode, undefined);
    if (mode) {
      result.mobileKeyboardMode = mode;
    }
  }

  const favoriteModels = sanitizeModelRefs(candidate.favoriteModels, 64);
  if (favoriteModels) {
    result.favoriteModels = favoriteModels;
  }

  const recentModels = sanitizeModelRefs(candidate.recentModels, 16);
  if (recentModels) {
    result.recentModels = recentModels;
  }
  if (
    typeof candidate.diffLayoutPreference === 'string'
    && (candidate.diffLayoutPreference === 'dynamic'
      || candidate.diffLayoutPreference === 'inline'
      || candidate.diffLayoutPreference === 'side-by-side')
  ) {
    result.diffLayoutPreference = candidate.diffLayoutPreference;
  }
  if (
    typeof candidate.diffViewMode === 'string'
    && (candidate.diffViewMode === 'single' || candidate.diffViewMode === 'stacked')
  ) {
    result.diffViewMode = candidate.diffViewMode;
  }
  if (
    typeof candidate.gitChangesViewMode === 'string'
    && (candidate.gitChangesViewMode === 'flat' || candidate.gitChangesViewMode === 'tree')
  ) {
    result.gitChangesViewMode = candidate.gitChangesViewMode;
  }
  if (typeof candidate.directoryShowHidden === 'boolean') {
    result.directoryShowHidden = candidate.directoryShowHidden;
  }
  if (typeof candidate.filesViewShowGitignored === 'boolean') {
    result.filesViewShowGitignored = candidate.filesViewShowGitignored;
  }
  if (typeof candidate.openInAppId === 'string' && candidate.openInAppId.length > 0) {
    result.openInAppId = candidate.openInAppId;
  }
  if (typeof candidate.pwaAppName === 'string') {
    const normalized = candidate.pwaAppName.trim().replace(/\s+/g, ' ').slice(0, 64);
    result.pwaAppName = normalized.length > 0 ? normalized : '';
  }

  const skillCatalogs = sanitizeSkillCatalogs(candidate.skillCatalogs);
  if (skillCatalogs) {
    result.skillCatalogs = skillCatalogs;
  }

  if (typeof candidate.reportUsage === 'boolean') {
    result.reportUsage = candidate.reportUsage;
  }

  if (typeof candidate.globalBehaviorPrompt === 'string') {
    result.globalBehaviorPrompt = candidate.globalBehaviorPrompt;
  }
  if (typeof candidate.responseStyleEnabled === 'boolean') {
    result.responseStyleEnabled = candidate.responseStyleEnabled;
  }
  if (
    typeof candidate.responseStylePreset === 'string'
    && (candidate.responseStylePreset === 'concise'
      || candidate.responseStylePreset === 'detailed'
      || candidate.responseStylePreset === 'mentor'
      || candidate.responseStylePreset === 'pushback'
      || candidate.responseStylePreset === 'noFiller'
      || candidate.responseStylePreset === 'matchEnergy'
      || candidate.responseStylePreset === 'warmPeer'
      || candidate.responseStylePreset === 'custom')
  ) {
    result.responseStylePreset = candidate.responseStylePreset;
  }
  if (typeof candidate.responseStyleCustomInstructions === 'string') {
    result.responseStyleCustomInstructions = candidate.responseStyleCustomInstructions;
  }
  if (candidate.sttProvider === 'browser' || candidate.sttProvider === 'server') {
    result.sttProvider = candidate.sttProvider;
  }
  if (typeof candidate.sttServerUrl === 'string') {
    result.sttServerUrl = candidate.sttServerUrl.trim();
  }
  if (typeof candidate.sttModel === 'string') {
    result.sttModel = candidate.sttModel.trim();
  }
  if (typeof candidate.sttLanguage === 'string') {
    result.sttLanguage = candidate.sttLanguage.trim();
  }
  if (typeof candidate.sttSilenceThresholdDb === 'number' && Number.isFinite(candidate.sttSilenceThresholdDb)) {
    result.sttSilenceThresholdDb = candidate.sttSilenceThresholdDb;
  }
  if (typeof candidate.sttSilenceHoldMs === 'number' && Number.isFinite(candidate.sttSilenceHoldMs)) {
    result.sttSilenceHoldMs = candidate.sttSilenceHoldMs;
  }
  if (typeof candidate.sttTranscribeOnStop === 'boolean') {
    result.sttTranscribeOnStop = candidate.sttTranscribeOnStop;
  }

  return result;
};

// Short-lived cache + in-flight dedup for settings fetches to avoid repeated GET calls during startup
let _settingsCache: { value: DesktopSettings | null; at: number } | null = null;
let _settingsInflight: Promise<DesktopSettings | null> | null = null;
const SETTINGS_CACHE_TTL = 2_000; // 2 seconds — covers the startup burst

const fetchWebSettings = async (): Promise<DesktopSettings | null> => {
  // Return cached if fresh
  if (_settingsCache && Date.now() - _settingsCache.at < SETTINGS_CACHE_TTL) {
    return _settingsCache.value;
  }

  // Dedup concurrent calls
  if (_settingsInflight) return _settingsInflight;

  _settingsInflight = (async (): Promise<DesktopSettings | null> => {
    const runtimeSettings = getRuntimeSettingsAPI();
    if (runtimeSettings) {
      try {
        const result = await runtimeSettings.load();
        const settings = sanitizeWebSettings(result.settings);
        _settingsCache = { value: settings, at: Date.now() };
        return settings;
      } catch (error) {
        console.warn('Failed to load shared settings from runtime settings API:', error);
      }
    }

    try {
      const response = await fetch('/api/config/settings', {
        method: 'GET',
        headers: { Accept: 'application/json' },
      });
      if (!response.ok) {
        return null;
      }
      const data = await response.json().catch(() => null);
      const settings = sanitizeWebSettings(data);
      _settingsCache = { value: settings, at: Date.now() };
      return settings;
    } catch (error) {
      console.warn('Failed to load shared settings from server:', error);
      return null;
    }
  })().finally(() => { _settingsInflight = null; });

  return _settingsInflight;
};

/** Invalidate cached settings (call after a successful PUT) */
export const invalidateSettingsCache = (): void => {
  _settingsCache = null;
};

export const syncDesktopSettings = async (): Promise<void> => {
  if (typeof window === 'undefined') {
    return;
  }

  const persistApi = getPersistApi();

  // Wait for Zustand persist hydration before applying server settings.
  // Otherwise `set()`-calls race with hydration: we set X, then hydration
  // reads localStorage and overwrites back to the persisted value.
  const waitForHydration = (): Promise<void> => {
    if (!persistApi?.hasHydrated || persistApi.hasHydrated()) {
      return Promise.resolve();
    }
    if (!persistApi.onFinishHydration) {
      return Promise.resolve();
    }
    return new Promise<void>((resolve) => {
      let settled = false;
      const finish = () => {
        if (settled) return;
        settled = true;
        resolve();
      };
      const unsubscribe = persistApi.onFinishHydration!(() => {
        unsubscribe?.();
        finish();
      });
      // Guard: hydration may have flipped to true between the hasHydrated
      // check and the onFinishHydration subscription — resolve immediately.
      if (persistApi.hasHydrated?.()) finish();
    });
  };

  // Each step is wrapped in try/catch so a failure in one side-effect (e.g.
  // a TypeError from writing to a contextBridge-protected global) doesn't
  // prevent server settings from reaching the Zustand store.
  const applySettings = async (settings: DesktopSettings) => {
    try {
      persistToLocalStorage(settings);
    } catch (error) {
      console.warn('persistToLocalStorage failed:', error);
    }
    await waitForHydration();
    try {
      applyDesktopUiPreferences(settings);
    } catch (error) {
      console.warn('applyDesktopUiPreferences failed:', error);
    }

    if (typeof window !== 'undefined') {
      window.dispatchEvent(new CustomEvent<DesktopSettings>('openchamber:settings-synced', { detail: settings }));
    }
  };

  try {
    const webSettings = await fetchWebSettings();
    if (webSettings) {
      await applySettings(webSettings);
    }
  } catch (error) {
    console.warn('Failed to synchronise settings:', error);
  }
};

// Coalesce rapid updateDesktopSettings calls into a single PUT
let _pendingSettingsChanges: Partial<DesktopSettings> | null = null;
let _settingsFlushTimer: ReturnType<typeof setTimeout> | null = null;
const SETTINGS_DEBOUNCE_MS = 200;

const _flushSettingsUpdate = async (): Promise<void> => {
  const changes = _pendingSettingsChanges;
  _pendingSettingsChanges = null;
  _settingsFlushTimer = null;
  if (!changes || Object.keys(changes).length === 0) return;

  const runtimeSettings = getRuntimeSettingsAPI();
  if (runtimeSettings) {
    try {
      const updated = await runtimeSettings.save(changes);
      if (updated) {
        persistToLocalStorage(updated);
        applyDesktopUiPreferences(updated);
      }
      return;
    } catch (error) {
      console.warn('Failed to update settings via runtime settings API:', error);
    }
  }

  try {
    const response = await fetch('/api/config/settings', {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json',
        Accept: 'application/json',
      },
      body: JSON.stringify(changes),
    });

    if (!response.ok) {
      console.warn('Failed to update shared settings via API:', response.status, response.statusText);
      return;
    }

    const updated = (await response.json().catch(() => null)) as DesktopSettings | null;
    if (updated) {
      persistToLocalStorage(updated);
      applyDesktopUiPreferences(updated);
      // Invalidate GET cache so next read sees the fresh data
      _settingsCache = null;
    }
  } catch (error) {
    console.warn('Failed to update shared settings via API:', error);
  }
};

export const updateDesktopSettings = async (changes: Partial<DesktopSettings>): Promise<void> => {
  if (typeof window === 'undefined') {
    return;
  }

  _pendingSettingsChanges = { ...(_pendingSettingsChanges ?? {}), ...changes };

  if (_settingsFlushTimer) {
    clearTimeout(_settingsFlushTimer);
  }
  _settingsFlushTimer = setTimeout(() => void _flushSettingsUpdate(), SETTINGS_DEBOUNCE_MS);
};

export const initializeAppearancePreferences = async (): Promise<void> => {
  if (typeof window === 'undefined') {
    return;
  }

  const persistApi = getPersistApi();

  try {
    const appearance = await loadAppearancePreferences();
    if (!appearance) {
      return;
    }

    const applyAppearance = () => applyAppearancePreferences(appearance);

    if (persistApi?.hasHydrated?.()) {
      applyAppearance();
      return;
    }

    applyAppearance();
    if (persistApi?.onFinishHydration) {
      const unsubscribe = persistApi.onFinishHydration(() => {
        unsubscribe?.();
        applyAppearance();
      });
    }
  } catch (error) {
    console.warn('Failed to load appearance preferences:', error);
  }
};
