'use client'

import { HugeiconsIcon } from '@hugeicons/react'
import {
  ArrowLeft01Icon,
  Cancel01Icon,
  CheckmarkCircle02Icon,
  CloudIcon,
  ComputerIcon,
  MessageMultiple01Icon,
  Mic01Icon,
  Moon01Icon,
  Notification03Icon,
  PaintBoardIcon,
  Settings02Icon,
  Sun01Icon,
  VolumeHighIcon,
} from '@hugeicons/core-free-icons'
import { Component, useCallback, useEffect, useRef, useState } from 'react'
import type * as React from 'react'
import type { AccentColor, SettingsThemeMode } from '@/hooks/use-settings'
import type { LoaderStyle } from '@/hooks/use-chat-settings'
import type { BrailleSpinnerPreset } from '@/components/ui/braille-spinner'
import type { ThemeId } from '@/lib/theme'
import type {LocaleId} from '@/lib/i18n';
import { GROQ_STT_MODELS, STT_PROVIDER_OPTIONS } from '@/lib/stt-config'
import { Button } from '@/components/ui/button'
import { Switch } from '@/components/ui/switch'
import { applyTheme, useSettings } from '@/hooks/use-settings'
import {
  THEMES,
  getTheme,
  getThemeVariant,
  isDarkTheme,
  setTheme,
} from '@/lib/theme'
import { cn } from '@/lib/utils'
import {
  getChatProfileDisplayName,
  useChatSettingsStore,
} from '@/hooks/use-chat-settings'
import { UserAvatar } from '@/components/avatars'
import { Input } from '@/components/ui/input'
import { LogoLoader } from '@/components/logo-loader'
import { BrailleSpinner } from '@/components/ui/braille-spinner'
import { ThreeDotsSpinner } from '@/components/ui/three-dots-spinner'
import BackendUnavailableState from '@/components/backend-unavailable-state'
import { applyAccentColor } from '@/lib/accent-colors'
import { getUnavailableReason } from '@/lib/feature-gates'
import { useFeatureAvailable } from '@/hooks/use-feature-available'
import { ProviderLogo } from '@/components/provider-logo'
import {
  DialogClose,
  DialogContent,
  DialogDescription,
  DialogRoot,
  DialogTitle,
} from '@/components/ui/dialog'

// ── Language ────────────────────────────────────────────────────────────

import { LOCALE_LABELS,  getLocale, setLocale } from '@/lib/i18n'

// ── Types ───────────────────────────────────────────────────────────────

type SectionId =
  | 'claude'
  | 'agent'
  | 'voice'
  | 'display'
  | 'appearance'
  | 'chat'
  | 'notifications'
  | 'language'

const SECTIONS: Array<{ id: SectionId; label: string; icon: any }> = [
  { id: 'claude', label: 'Model & Provider', icon: CloudIcon },
  { id: 'agent', label: 'Agent', icon: Settings02Icon },
  { id: 'voice', label: 'Voice', icon: VolumeHighIcon },
  { id: 'display', label: 'Display', icon: PaintBoardIcon },
  { id: 'appearance', label: 'Theme', icon: PaintBoardIcon },
  { id: 'chat', label: 'Chat', icon: MessageMultiple01Icon },
  { id: 'notifications', label: 'Alerts', icon: Notification03Icon },
  { id: 'language', label: 'Language', icon: MessageMultiple01Icon },
]

const DARK_ENTERPRISE_THEMES = new Set<ThemeId>([
  'claude-nous',
  'claude-official',
  'claude-classic',
  'claude-slate',
])

function _isDarkEnterpriseTheme(theme: string | null): theme is ThemeId {
  if (!theme) return false
  return DARK_ENTERPRISE_THEMES.has(theme as ThemeId)
}
void _isDarkEnterpriseTheme

// ── Shared building blocks ──────────────────────────────────────────────

function SectionHeader({
  title,
  description,
}: {
  title: string
  description: string
}) {
  return (
    <div className="mb-2">
      <p className="mb-2 text-xs font-semibold uppercase tracking-wider text-primary-500">
        Settings
      </p>
      <h3 className="text-base font-semibold text-primary-900 dark:text-neutral-100">
        {title}
      </h3>
      <p className="text-xs text-primary-500 dark:text-neutral-400">
        {description}
      </p>
    </div>
  )
}

function Row({
  label,
  description,
  children,
}: {
  label: string
  description?: string
  children: React.ReactNode
}) {
  return (
    <div className="flex flex-wrap items-center justify-between gap-4 py-1.5">
      <div className="min-w-0 flex-1">
        <p className="text-sm font-medium text-primary-900 dark:text-neutral-100">
          {label}
        </p>
        {description && (
          <p className="text-xs text-primary-500 dark:text-neutral-400">
            {description}
          </p>
        )}
      </div>
      <div className="flex items-center gap-2">{children}</div>
    </div>
  )
}

const SETTINGS_CARD_CLASS =
  'rounded-xl border border-primary-200 bg-primary-50/80 px-4 py-3 shadow-sm'

// ── Section components ──────────────────────────────────────────────────

const PROVIDER_CARDS: Array<{
  id: string
  name: string
  logo: string
  models: Array<string>
  authType: 'oauth' | 'api_key' | 'none'
  envKey?: string
}> = [
  // Local providers first — zero setup
  {
    id: 'ollama',
    name: 'Ollama',
    logo: '/providers/ollama.png',
    models: ['llama3.1:70b', 'qwen3:32b', 'deepseek-r1:32b'],
    authType: 'none',
  },
  {
    id: 'atomic-chat',
    name: 'Atomic Chat',
    logo: '/providers/atomic-chat.png',
    models: ['llama-3.2-3b', 'qwen2.5-7b', 'gemma-3-4b'],
    authType: 'none',
  },
  // Cloud providers
  {
    id: 'anthropic',
    name: 'Anthropic',
    logo: '/providers/anthropic.png',
    models: ['claude-sonnet-4-6', 'claude-opus-4-6', 'claude-haiku-3-5'],
    authType: 'api_key',
    envKey: 'ANTHROPIC_API_KEY',
  },
  {
    id: 'nous',
    name: 'Nous Portal',
    logo: '/providers/nous.png',
    models: [
      'xiaomi/mimo-v2-pro',
      'xiaomi/mimo-v2-omni',
      'claude-3-llama-3.1-405b',
      'claude-3-llama-3.1-70b',
    ],
    authType: 'oauth',
  },
  {
    id: 'openai-codex',
    name: 'OpenAI Codex',
    logo: '/providers/openai.png',
    models: ['gpt-5.4', 'gpt-5.3-codex', 'gpt-4o'],
    authType: 'oauth',
  },
  {
    id: 'openrouter',
    name: 'OpenRouter',
    logo: '/providers/openrouter.png',
    models: ['auto', 'deepseek/deepseek-r1', 'google/gemini-2.5-pro'],
    authType: 'api_key',
    envKey: 'OPENROUTER_API_KEY',
  },
  {
    id: 'zai',
    name: 'Z.AI / GLM',
    logo: '/providers/zhipu.png',
    models: ['glm-4-plus', 'glm-4-air'],
    authType: 'api_key',
    envKey: 'GLM_API_KEY',
  },
  {
    id: 'kimi-coding',
    name: 'Kimi',
    logo: '/providers/kimi.png',
    models: ['kimi-latest', 'moonshot-v1-128k'],
    authType: 'api_key',
    envKey: 'KIMI_API_KEY',
  },
  {
    id: 'minimax',
    name: 'MiniMax',
    logo: '/providers/minimax.png',
    models: ['MiniMax-M3', 'MiniMax-M2.7', 'MiniMax-M2.7-Lightning'],
    authType: 'api_key',
    envKey: 'MINIMAX_API_KEY',
  },
  {
    id: 'xiaomi',
    name: 'Xiaomi MiMo',
    logo: '/providers/xiaomi.png',
    models: ['mimo-v2-pro', 'mimo-v2-omni', 'mimo-v2-flash'],
    authType: 'api_key',
    envKey: 'XIAOMI_API_KEY',
  },
  { id: 'custom', name: 'Custom', logo: '', models: [], authType: 'api_key', envKey: 'CUSTOM_API_KEY' },
]

export type ProviderClickAction = 'select' | 'oauth' | 'local' | 'custom' | 'ignore'

export function getProviderClickAction(input: {
  providerId?: string
  authType: 'oauth' | 'api_key' | 'none'
  hasKey: boolean
}): ProviderClickAction {
  if (input.providerId === 'custom') return 'custom'
  if (input.authType === 'oauth') return 'oauth'
  if (input.authType === 'none') return 'local'
  return input.hasKey ? 'select' : 'ignore'
}

const LOCAL_PROVIDER_SETUP: Partial<Record<
  string,
  { baseUrl: string; unavailableMessage: string }
>> = {
  ollama: {
    baseUrl: 'http://127.0.0.1:11434/v1',
    unavailableMessage:
      'No Ollama endpoint detected at http://127.0.0.1:11434/v1.',
  },
  'atomic-chat': {
    baseUrl: 'http://127.0.0.1:1337/v1',
    unavailableMessage:
      'No Atomic Chat endpoint detected at http://127.0.0.1:1337/v1.',
  },
}

export type OAuthStatus = 'idle' | 'starting' | 'pending' | 'success' | 'error'

const DEFAULT_OAUTH_EXPIRES_SECONDS = 600
const DEFAULT_OAUTH_POLL_INTERVAL_SECONDS = 3

export function getOAuthStartButtonLabel(status: OAuthStatus): string {
  return status === 'starting' || status === 'pending'
    ? 'Waiting...'
    : 'Start OAuth'
}

type OAuthDeviceCodeResponse = {
  device_code?: string
  user_code?: string
  verification_uri_complete?: string
  interval?: number
  expires_in?: number
  error?: string
}

type OAuthPollResponse = {
  status?: string
  message?: string
}

function HermesContent() {
  const configAvailable = useFeatureAvailable('config')
  const [activeProvider, setActiveProvider] = useState('')
  const [activeModel, setActiveModel] = useState('')
  const [defaultProvider, setDefaultProvider] = useState('')
  const [defaultModelId, setDefaultModelId] = useState('')
  const [availableModels, setAvailableModels] = useState<Array<string>>([])
  const [editingKey, setEditingKey] = useState<string | null>(null)
  const [keyInput, setKeyInput] = useState('')
  const [_saving, setSaving] = useState(false)
  const [msg, setMsg] = useState<string | null>(null)
  const [configuredKeys, setConfiguredKeys] = useState<Record<string, string>>(
    {},
  )
  const [memEnabled, setMemEnabled] = useState(true)
  const [userProfileEnabled, setUserProfileEnabled] = useState(true)
  const [customBaseUrl, setCustomBaseUrl] = useState('')
  const [customModel, setCustomModel] = useState('')
  const [oauthProviderId, setOauthProviderId] = useState<string | null>(null)
  const [oauthStatus, setOauthStatus] = useState<OAuthStatus>('idle')
  const [oauthMessage, setOauthMessage] = useState('')
  const [oauthUserCode, setOauthUserCode] = useState('')
  const [oauthVerificationUri, setOauthVerificationUri] = useState('')
  const oauthAbortRef = useRef<AbortController | null>(null)
  const [localProviderId, setLocalProviderId] = useState<string | null>(null)
  const [localDiscovery, setLocalDiscovery] = useState<{
    providers: Array<{
      id: string
      name: string
      online: boolean
      modelCount: number
      configured: boolean
      needsRestart: boolean
    }>
    models: Array<{ id: string; name: string; provider: string }>
  } | null>(null)

  const fetchModelsForProvider = useCallback(
    (providerId: string) => {
      // For local providers, prefer auto-discovered models first
      if (localDiscovery) {
        const discovered = localDiscovery.models
          .filter((m) => m.provider === providerId)
          .map((m) => m.id)
        if (discovered.length > 0) {
          setAvailableModels(discovered)
          return
        }
      }
      fetch(
        `/api/claude-proxy/api/available-models?provider=${encodeURIComponent(providerId)}`,
      )
        .then((r) => r.json())
        .then((d: { models?: Array<{ id: string }> }) => {
          setAvailableModels((d.models || []).map((m) => m.id))
        })
        .catch(() => {
          // Fall back to hardcoded
          const card = PROVIDER_CARDS.find((p) => p.id === providerId)
          setAvailableModels(card?.models || [])
        })
    },
    [localDiscovery],
  )

  useEffect(() => {
    fetch('/api/local-providers')
      .then((r) => r.json())
      .then((d: any) => {
        if (d.ok) setLocalDiscovery(d)
      })
      .catch(() => {})
  }, [])

  useEffect(() => {
    fetch('/api/hermes-config')
      .then((r) => r.json())
      .then((d: any) => {
        setActiveProvider(d.activeProvider || '')
        setActiveModel(d.activeModel || '')
        setDefaultProvider(d.activeProvider || '')
        setDefaultModelId(d.activeModel || '')
        if (d.activeProvider) fetchModelsForProvider(d.activeProvider)
        const mem = (d.config?.memory as Record<string, unknown>) || {}
        setMemEnabled(mem.memory_enabled !== false)
        setUserProfileEnabled(mem.user_profile_enabled !== false)
        // Build configured keys map
        const keys: Record<string, string> = {}
        for (const p of d.providers || []) {
          const envKey = p.envKeys?.[0]
          if (!p.configured || !envKey) continue
          keys[envKey] = p.maskedCredentials?.[envKey] || '••••'
        }
        setConfiguredKeys(keys)
        // Load custom provider config (may be stored as 'custom' or legacy 'manifest')
        const cfgProviders = (d.config?.providers as Record<string, any>) || {}
        const customCfg = cfgProviders['custom'] || cfgProviders['manifest'] || {}
        if (customCfg.base_url) setCustomBaseUrl(customCfg.base_url)
        if (d.activeProvider === 'custom' && d.activeModel) {
          setCustomModel(d.activeModel)
        }
      })
      .catch(() => {})
  }, [])

  const refreshConfig = async () => {
    const ref = await fetch('/api/hermes-config')
    const d = await ref.json()
    setDefaultProvider(d.activeProvider || '')
    setDefaultModelId(d.activeModel || '')
    if (
      (d.activeProvider === 'custom' || d.activeProvider === 'manifest') &&
      d.activeModel
    ) {
      setCustomModel(d.activeModel)
    }
    const keys: Record<string, string> = {}
    for (const p of d.providers || []) {
      const envKey = p.envKeys?.[0]
      if (!p.configured || !envKey) continue
      keys[envKey] = p.maskedCredentials?.[envKey] || '••••'
    }
    setConfiguredKeys(keys)
  }

  const save = async (
    updates:
      | { config?: Record<string, unknown>; env?: Record<string, string> }
      | { action: string; [key: string]: unknown },
  ) => {
    setSaving(true)
    setMsg(null)
    try {
      const res = await fetch('/api/hermes-config', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(updates),
      })
      const r = (await res.json()) as { message?: string }
      setMsg(r.message || 'Saved')
      await refreshConfig()
      setTimeout(() => setMsg(null), 3000)
    } catch {
      setMsg('Failed to save')
    }
    setSaving(false)
  }

  const setDefaultModel = (providerId: string, modelId: string) => {
    return save({ action: 'set-default-model', providerId, modelId })
  }

  const selectProvider = (providerId: string, model?: string) => {
    setOauthProviderId(null)
    setLocalProviderId(null)
    if (providerId !== activeProvider) setActiveModel('')
    setActiveProvider(providerId)
    if (model) setActiveModel(model)
    else fetchModelsForProvider(providerId)
  }

  const clearProviderPreview = () => {
    setActiveProvider('')
    setActiveModel('')
    setAvailableModels([])
  }

  const abortOAuth = () => {
    oauthAbortRef.current?.abort()
    oauthAbortRef.current = null
  }

  const resetOAuthState = (providerId: string) => {
    abortOAuth()
    setOauthProviderId(providerId)
    setLocalProviderId(null)
    clearProviderPreview()
    setOauthStatus('idle')
    setOauthMessage('')
    setOauthUserCode('')
    setOauthVerificationUri('')
    setMsg(null)
  }

  const showLocalProviderSetup = (providerId: string) => {
    abortOAuth()
    setOauthProviderId(null)
    setLocalProviderId(providerId)
    clearProviderPreview()
    setMsg(null)
  }

  const showCustomProviderSetup = () => {
    abortOAuth()
    setOauthProviderId(null)
    setLocalProviderId(null)
    setActiveProvider('custom')
    setAvailableModels([])
    setMsg(null)
  }

  useEffect(() => {
    return () => abortOAuth()
  }, [])

  const sleepUnlessAborted = (ms: number, signal: AbortSignal) =>
    new Promise<void>((resolve, reject) => {
      const timer = globalThis.setTimeout(() => {
        signal.removeEventListener('abort', onAbort)
        resolve()
      }, ms)
      const onAbort = () => {
        clearTimeout(timer)
        reject(new DOMException('Aborted', 'AbortError'))
      }
      if (signal.aborted) {
        onAbort()
        return
      }
      signal.addEventListener('abort', onAbort, { once: true })
    })

  const startOAuthFlow = async () => {
    const provider = PROVIDER_CARDS.find((p) => p.id === oauthProviderId)
    if (!provider) return

    abortOAuth()
    const controller = new AbortController()
    oauthAbortRef.current = controller
    const { signal } = controller

    setOauthStatus('starting')
    setOauthMessage(`Starting ${provider.name} OAuth...`)
    setOauthUserCode('')
    setOauthVerificationUri('')

    try {
      const codeRes = await fetch('/api/oauth/device-code', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ provider: provider.id }),
        signal,
      })
      const codeData = (await codeRes.json()) as OAuthDeviceCodeResponse
      if (!codeRes.ok || codeData.error || !codeData.device_code) {
        throw new Error(codeData.error || 'Could not start OAuth device flow')
      }

      const verificationUri = codeData.verification_uri_complete || ''
      setOauthStatus('pending')
      setOauthUserCode(codeData.user_code || '')
      setOauthVerificationUri(verificationUri)
      setOauthMessage(
        verificationUri
          ? `Authorize ${provider.name} in the browser, then return here.`
          : `Enter the user code to authorize ${provider.name}.`,
      )

      if (verificationUri) {
        window.open(verificationUri, '_blank', 'noopener,noreferrer')
      }

      const expiresInSeconds = codeData.expires_in || DEFAULT_OAUTH_EXPIRES_SECONDS
      const intervalSeconds = Math.max(
        1,
        codeData.interval || DEFAULT_OAUTH_POLL_INTERVAL_SECONDS,
      )
      const deadline = Date.now() + expiresInSeconds * 1000
      const intervalMs = intervalSeconds * 1000

      while (Date.now() < deadline) {
        await sleepUnlessAborted(intervalMs, signal)
        const pollRes = await fetch('/api/oauth/poll-token', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            provider: provider.id,
            deviceCode: codeData.device_code,
          }),
          signal,
        })
        const pollData = (await pollRes.json()) as OAuthPollResponse
        if (pollData.status === 'pending') continue
        if (pollData.status === 'success') {
          setOauthStatus('success')
          setOauthMessage(
            `${provider.name} OAuth is connected. TUI and WebUI will use the shared Hermes credentials.`,
          )
          await refreshConfig()
          return
        }
        throw new Error(pollData.message || 'OAuth authorization failed')
      }

      throw new Error('OAuth authorization timed out')
    } catch (error) {
      if ((error as { name?: string })?.name === 'AbortError') return
      setOauthStatus('error')
      setOauthMessage(
        error instanceof Error ? error.message : 'OAuth authorization failed',
      )
    } finally {
      if (oauthAbortRef.current === controller) {
        oauthAbortRef.current = null
      }
    }
  }

  if (!configAvailable) {
    return (
      <BackendUnavailableState
        feature="Hermes Agent Settings"
        description={getUnavailableReason('config')}
      />
    )
  }

  const cardStyle: React.CSSProperties = {
    backgroundColor: 'var(--theme-card)',
    border: '1px solid var(--theme-border)',
    color: 'var(--theme-text)',
  }
  const mutedStyle: React.CSSProperties = { color: 'var(--theme-muted)' }

  return (
    <div className="space-y-5">
      {msg && (
        <div
          className={cn(
            'rounded-lg px-3 py-2 text-sm font-medium',
            msg.includes('Failed')
              ? 'bg-red-500/15 text-red-400'
              : 'bg-green-500/15 text-green-400',
          )}
        >
          {msg}
        </div>
      )}

      {/* Provider Selection */}
      <div>
        <p
          className="mb-1 text-xs font-semibold uppercase tracking-wider"
          style={mutedStyle}
        >
          Provider
        </p>
        <p className="mb-3 text-[11px]" style={mutedStyle}>
          Select your AI provider. OAuth providers authenticate via browser.
        </p>
        <div className="grid grid-cols-2 gap-2 sm:grid-cols-3">
          {PROVIDER_CARDS.map((p) => {
            const isActive =
              (oauthProviderId || localProviderId || activeProvider) === p.id
            const localOnline =
              localDiscovery?.providers.find((lp) => lp.id === p.id)?.online ===
              true
            // verified = truly available right now. OAuth status isn't tracked
            // here, so OAuth providers stay neutral until an actual session
            // check is wired. Local providers require live discovery hit.
            const verified =
              (p.authType === 'none' && localOnline) ||
              (p.authType === 'api_key' &&
                !!p.envKey &&
                !!configuredKeys[p.envKey])
            const missingKey =
              p.authType === 'api_key' && !verified && p.id !== 'custom'
            // hasKey gates click — keep OAuth + local clickable (existing
            // behaviour) so users can still authenticate via the card.
            const hasKey =
              p.authType === 'none' ||
              p.authType === 'oauth' ||
              verified ||
              p.id === 'custom'
            return (
              <button
                key={p.id}
                type="button"
                onClick={() => {
                  const action = getProviderClickAction({
                    providerId: p.id,
                    authType: p.authType,
                    hasKey,
                  })
                  if (action === 'oauth') {
                    resetOAuthState(p.id)
                    return
                  }
                  if (action === 'local') {
                    showLocalProviderSetup(p.id)
                    return
                  }
                  if (action === 'custom') {
                    showCustomProviderSetup()
                    return
                  }
                  if (action === 'select') selectProvider(p.id)
                }}
                className={cn(
                  'flex flex-col items-start gap-1 rounded-xl px-3 py-2.5 text-left transition-all',
                  isActive
                    ? 'ring-2 ring-accent-500 shadow-md'
                    : 'hover:brightness-110',
                  missingKey && 'opacity-60',
                )}
                style={cardStyle}
              >
                <div className="flex w-full items-center justify-between">
                  <ProviderLogo provider={p.id} size={32} />
                  {/* Single-dot precedence: active > missing-key > verified > none */}
                  {isActive ? (
                    <span className="size-2 rounded-full bg-green-500" />
                  ) : missingKey ? (
                    <span className="size-2 rounded-full bg-red-500/60" />
                  ) : verified ? (
                    <span className="size-2 rounded-full bg-green-500/40" />
                  ) : null}
                </div>
                <span className="text-xs font-semibold mt-1">{p.name}</span>
                <span className="text-[9px]" style={mutedStyle}>
                  {(() => {
                    const disc = localDiscovery?.providers.find(
                      (lp) => lp.id === p.id,
                    )
                    if (disc?.online) return '🟢 Detected'
                    if (p.authType === 'oauth') return 'OAuth'
                    if (p.authType === 'none') return 'Local'
                    return hasKey ? 'Key set' : 'Key required'
                  })()}
                </span>
              </button>
            )
          })}
        </div>
      </div>

      {oauthProviderId ? (
        <div className="rounded-xl px-3 py-2.5" style={cardStyle}>
          {(() => {
            const provider = PROVIDER_CARDS.find((p) => p.id === oauthProviderId)
            if (!provider) return null

            return (
              <div className="space-y-3">
                <div className="flex flex-wrap items-center justify-between gap-3">
                  <div className="min-w-0">
                    <p className="text-sm font-semibold">{provider.name} OAuth</p>
                  </div>
                  <Button
                    size="sm"
                    disabled={oauthStatus === 'starting' || oauthStatus === 'pending'}
                    onClick={() => {
                      void startOAuthFlow()
                    }}
                  >
                    {getOAuthStartButtonLabel(oauthStatus)}
                  </Button>
                </div>

                <div className="rounded-lg border border-primary-200 bg-primary-50/80 px-3 py-2 text-xs text-primary-700 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-300">
                  {oauthMessage || 'Start the browser-based OAuth flow.'}
                  {oauthUserCode ? (
                    <div className="mt-2">
                      User code:{' '}
                      <code className="rounded bg-black/10 px-1 py-0.5 font-mono dark:bg-white/10">
                        {oauthUserCode}
                      </code>
                    </div>
                  ) : null}
                  {oauthVerificationUri ? (
                    <a
                      href={oauthVerificationUri}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="mt-2 inline-block font-medium underline underline-offset-2"
                    >
                      Open authorization page
                    </a>
                  ) : null}
                </div>
              </div>
            )
          })()}
        </div>
      ) : null}

      {localProviderId ? (
        <div className="rounded-xl px-3 py-2.5" style={cardStyle}>
          {(() => {
            const provider = PROVIDER_CARDS.find((p) => p.id === localProviderId)
            if (!provider) return null
            const disc = localDiscovery?.providers.find(
              (lp) => lp.id === provider.id,
            )
            const models =
              localDiscovery?.models.filter((m) => m.provider === provider.id) ||
              []
            const setup = LOCAL_PROVIDER_SETUP[provider.id] || {
              baseUrl: 'local OpenAI-compatible endpoint',
              unavailableMessage: 'No local endpoint detected.',
            }

            return (
              <div className="space-y-3">
                <div className="flex flex-wrap items-start gap-3">
                  <div className="min-w-0">
                    <p className="text-sm font-semibold">{provider.name}</p>
                  </div>
                </div>

                <div className="rounded-lg border border-primary-200 bg-primary-50/80 px-3 py-2 text-xs text-primary-700 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-300">
                  {disc?.online ? (
                    <>
                      Detected {disc.modelCount} model
                      {disc.modelCount === 1 ? '' : 's'} at{' '}
                      <code className="rounded bg-black/10 px-1 py-0.5 font-mono dark:bg-white/10">
                        {setup.baseUrl}
                      </code>
                      .
                    </>
                  ) : (
                    setup.unavailableMessage
                  )}
                  {disc?.needsRestart ? (
                    <div className="mt-2 text-yellow-700 dark:text-yellow-200">
                      Gateway restart may be needed after adding this provider to
                      config.
                    </div>
                  ) : null}
                </div>

                {models.length > 0 ? (
                  <div>
                    <p className="mb-2 text-xs font-semibold uppercase tracking-wider" style={mutedStyle}>
                      Detected Models
                    </p>
                    <div className="flex flex-wrap gap-2">
                      {models.map((model) => (
                        <button
                          key={model.id}
                          type="button"
                          aria-pressed={
                            activeProvider === provider.id &&
                            activeModel === model.id
                          }
                          onClick={() => {
                            setActiveProvider(provider.id)
                            setActiveModel(model.id)
                          }}
                          className={cn(
                            'rounded-lg px-3 py-1.5 text-xs font-medium transition-all hover:brightness-110',
                            activeProvider === provider.id &&
                              activeModel === model.id
                              ? 'ring-2 ring-accent-500'
                              : '',
                          )}
                          style={cardStyle}
                        >
                          {model.id}
                          {defaultProvider === provider.id &&
                          defaultModelId === model.id
                            ? ' · default'
                            : ''}
                        </button>
                      ))}
                    </div>
                    {activeProvider === provider.id &&
                    activeModel &&
                    (defaultProvider !== provider.id ||
                      activeModel !== defaultModelId) ? (
                      <div className="mt-2 flex items-center gap-2">
                        <Button
                          size="sm"
                          onClick={() => setDefaultModel(provider.id, activeModel)}
                        >
                          Set as default: {provider.id} · {activeModel}
                        </Button>
                      </div>
                    ) : null}
                  </div>
                ) : null}
              </div>
            )
          })()}
        </div>
      ) : null}

      {/* Model Selection for active provider */}
      {!oauthProviderId && !localProviderId && activeProvider && activeProvider !== 'custom' && (
        <div>
          <p
            className="mb-1 text-xs font-semibold uppercase tracking-wider"
            style={mutedStyle}
          >
            Model — pick one, then confirm below
          </p>
          <div className="flex flex-wrap gap-2">
            {(() => {
              if (availableModels.length > 0) return availableModels
              // Use auto-discovered models for local providers
              const discovered = localDiscovery?.models
                .filter((m) => m.provider === activeProvider)
                .map((m) => m.id)
              if (discovered && discovered.length > 0) return discovered
              return (
                PROVIDER_CARDS.find((p) => p.id === activeProvider)?.models ||
                []
              )
            })().map((model) => (
              <button
                key={model}
                type="button"
                aria-pressed={activeModel === model}
                onClick={() => setActiveModel(model)}
                className={cn(
                  'rounded-lg px-3 py-1.5 text-xs font-medium transition-all',
                  activeModel === model
                    ? 'ring-2 ring-accent-500'
                    : 'hover:brightness-110',
                  defaultProvider === activeProvider && defaultModelId === model
                    ? 'border border-accent-500/40'
                    : '',
                )}
                style={cardStyle}
              >
                {model}
                {defaultProvider === activeProvider && defaultModelId === model
                  ? ' · default'
                  : ''}
              </button>
            ))}
          </div>
          {activeModel &&
          (activeProvider !== defaultProvider || activeModel !== defaultModelId) ? (
            <div className="mt-2 flex items-center gap-2">
              <Button
                size="sm"
                onClick={() => setDefaultModel(activeProvider, activeModel)}
              >
                Set as default: {activeProvider} · {activeModel}
              </Button>
            </div>
          ) : null}
        </div>
      )}

      {/* Custom OpenAI-compatible endpoint fields — Base URL only; API key lives in API Keys section */}
      {activeProvider === 'custom' && (
        <div>
          <p className="mb-1 text-xs font-semibold uppercase tracking-wider" style={mutedStyle}>
            Custom Endpoint
          </p>
          <div className="space-y-1.5">
            {(() => {
              const isEditing = editingKey === 'custom_base_url'
              const hasValue = !!customBaseUrl
              return (
                <div className="flex items-center gap-3 rounded-xl px-3 py-2.5" style={cardStyle}>
                  <div className="flex-1 min-w-0">
                    <div className="text-sm font-medium">Base URL</div>
                    <div className="text-[11px] font-mono" style={mutedStyle}>
                      {isEditing ? (
                        <input
                          type="url"
                          value={customBaseUrl}
                          onChange={(e) => setCustomBaseUrl(e.target.value)}
                          placeholder="http://127.0.0.1:38238/v1"
                          className="w-full rounded border-0 bg-transparent py-0.5 text-[11px] outline-none"
                          style={{ color: 'var(--theme-text)' }}
                          autoFocus
                          onKeyDown={(e) => {
                            if (e.key === 'Enter') {
                              save({ config: { model: { provider: 'manifest' }, providers: { manifest: { type: 'openai', base_url: customBaseUrl, key_env: 'CUSTOM_API_KEY' } } } })
                                .then(() => setEditingKey(null))
                            }
                            if (e.key === 'Escape') setEditingKey(null)
                          }}
                        />
                      ) : hasValue ? customBaseUrl : 'Not configured'}
                    </div>
                  </div>
                  <div className="flex items-center gap-2">
                    <span className={cn('size-2 rounded-full', hasValue ? 'bg-green-500' : 'bg-neutral-500')} />
                    {isEditing ? (
                      <>
                        <button type="button" onClick={() => { save({ config: { model: { provider: 'manifest' }, providers: { manifest: { type: 'openai', base_url: customBaseUrl, key_env: 'CUSTOM_API_KEY' } } } }).then(() => setEditingKey(null)) }} className="text-xs font-medium text-green-400">Save</button>
                        <button type="button" onClick={() => setEditingKey(null)} className="text-xs" style={mutedStyle}>Cancel</button>
                      </>
                    ) : (
                      <button type="button" onClick={() => setEditingKey('custom_base_url')} className="text-xs font-medium" style={{ color: 'var(--theme-accent)' }}>
                        {hasValue ? 'Edit' : 'Add'}
                      </button>
                    )}
                  </div>
                </div>
              )
            })()}
            {(() => {
              const isEditing = editingKey === 'custom_model'
              const hasValue = !!customModel
              return (
                <div
                  className="flex items-center gap-3 rounded-xl px-3 py-2.5"
                  style={cardStyle}
                >
                  <div className="flex-1 min-w-0">
                    <div className="text-sm font-medium">Model</div>
                    <div
                      className="text-[11px] font-mono"
                      style={mutedStyle}
                    >
                      {isEditing ? (
                        <input
                          type="text"
                          value={customModel}
                          onChange={(e) => setCustomModel(e.target.value)}
                          placeholder="e.g. gpt-4o-mini, llama3:8b"
                          className="w-full rounded border-0 bg-transparent py-0.5 text-[11px] outline-none"
                          style={{ color: 'var(--theme-text)' }}
                          autoFocus
                          onKeyDown={(e) => {
                            if (e.key === 'Enter') setEditingKey(null)
                            if (e.key === 'Escape') setEditingKey(null)
                          }}
                        />
                      ) : hasValue ? (
                        customModel
                      ) : (
                        'Not configured'
                      )}
                    </div>
                  </div>
                  <div className="flex items-center gap-2">
                    <span
                      className={cn(
                        'size-2 rounded-full',
                        hasValue ? 'bg-green-500' : 'bg-neutral-500',
                      )}
                    />
                    {isEditing ? (
                      <button
                        type="button"
                        onClick={() => setEditingKey(null)}
                        className="text-xs font-medium text-green-400"
                      >
                        Done
                      </button>
                    ) : (
                      <button
                        type="button"
                        onClick={() => setEditingKey('custom_model')}
                        className="text-xs font-medium"
                        style={{ color: 'var(--theme-accent)' }}
                      >
                        {hasValue ? 'Edit' : 'Add'}
                      </button>
                    )}
                  </div>
                </div>
              )
            })()}
          </div>
          {customBaseUrl &&
          customModel &&
          (defaultProvider !== 'custom' || customModel !== defaultModelId) ? (
            <div className="mt-2 flex items-center gap-2">
              <Button
                size="sm"
                onClick={() => setDefaultModel('custom', customModel)}
              >
                Set as default: custom · {customModel}
              </Button>
            </div>
          ) : null}
        </div>
      )}

      {(() => {
        const disc = localDiscovery?.providers.find(
          (lp) => lp.id === activeProvider,
        )
        if (!disc || !disc.needsRestart) return null
        return (
          <div className="rounded-lg border border-yellow-500/30 bg-yellow-500/10 px-3 py-2 text-xs text-yellow-200">
            ⚠️ Gateway restart needed to use {disc.name}. Run{' '}
            <code className="rounded bg-black/30 px-1">
              hermes gateway restart
            </code>{' '}
            in your terminal.
          </div>
        )
      })()}

      {/* API Keys */}
      <div>
        <p
          className="mb-1 text-xs font-semibold uppercase tracking-wider"
          style={mutedStyle}
        >
          API Keys
        </p>
        <div className="space-y-1.5">
          {PROVIDER_CARDS.filter((p) => p.envKey).map((p) => {
            const key = p.envKey!
            const hasKey = !!configuredKeys[key]
            const isEditing = editingKey === key
            return (
              <div
                key={p.id}
                className="flex items-center gap-3 rounded-xl px-3 py-2.5"
                style={cardStyle}
              >
                <ProviderLogo
                  provider={p.id}
                  size={28}
                  className="rounded-md"
                />
                <div className="flex-1 min-w-0">
                  <div className="text-sm font-medium">{p.name}</div>
                  <div className="text-[11px] font-mono" style={mutedStyle}>
                    {isEditing ? (
                      <input
                        type="password"
                        value={keyInput}
                        onChange={(e) => setKeyInput(e.target.value)}
                        placeholder={`Paste ${key}`}
                        className="w-full rounded border-0 bg-transparent py-0.5 text-[11px] outline-none"
                        style={{ color: 'var(--theme-text)' }}
                        autoFocus
                        onKeyDown={(e) => {
                          if (e.key === 'Enter' && keyInput) {
                            save({ env: { [key]: keyInput } })
                            setEditingKey(null)
                            setKeyInput('')
                          }
                          if (e.key === 'Escape') {
                            setEditingKey(null)
                            setKeyInput('')
                          }
                        }}
                      />
                    ) : hasKey ? (
                      configuredKeys[key]
                    ) : (
                      'Not configured'
                    )}
                  </div>
                </div>
                <div className="flex items-center gap-2">
                  <span
                    className={cn(
                      'size-2 rounded-full',
                      hasKey ? 'bg-green-500' : 'bg-neutral-500',
                    )}
                  />
                  {isEditing ? (
                    <>
                      <button
                        type="button"
                        onClick={() => {
                          if (keyInput) {
                            save({ env: { [key]: keyInput } })
                          }
                          setEditingKey(null)
                          setKeyInput('')
                        }}
                        className="rounded-lg px-2 py-1 text-[11px] font-medium bg-accent-500 text-white"
                      >
                        Save
                      </button>
                      <button
                        type="button"
                        onClick={() => {
                          setEditingKey(null)
                          setKeyInput('')
                        }}
                        className="rounded-lg px-2 py-1 text-[11px] font-medium"
                        style={{ color: 'var(--theme-muted)' }}
                      >
                        Cancel
                      </button>
                    </>
                  ) : (
                    <button
                      type="button"
                      onClick={() => {
                        setEditingKey(key)
                        setKeyInput('')
                      }}
                      className="rounded-lg px-2.5 py-1 text-[11px] font-medium transition-colors hover:bg-accent-500/10"
                      style={{
                        color: 'var(--theme-accent, var(--theme-text))',
                      }}
                    >
                      {hasKey ? 'Update' : 'Add'}
                    </button>
                  )}
                </div>
              </div>
            )
          })}
        </div>
      </div>

      {/* Memory */}
      <div>
        <p
          className="mb-1 text-xs font-semibold uppercase tracking-wider"
          style={mutedStyle}
        >
          Memory
        </p>
        <div className="space-y-1.5">
          <div
            className="flex items-center justify-between rounded-xl px-3 py-2.5"
            style={cardStyle}
          >
            <div>
              <div className="text-sm font-medium">Memory</div>
              <div className="text-[11px]" style={mutedStyle}>
                Store & recall memories across sessions
              </div>
            </div>
            <Switch
              checked={memEnabled}
              onCheckedChange={(c) => {
                setMemEnabled(c)
                save({ config: { memory: { memory_enabled: c } } })
              }}
            />
          </div>
          <div
            className="flex items-center justify-between rounded-xl px-3 py-2.5"
            style={cardStyle}
          >
            <div>
              <div className="text-sm font-medium">User Profile</div>
              <div className="text-[11px]" style={mutedStyle}>
                Remember preferences & context
              </div>
            </div>
            <Switch
              checked={userProfileEnabled}
              onCheckedChange={(c) => {
                setUserProfileEnabled(c)
                save({ config: { memory: { user_profile_enabled: c } } })
              }}
            />
          </div>
        </div>
      </div>

      {/* Runtime Info */}
      <div className="rounded-xl px-3 py-2.5" style={cardStyle}>
        <div className="flex items-center gap-2 mb-2">
          <span className="size-2 rounded-full bg-green-500 animate-pulse" />
          <span
            className="text-xs font-semibold uppercase tracking-wider"
            style={mutedStyle}
          >
            Runtime
          </span>
        </div>
        <div className="grid grid-cols-2 gap-x-4 gap-y-1 text-[11px]">
          <span style={mutedStyle}>Model</span>
          <span className="font-mono font-medium">{activeModel || '—'}</span>
          <span style={mutedStyle}>Provider</span>
          <span className="font-mono font-medium">
            {PROVIDER_CARDS.find((p) => p.id === activeProvider)?.name ||
              activeProvider ||
              '—'}
          </span>
          <span style={mutedStyle}>Config</span>
          <span className="font-mono font-medium">~/.hermes/config.yaml</span>
        </div>
      </div>
    </div>
  )
}

function _ProfileContent() {
  const { settings: cs, updateSettings: updateCS } = useChatSettingsStore()
  const [profileError, setProfileError] = useState<string | null>(null)
  const [processing, setProcessing] = useState(false)
  const displayName = getChatProfileDisplayName(cs.displayName)
  const [nameError, setNameError] = useState<string | null>(null)

  function handleNameChange(value: string) {
    if (value.length > 50) {
      setNameError('Display name too long (max 50 characters)')
      return
    }
    setNameError(null)
    updateCS({ displayName: value })
  }

  async function handleAvatarUpload(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0]
    e.target.value = ''
    if (!file) return
    if (!file.type.startsWith('image/')) {
      setProfileError('Unsupported file type.')
      return
    }
    if (file.size > 10 * 1024 * 1024) {
      setProfileError('Image too large (max 10MB).')
      return
    }
    setProfileError(null)
    setProcessing(true)
    try {
      const url = URL.createObjectURL(file)
      const img = await new Promise<HTMLImageElement>((resolve, reject) => {
        const i = new Image()
        i.onload = () => resolve(i)
        i.onerror = () => reject(new Error('Failed'))
        i.src = url
      })
      const max = 128,
        scale = Math.min(1, max / Math.max(img.width, img.height))
      const w = Math.round(img.width * scale),
        h = Math.round(img.height * scale)
      const canvas = document.createElement('canvas')
      canvas.width = w
      canvas.height = h
      const ctx = canvas.getContext('2d')!
      ctx.imageSmoothingQuality = 'high'
      ctx.drawImage(img, 0, 0, w, h)
      URL.revokeObjectURL(url)
      updateCS({
        avatarDataUrl: canvas.toDataURL(
          file.type === 'image/png' ? 'image/png' : 'image/jpeg',
          0.82,
        ),
      })
    } catch {
      setProfileError('Failed to process image.')
    } finally {
      setProcessing(false)
    }
  }

  const errorId = 'profile-name-error'

  return (
    <div className="space-y-4">
      <SectionHeader
        title="Profile"
        description="Your display identity in chat."
      />
      <div className={SETTINGS_CARD_CLASS}>
        <div className="flex items-center gap-3">
          <UserAvatar size={44} src={cs.avatarDataUrl} alt={displayName} />
          <div>
            <p className="text-sm font-medium text-primary-900 dark:text-neutral-100">
              {displayName}
            </p>
            <p className="text-xs text-primary-500 dark:text-neutral-400">
              No email connected
            </p>
          </div>
        </div>
      </div>
      <div className={SETTINGS_CARD_CLASS}>
        <Row label="Display name" description="Shown in chat and sidebar">
          <div className="w-full max-w-xs">
            <Input
              value={cs.displayName}
              onChange={(e) => handleNameChange(e.target.value)}
              placeholder="User"
              className="h-8 w-full rounded-lg border-primary-200 text-sm"
              maxLength={50}
              aria-label="Display name"
              aria-invalid={!!nameError}
              aria-describedby={nameError ? errorId : undefined}
            />
            {nameError && (
              <p
                id={errorId}
                className="mt-1 text-xs text-red-600"
                role="alert"
              >
                {nameError}
              </p>
            )}
          </div>
        </Row>
        <Row label="Avatar">
          <div className="flex items-center gap-2">
            <label className="block">
              <input
                type="file"
                accept="image/*"
                onChange={handleAvatarUpload}
                disabled={processing}
                aria-label="Upload profile picture"
                className="block max-w-[13rem] cursor-pointer text-xs text-primary-700 dark:text-neutral-300 file:mr-2 file:cursor-pointer file:rounded-lg file:border file:border-primary-200 file:bg-primary-100 file:px-2.5 file:py-1.5 file:text-xs file:font-medium file:text-primary-900 file:transition-colors hover:file:bg-primary-200 disabled:cursor-not-allowed disabled:opacity-50"
              />
            </label>
            <Button
              variant="outline"
              size="sm"
              onClick={() => updateCS({ avatarDataUrl: null })}
              disabled={!cs.avatarDataUrl || processing}
              className="h-8 rounded-lg border-primary-200 px-3"
            >
              Remove
            </Button>
          </div>
          {profileError && (
            <p className="text-xs text-red-600" role="alert">
              {profileError}
            </p>
          )}
        </Row>
      </div>
    </div>
  )
}

function AppearanceContent() {
  const { settings, updateSettings } = useSettings()

  function handleThemeChange(value: string) {
    const theme = value as SettingsThemeMode
    applyTheme(theme)
    if (theme === 'light' || theme === 'dark') {
      setTheme(getThemeVariant(getTheme(), theme))
    }
    updateSettings({ theme })
  }

  function _badgeClass(color: AccentColor): string {
    if (color === 'orange') return 'bg-orange-500'
    if (color === 'purple') return 'bg-purple-500'
    if (color === 'blue') return 'bg-blue-500'
    return 'bg-green-500'
  }

  function _handleAccentColorChange(selectedAccent: AccentColor) {
    localStorage.setItem('claude-accent', selectedAccent)
    document.documentElement.setAttribute('data-accent', selectedAccent)
    applyAccentColor(selectedAccent)
    updateSettings({ accentColor: selectedAccent })
  }

  return (
    <div className="space-y-4">
      <SectionHeader
        title="Appearance"
        description="Theme and color accents."
      />
      <div className={SETTINGS_CARD_CLASS}>
        <p className="mb-2 text-xs font-semibold uppercase tracking-wider text-primary-500">
          Theme Mode
        </p>
        <div className="inline-flex rounded-lg border border-primary-200 p-1">
          {[
            { value: 'light', label: 'Light', icon: Sun01Icon },
            { value: 'dark', label: 'Dark', icon: Moon01Icon },
            { value: 'system', label: 'System', icon: ComputerIcon },
          ].map((option) => (
            <button
              key={option.value}
              type="button"
              onClick={() => handleThemeChange(option.value)}
              className={cn(
                'flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm transition-colors',
                settings.theme === option.value
                  ? 'bg-accent-500 text-white'
                  : 'text-primary-600 hover:bg-primary-100',
              )}
            >
              <HugeiconsIcon icon={option.icon} size={16} strokeWidth={1.5} />
              {option.label}
            </button>
          ))}
        </div>
      </div>
      {/* Accent color removed — themes control accent */}
      <div className={SETTINGS_CARD_CLASS}>
        <p className="mb-2 text-xs font-semibold uppercase tracking-wider text-primary-500">
          Enterprise Theme
        </p>
        <EnterpriseThemePicker />
      </div>
      <div className={SETTINGS_CARD_CLASS}>
        <Row
          label="System metrics footer"
          description="Show a persistent footer with CPU, RAM, disk, and Hermes Agent status."
        >
          <Switch
            checked={settings.showSystemMetricsFooter}
            onCheckedChange={(c) =>
              updateSettings({ showSystemMetricsFooter: c })
            }
            aria-label="Show system metrics footer"
          />
        </Row>

        {/* Mobile chat nav removed — not relevant for Hermes */}
      </div>
    </div>
  )
}

const ENTERPRISE_THEME_FAMILIES: Array<ThemeId> = [
  'claude-nous',
  'matrix',
  'claude-official',
  'claude-classic',
  'claude-slate',
]

const ENTERPRISE_THEMES = THEMES.map((theme) => ({
  ...theme,
  desc: theme.description,
  preview:
    theme.id === 'claude-nous'
      ? {
          bg: '#041C1C',
          panel: '#06282A',
          border: 'rgba(255,230,203,0.2)',
          accent: '#FFAC02',
          text: '#FFE6CB',
        }
      : theme.id === 'claude-nous-light'
        ? {
            bg: '#F8FAF8',
            panel: '#FBFDFB',
            border: 'rgba(30,74,92,0.18)',
            accent: '#2557B7',
            text: '#16315F',
          }
        : theme.id === 'matrix'
          ? {
              bg: '#020804',
              panel: '#07130A',
              border: 'rgba(0,255,65,0.28)',
              accent: '#00FF41',
              text: '#D8FFE3',
            }
          : theme.id === 'matrix-light'
            ? {
                bg: '#F4FFF6',
                panel: '#FFFFFF',
                border: 'rgba(0,126,34,0.2)',
                accent: '#008F2D',
                text: '#062A12',
              }
            : theme.id === 'claude-official'
              ? {
                  bg: '#0A0E1A',
                  panel: '#11182A',
                  border: '#24304A',
                  accent: '#6366F1',
                  text: '#E6EAF2',
                }
              : theme.id === 'claude-official-light'
                ? {
                    bg: '#F7F7F1',
                    panel: '#FAFBF6',
                    border: '#CDD5DA',
                    accent: '#2557B7',
                    text: '#16315F',
                  }
                : theme.id === 'claude-classic'
              ? {
                  bg: '#0d0f12',
                  panel: '#1a1f26',
                  border: '#2a313b',
                  accent: '#b98a44',
                  text: '#eceff4',
                }
              : theme.id === 'claude-classic-light'
                ? {
                    bg: '#F5F2ED',
                    panel: '#FCFAF7',
                    border: '#D8CCBC',
                    accent: '#b98a44',
                    text: '#1a1f26',
                  }
                : theme.id === 'claude-slate'
                  ? {
                      bg: '#0d1117',
                      panel: '#1c2128',
                      border: '#30363d',
                      accent: '#7eb8f6',
                      text: '#c9d1d9',
                    }
                  : {
                      bg: '#F6F8FA',
                      panel: '#FFFFFF',
                      border: '#D0D7DE',
                      accent: '#3b82f6',
                      text: '#24292f',
                    },
}))

function ThemeSwatch({
  colors,
}: {
  colors: (typeof ENTERPRISE_THEMES)[number]['preview']
}) {
  return (
    <div
      className="flex h-10 w-full overflow-hidden rounded-md border"
      style={{ borderColor: colors.border, backgroundColor: colors.bg }}
    >
      <div
        className="flex h-full w-4 flex-col gap-0.5 p-0.5"
        style={{ backgroundColor: colors.panel }}
      >
        {[1, 2, 3].map((i) => (
          <div
            key={i}
            className="h-1.5 w-full rounded-sm"
            style={{ backgroundColor: colors.border }}
          />
        ))}
      </div>
      <div className="flex flex-1 flex-col gap-0.5 p-1">
        <div
          className="h-1.5 w-3/4 rounded"
          style={{ backgroundColor: colors.text, opacity: 0.8 }}
        />
        <div
          className="h-1 w-1/2 rounded"
          style={{ backgroundColor: colors.text, opacity: 0.3 }}
        />
        <div
          className="mt-0.5 h-1.5 w-6 rounded-full"
          style={{ backgroundColor: colors.accent }}
        />
      </div>
    </div>
  )
}

function EnterpriseThemePicker() {
  const { updateSettings } = useSettings()
  const [current, setCurrent] = useState(() => {
    if (typeof window === 'undefined') return 'claude-nous'
    return getTheme()
  })
  const currentMode = isDarkTheme(current) ? 'dark' : 'light'

  useEffect(() => {
    setCurrent(getTheme())
  }, [])

  function applyEnterpriseTheme(id: ThemeId) {
    setTheme(id)
    updateSettings({ theme: isDarkTheme(id) ? 'dark' : 'light' })
    setCurrent(id)
  }

  function toggleEnterpriseThemeMode() {
    const nextMode = currentMode === 'dark' ? 'light' : 'dark'
    applyEnterpriseTheme(getThemeVariant(current, nextMode))
  }

  const visibleThemes = ENTERPRISE_THEME_FAMILIES.map((themeId) =>
    ENTERPRISE_THEMES.find(
      (theme) => theme.id === getThemeVariant(themeId, currentMode),
    ),
  ).filter(Boolean) as typeof ENTERPRISE_THEMES

  return (
    <div className="space-y-3">
      <div className="flex items-center justify-between rounded-lg border border-primary-200 px-3 py-2">
        <div>
          <p className="text-xs font-semibold text-primary-900 dark:text-neutral-100">
            {currentMode === 'dark' ? 'Dark mode' : 'Light mode'}
          </p>
          <p className="text-[11px] text-primary-500 dark:text-neutral-400">
            Toggle the current theme family between paired light and dark
            variants.
          </p>
        </div>
        <button
          type="button"
          onClick={toggleEnterpriseThemeMode}
          className="inline-flex items-center gap-2 rounded-lg border border-primary-200 bg-primary-50 px-3 py-1.5 text-xs font-medium text-primary-900 transition-colors hover:bg-primary-100"
          aria-label={
            currentMode === 'dark'
              ? 'Switch enterprise theme to light mode'
              : 'Switch enterprise theme to dark mode'
          }
        >
          <HugeiconsIcon
            icon={currentMode === 'dark' ? Sun01Icon : Moon01Icon}
            size={16}
            strokeWidth={1.5}
          />
          {currentMode === 'dark' ? 'Light' : 'Dark'}
        </button>
      </div>
      <div className="grid w-full grid-cols-2 gap-2">
        {visibleThemes.map((t) => {
          const isActive = current === t.id
          return (
            <button
              key={t.id}
              type="button"
              onClick={() => applyEnterpriseTheme(t.id)}
              className={cn(
                'flex flex-col gap-1.5 rounded-lg border p-2 text-left transition-colors',
                isActive
                  ? 'border-accent-500 bg-accent-50 text-accent-700'
                  : 'border-primary-200 bg-primary-50/80 hover:bg-primary-100',
              )}
            >
              <ThemeSwatch colors={t.preview} />
              <div className="flex items-center gap-1">
                <span className="text-xs">{t.icon}</span>
                <span className="text-xs font-semibold text-primary-900 dark:text-neutral-100">
                  {t.label}
                </span>
                {isActive && (
                  <span className="ml-auto text-[9px] font-bold text-accent-600 uppercase tracking-wide">
                    Active
                  </span>
                )}
              </div>
              <p className="text-[10px] text-primary-500 dark:text-neutral-400 leading-tight">
                {t.desc}
              </p>
            </button>
          )
        })}
      </div>
    </div>
  )
}

function _LoaderContent() {
  const { settings: cs, updateSettings: updateCS } = useChatSettingsStore()
  const styles: Array<{ value: LoaderStyle; label: string }> = [
    { value: 'dots', label: 'Dots' },
    { value: 'braille-claude', label: 'Hermes' },
    { value: 'braille-orbit', label: 'Orbit' },
    { value: 'braille-breathe', label: 'Breathe' },
    { value: 'braille-pulse', label: 'Pulse' },
    { value: 'braille-wave', label: 'Wave' },
    { value: 'lobster', label: 'Lobster' },
    { value: 'logo', label: 'Logo' },
  ]
  function getPreset(s: LoaderStyle): BrailleSpinnerPreset | null {
    const m: Record<string, BrailleSpinnerPreset> = {
      'braille-claude': 'claude',
      'braille-orbit': 'orbit',
      'braille-breathe': 'breathe',
      'braille-pulse': 'pulse',
      'braille-wave': 'wave',
    }
    return m[s] ?? null
  }
  function Preview({ style }: { style: LoaderStyle }) {
    if (style === 'dots') return <ThreeDotsSpinner />
    if (style === 'lobster')
      return <span className="inline-block text-sm animate-pulse">🦞</span>
    if (style === 'logo') return <LogoLoader />
    const p = getPreset(style)
    return p ? (
      <BrailleSpinner
        preset={p}
        size={16}
        speed={120}
        className="text-primary-500"
      />
    ) : (
      <ThreeDotsSpinner />
    )
  }
  return (
    <div>
      <p className="mb-2 text-xs font-semibold uppercase tracking-wider text-primary-500">
        Loading animation
      </p>
      <div className="grid grid-cols-4 gap-2">
        {styles.map((o) => (
          <button
            key={o.value}
            type="button"
            onClick={() => updateCS({ loaderStyle: o.value })}
            className={cn(
              'flex min-h-14 flex-col items-center justify-center gap-1.5 rounded-lg border px-1.5 py-1.5 transition-colors',
              cs.loaderStyle === o.value
                ? 'border-accent-500 bg-accent-50 text-accent-700'
                : 'border-primary-200 bg-primary-50/80 text-primary-700 hover:bg-primary-100',
            )}
            aria-pressed={cs.loaderStyle === o.value}
          >
            <span className="flex h-4 items-center justify-center">
              <Preview style={o.value} />
            </span>
            <span className="text-[10px] font-medium leading-3">{o.label}</span>
          </button>
        ))}
      </div>
    </div>
  )
}

function ChatContent() {
  const { settings: cs, updateSettings: updateCS } = useChatSettingsStore()
  return (
    <div className="space-y-4">
      <SectionHeader
        title="Chat"
        description="Message visibility and response loader style."
      />
      <div className={SETTINGS_CARD_CLASS}>
        <Row
          label="Show tool messages"
          description="Display tool call details in assistant responses."
        >
          <Switch
            checked={cs.showToolMessages}
            onCheckedChange={(c) => updateCS({ showToolMessages: c })}
            aria-label="Show tool messages"
          />
        </Row>
        <Row
          label="Show reasoning blocks"
          description="Display model reasoning blocks when available."
        >
          <Switch
            checked={cs.showReasoningBlocks}
            onCheckedChange={(c) => updateCS({ showReasoningBlocks: c })}
            aria-label="Show reasoning blocks"
          />
        </Row>
        <Row
          label="Sound on response complete"
          description="Play a short sound in the browser when the agent finishes replying."
        >
          <Switch
            checked={cs.soundOnChatComplete}
            onCheckedChange={(c) => updateCS({ soundOnChatComplete: c })}
            aria-label="Sound on response complete"
          />
        </Row>
        <Row
          label="Enter key behavior"
          description={
            cs.enterBehavior === 'newline'
              ? 'Enter inserts a newline. Use ⌘/Ctrl+Enter to send.'
              : 'Enter sends the message. Use Shift+Enter for a newline.'
          }
        >
          <Switch
            checked={cs.enterBehavior === 'newline'}
            onCheckedChange={(c) =>
              updateCS({ enterBehavior: c ? 'newline' : 'send' })
            }
            aria-label="Enter inserts newline instead of sending"
          />
        </Row>
        <Row
          label="Chat content width"
          description="Max-width of the message column on wide screens."
        >
          <select
            value={cs.chatWidth}
            onChange={(e) =>
              updateCS({
                chatWidth: e.target.value as 'comfortable' | 'wide' | 'full',
              })
            }
            className="h-8 rounded-md border border-primary-200 bg-primary-50 px-2 text-sm text-primary-900 outline-none transition-colors focus-visible:ring-2 focus-visible:ring-primary-400"
            aria-label="Chat content width"
          >
            <option value="comfortable">Comfortable (900px)</option>
            <option value="wide">Wide (1200px)</option>
            <option value="full">Full width</option>
          </select>
        </Row>
        <Row
          label="Expand sidebar on hover"
          description={
            cs.sidebarHoverExpand
              ? 'Collapsed sidebar expands temporarily on hover.'
              : 'Collapsed sidebar stays at 48px until you click the toggle.'
          }
        >
          <Switch
            checked={cs.sidebarHoverExpand}
            onCheckedChange={(c) => updateCS({ sidebarHoverExpand: c })}
            aria-label="Expand sidebar on hover"
          />
        </Row>
      </div>
      {/* Loading animation removed — not relevant for Hermes */}
    </div>
  )
}

function NotificationsContent() {
  const { settings, updateSettings } = useSettings()
  return (
    <div className="space-y-4">
      <SectionHeader
        title="Notifications"
        description="Simple alerts and threshold controls."
      />
      <div className={SETTINGS_CARD_CLASS}>
        <Row label="Enable alerts">
          <Switch
            checked={settings.notificationsEnabled}
            onCheckedChange={(c) => updateSettings({ notificationsEnabled: c })}
            aria-label="Enable alerts"
          />
        </Row>
        <Row label="Usage threshold">
          <div className="flex w-full max-w-[14rem] items-center gap-2">
            <input
              type="range"
              min={50}
              max={100}
              value={settings.usageThreshold}
              onChange={(e) =>
                updateSettings({ usageThreshold: Number(e.target.value) })
              }
              className="w-full accent-primary-900 dark:accent-primary-400 disabled:cursor-not-allowed disabled:opacity-50"
              disabled={!settings.notificationsEnabled}
              aria-label={`Usage threshold: ${settings.usageThreshold} percent`}
              aria-valuemin={50}
              aria-valuemax={100}
              aria-valuenow={settings.usageThreshold}
            />
            <span className="w-10 text-right text-sm tabular-nums text-primary-700 dark:text-neutral-300">
              {settings.usageThreshold}%
            </span>
          </div>
        </Row>
      </div>
    </div>
  )
}

function _AdvancedContent() {
  const { settings, updateSettings } = useSettings()
  const [connectionStatus, setConnectionStatus] = useState<
    'idle' | 'testing' | 'connected' | 'failed'
  >('idle')
  const [urlError, setUrlError] = useState<string | null>(null)

  function validateAndUpdateUrl(value: string) {
    if (value && value.length > 0) {
      try {
        new URL(value)
        setUrlError(null)
      } catch {
        setUrlError('Invalid URL format')
      }
    } else {
      setUrlError(null)
    }
    updateSettings({ claudeUrl: value })
  }

  async function testConnection() {
    if (urlError) return
    setConnectionStatus('testing')
    try {
      const r = await fetch('/api/ping')
      setConnectionStatus(r.ok ? 'connected' : 'failed')
    } catch {
      setConnectionStatus('failed')
    }
  }

  const urlErrorId = 'claude-url-error'

  return (
    <div className="space-y-4">
      <SectionHeader
        title="Advanced"
        description="Hermes Agent endpoint and connectivity."
      />
      <div className={SETTINGS_CARD_CLASS}>
        <Row
          label="Hermes Agent URL"
          description="Used for API requests from Studio"
        >
          <div className="w-full max-w-sm">
            <Input
              type="url"
              placeholder="https://api.claudeworkspace.app"
              value={settings.claudeUrl}
              onChange={(e) => validateAndUpdateUrl(e.target.value)}
              className="h-8 w-full rounded-lg border-primary-200 text-sm"
              aria-label="Hermes Agent URL"
              aria-invalid={!!urlError}
              aria-describedby={urlError ? urlErrorId : undefined}
            />
            {urlError && (
              <p
                id={urlErrorId}
                className="mt-1 text-xs text-red-600"
                role="alert"
              >
                {urlError}
              </p>
            )}
          </div>
        </Row>
        <Row label="Connection status">
          <span
            className={cn(
              'inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium',
              connectionStatus === 'connected' &&
                'border-green-500/35 bg-green-500/10 text-green-600',
              connectionStatus === 'failed' &&
                'border-red-500/35 bg-red-500/10 text-red-600',
              connectionStatus === 'testing' &&
                'border-accent-500/35 bg-accent-500/10 text-accent-600',
              connectionStatus === 'idle' &&
                'border-primary-300 bg-primary-100 text-primary-700',
            )}
          >
            {connectionStatus === 'idle'
              ? 'Not tested'
              : connectionStatus === 'testing'
                ? 'Testing...'
                : connectionStatus === 'connected'
                  ? 'Connected'
                  : 'Failed'}
          </span>
          <Button
            variant="outline"
            size="sm"
            onClick={() => void testConnection()}
            disabled={connectionStatus === 'testing' || !!urlError}
            className="h-8 rounded-lg border-primary-200 px-3"
          >
            <HugeiconsIcon
              icon={CheckmarkCircle02Icon}
              size={16}
              strokeWidth={1.5}
            />
            Test
          </Button>
        </Row>
      </div>
    </div>
  )
}

// ── Error Boundary ──────────────────────────────────────────────────────

class SettingsErrorBoundary extends Component<
  { children: React.ReactNode },
  { error: Error | null }
> {
  state = { error: null as Error | null }

  static getDerivedStateFromError(error: Error) {
    return { error }
  }

  render() {
    if (this.state.error) {
      return (
        <div className="flex h-full items-center justify-center p-8 text-center">
          <div>
            <p className="mb-2 text-sm font-medium text-red-500">
              Settings failed to load
            </p>
            <button
              onClick={() => this.setState({ error: null })}
              className="text-xs text-primary-600 underline hover:text-primary-900"
            >
              Try again
            </button>
          </div>
        </div>
      )
    }
    return this.props.children
  }
}

// ── Agent Behavior ──────────────────────────────────────────────────────

function AgentBehaviorContent() {
  const [config, setConfig] = useState<Record<string, unknown>>({})
  const [msg, setMsg] = useState<string | null>(null)

  useEffect(() => {
    fetch('/api/hermes-config')
      .then((r) => r.json())
      .then((d: any) => {
        setConfig((d.config?.agent as Record<string, unknown>) || {})
      })
      .catch(() => {})
  }, [])

  const save = async (key: string, value: unknown) => {
    setMsg(null)
    try {
      await fetch('/api/hermes-config', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ config: { agent: { [key]: value } } }),
      })
      setConfig((prev) => ({ ...prev, [key]: value }))
      setMsg('Saved')
      setTimeout(() => setMsg(null), 2000)
    } catch {
      setMsg('Failed')
    }
  }

  return (
    <div className="space-y-4">
      <SectionHeader
        title="Agent Behavior"
        description="Execution limits and tool access."
      />
      {msg && (
        <div
          className={cn(
            'rounded-lg px-3 py-1.5 text-xs font-medium',
            msg === 'Saved'
              ? 'bg-green-500/15 text-green-400'
              : 'bg-red-500/15 text-red-400',
          )}
        >
          {msg}
        </div>
      )}
      <div className={SETTINGS_CARD_CLASS}>
        <Row
          label="Max turns"
          description="Maximum agent turns per request (1-100)"
        >
          <input
            type="number"
            min={1}
            max={100}
            value={Number(config.max_turns) || 50}
            onChange={(e) => save('max_turns', Number(e.target.value))}
            className="h-8 w-20 rounded-lg border border-primary-200 bg-primary-50 px-2 text-sm text-center text-primary-900 outline-none dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
          />
        </Row>
        <Row label="Gateway timeout" description="Seconds before timeout">
          <input
            type="number"
            min={10}
            max={600}
            value={Number(config.gateway_timeout) || 120}
            onChange={(e) => save('gateway_timeout', Number(e.target.value))}
            className="h-8 w-20 rounded-lg border border-primary-200 bg-primary-50 px-2 text-sm text-center text-primary-900 outline-none dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
          />
        </Row>
        <Row label="Tool enforcement" description="When agent must use tools">
          <select
            value={String(config.tool_use_enforcement || 'auto')}
            onChange={(e) => save('tool_use_enforcement', e.target.value)}
            className="h-8 rounded-lg border border-primary-200 bg-primary-50 px-2 text-sm text-primary-900 outline-none dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
          >
            <option value="auto">Auto</option>
            <option value="required">Required</option>
            <option value="none">None</option>
          </select>
        </Row>
      </div>
    </div>
  )
}

// ── Voice (TTS + STT) ──────────────────────────────────────────────────

function VoiceContent() {
  const [tts, setTts] = useState<Record<string, unknown>>({})
  const [stt, setStt] = useState<Record<string, unknown>>({})
  const [msg, setMsg] = useState<string | null>(null)

  useEffect(() => {
    fetch('/api/hermes-config')
      .then((r) => r.json())
      .then((d: any) => {
        setTts((d.config?.tts as Record<string, unknown>) || {})
        setStt((d.config?.stt as Record<string, unknown>) || {})
      })
      .catch(() => {})
  }, [])

  const saveTts = async (key: string, value: unknown) => {
    setMsg(null)
    try {
      await fetch('/api/hermes-config', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ config: { tts: { [key]: value } } }),
      })
      setTts((prev) => ({ ...prev, [key]: value }))
      setMsg('Saved')
      setTimeout(() => setMsg(null), 2000)
    } catch {
      setMsg('Failed')
    }
  }

  const saveStt = async (key: string, value: unknown) => {
    setMsg(null)
    try {
      await fetch('/api/hermes-config', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ config: { stt: { [key]: value } } }),
      })
      setStt((prev) => ({ ...prev, [key]: value }))
      setMsg('Saved')
      setTimeout(() => setMsg(null), 2000)
    } catch {
      setMsg('Failed')
    }
  }

  const ttsProvider = String(tts.provider || 'edge')
  const sttProvider = String(stt.provider || 'local')
  const sttGroq =
    (stt.groq as Record<string, unknown> | undefined) || {}

  return (
    <div className="space-y-4">
      <SectionHeader
        title="Voice"
        description="Text-to-speech and speech-to-text."
      />
      {msg && (
        <div
          className={cn(
            'rounded-lg px-3 py-1.5 text-xs font-medium',
            msg === 'Saved'
              ? 'bg-green-500/15 text-green-400'
              : 'bg-red-500/15 text-red-400',
          )}
        >
          {msg}
        </div>
      )}
      <div className={SETTINGS_CARD_CLASS}>
        <p className="mb-2 text-xs font-semibold uppercase tracking-wider text-primary-500">
          Text-to-Speech
        </p>
        <Row label="TTS Provider">
          <select
            value={ttsProvider}
            onChange={(e) => saveTts('provider', e.target.value)}
            className="h-8 rounded-lg border border-primary-200 bg-primary-50 px-2 text-sm text-primary-900 outline-none dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
          >
            <option value="edge">Edge TTS</option>
            <option value="elevenlabs">ElevenLabs</option>
            <option value="openai">OpenAI TTS</option>
            <option value="neutts">NeuTTS</option>
          </select>
        </Row>
        {ttsProvider === 'openai' && (
          <Row label="Voice">
            <select
              value={String(
                (tts.openai as Record<string, unknown>)?.voice || 'nova',
              )}
              onChange={(e) =>
                saveTts('openai', {
                  ...((tts.openai as Record<string, unknown>) || {}),
                  voice: e.target.value,
                })
              }
              className="h-8 rounded-lg border border-primary-200 bg-primary-50 px-2 text-sm text-primary-900 outline-none dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
            >
              {['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'].map(
                (v) => (
                  <option key={v} value={v}>
                    {v}
                  </option>
                ),
              )}
            </select>
          </Row>
        )}
      </div>
      <div className={SETTINGS_CARD_CLASS}>
        <p className="mb-2 text-xs font-semibold uppercase tracking-wider text-primary-500">
          Speech-to-Text
        </p>
        <Row label="Enable STT">
          <Switch
            checked={stt.enabled !== false}
            onCheckedChange={(c) => saveStt('enabled', c)}
          />
        </Row>
        <Row label="STT Provider">
          <select
            value={sttProvider}
            onChange={(e) => saveStt('provider', e.target.value)}
            className="h-8 rounded-lg border border-primary-200 bg-primary-50 px-2 text-sm text-primary-900 outline-none dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
          >
            {STT_PROVIDER_OPTIONS.map((provider) => (
              <option key={provider.value} value={provider.value}>
                {provider.label}
              </option>
            ))}
          </select>
        </Row>
        {sttProvider === 'groq' && (
          <>
            <Row label="Groq model">
              <select
                value={String(sttGroq.model || GROQ_STT_MODELS[0])}
                onChange={(e) =>
                  saveStt('groq', {
                    ...sttGroq,
                    model: e.target.value,
                  })
                }
                className="h-8 rounded-lg border border-primary-200 bg-primary-50 px-2 text-sm text-primary-900 outline-none dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
              >
                {GROQ_STT_MODELS.map((model) => (
                  <option key={model} value={model}>
                    {model}
                  </option>
                ))}
              </select>
            </Row>
            <Row label="Language" description="Optional BCP-47 code, e.g. en or en-US.">
              <Input
                value={String(stt.language || '')}
                onChange={(e) => saveStt('language', e.target.value)}
                placeholder="auto"
                className="h-8 w-40"
              />
            </Row>
          </>
        )}
      </div>
    </div>
  )
}

// ── Display ─────────────────────────────────────────────────────────────

function DisplayContent() {
  const [config, setConfig] = useState<Record<string, unknown>>({})
  const [msg, setMsg] = useState<string | null>(null)

  useEffect(() => {
    fetch('/api/hermes-config')
      .then((r) => r.json())
      .then((d: any) => {
        setConfig((d.config?.display as Record<string, unknown>) || {})
      })
      .catch(() => {})
  }, [])

  const save = async (key: string, value: unknown) => {
    setMsg(null)
    try {
      await fetch('/api/hermes-config', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ config: { display: { [key]: value } } }),
      })
      setConfig((prev) => ({ ...prev, [key]: value }))
      setMsg('Saved')
      setTimeout(() => setMsg(null), 2000)
    } catch {
      setMsg('Failed')
    }
  }

  return (
    <div className="space-y-4">
      <SectionHeader
        title="Display"
        description="Agent response style and output preferences."
      />
      {msg && (
        <div
          className={cn(
            'rounded-lg px-3 py-1.5 text-xs font-medium',
            msg === 'Saved'
              ? 'bg-green-500/15 text-green-400'
              : 'bg-red-500/15 text-red-400',
          )}
        >
          {msg}
        </div>
      )}
      <div className={SETTINGS_CARD_CLASS}>
        <Row label="Personality" description="Agent response style">
          <select
            value={String(config.personality || 'default')}
            onChange={(e) => save('personality', e.target.value)}
            className="h-8 rounded-lg border border-primary-200 bg-primary-50 px-2 text-sm text-primary-900 outline-none dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
          >
            <option value="default">Default</option>
            <option value="concise">Concise</option>
            <option value="verbose">Verbose</option>
            <option value="creative">Creative</option>
          </select>
        </Row>
        <Row label="Streaming" description="Stream responses in real-time">
          <Switch
            checked={config.streaming !== false}
            onCheckedChange={(c) => save('streaming', c)}
          />
        </Row>
        <Row
          label="Show reasoning"
          description="Display model thinking process"
        >
          <Switch
            checked={config.show_reasoning !== false}
            onCheckedChange={(c) => save('show_reasoning', c)}
          />
        </Row>
        <Row label="Show cost" description="Display token cost per response">
          <Switch
            checked={config.show_cost === true}
            onCheckedChange={(c) => save('show_cost', c)}
          />
        </Row>
        <Row label="Compact mode" description="Reduce spacing in responses">
          <Switch
            checked={config.compact === true}
            onCheckedChange={(c) => save('compact', c)}
          />
        </Row>
      </div>
    </div>
  )
}

function LanguageContent() {
  return (
    <div className="space-y-4">
      <SectionHeader
        title="Language"
        description="Choose the display language for the workspace UI."
      />
      <Row
        label="Interface Language"
        description="Translates navigation, labels, and buttons."
      >
        <select
          value={getLocale()}
          onChange={(e) => {
            setLocale(e.target.value as LocaleId)
            window.location.reload()
          }}
          className="h-9 w-full rounded-lg border border-primary-200 dark:border-neutral-700 bg-primary-50 dark:bg-neutral-800 px-3 text-sm text-primary-900 dark:text-neutral-100 outline-none md:max-w-xs"
        >
          {(Object.entries(LOCALE_LABELS) as Array<[LocaleId, string]>).map(
            ([id, label]) => (
              <option key={id} value={id}>
                {label}
              </option>
            ),
          )}
        </select>
      </Row>
    </div>
  )
}

// ── Main Dialog ─────────────────────────────────────────────────────────

const CONTENT_MAP: Record<SectionId, () => React.JSX.Element> = {
  claude: HermesContent,
  agent: AgentBehaviorContent,
  voice: VoiceContent,
  display: DisplayContent,
  appearance: AppearanceContent,
  chat: ChatContent,
  notifications: NotificationsContent,
  language: LanguageContent,
}

type SettingsDialogProps = {
  open: boolean
  onOpenChange: (open: boolean) => void
  initialSection?: SectionId
}

export function SettingsDialog({
  open,
  onOpenChange,
  initialSection = 'claude',
}: SettingsDialogProps) {
  const [active, setActive] = useState<SectionId>(initialSection)
  const [mobileView, setMobileView] = useState<'nav' | 'content'>('nav')
  const ActiveContent = CONTENT_MAP[active]

  useEffect(() => {
    if (open) {
      setActive(initialSection)
      setMobileView('nav')
    }
  }, [initialSection, open])

  function handleSectionSelect(sectionId: SectionId) {
    setActive(sectionId)
    setMobileView('content')
  }

  return (
    <DialogRoot open={open} onOpenChange={onOpenChange}>
      <DialogContent className="inset-0 h-full w-full max-w-none translate-x-0 translate-y-0 overflow-hidden rounded-none border-0 p-0 shadow-xl md:inset-auto md:left-1/2 md:top-1/2 md:h-[min(88dvh,740px)] md:min-h-[520px] md:w-full md:max-w-3xl md:-translate-x-1/2 md:-translate-y-1/2 md:rounded-2xl md:border md:border-primary-200 bg-[var(--theme-bg)]">
        <div className="flex h-full min-h-0 flex-col">
          <div className="flex items-center justify-between border-b border-primary-200 bg-primary-50/80 px-4 py-4 md:rounded-t-2xl md:px-5">
            <div>
              <DialogTitle className="text-base font-semibold text-primary-900 dark:text-neutral-100">
                Settings
              </DialogTitle>
              <DialogDescription className="sr-only">
                Configure Hermes Workspace
              </DialogDescription>
            </div>
            <DialogClose
              render={
                <Button
                  size="icon-sm"
                  variant="ghost"
                  className="rounded-full text-primary-500 hover:bg-primary-100 dark:text-neutral-400 dark:hover:bg-neutral-800"
                  aria-label="Close"
                >
                  <HugeiconsIcon
                    icon={Cancel01Icon}
                    size={18}
                    strokeWidth={1.5}
                  />
                </Button>
              }
            />
          </div>

          <SettingsErrorBoundary>
            <div className="flex min-h-0 flex-1 flex-col md:flex-row">
              <aside
                className={cn(
                  'w-full bg-primary-50/60 p-2 md:w-44 md:shrink-0 md:border-r md:border-primary-200',
                  mobileView === 'content' && 'hidden md:block',
                )}
              >
                <nav className="space-y-1">
                  {SECTIONS.map((s) => (
                    <button
                      key={s.id}
                      type="button"
                      onClick={() => handleSectionSelect(s.id)}
                      className={cn(
                        'flex w-full items-center gap-2.5 rounded-lg px-3 py-2 text-left text-sm text-primary-600 transition-colors hover:bg-primary-100',
                        active === s.id &&
                          'bg-accent-50 font-medium text-accent-700',
                      )}
                    >
                      <HugeiconsIcon
                        icon={s.icon}
                        size={16}
                        strokeWidth={1.5}
                      />
                      {s.label}
                    </button>
                  ))}
                </nav>
              </aside>
              <div
                className={cn(
                  'min-w-0 flex-1 overflow-y-auto p-4 pb-[calc(env(safe-area-inset-bottom)+1rem)] md:p-5 md:pb-5',
                  mobileView === 'nav' && 'hidden md:block',
                )}
              >
                <div className="mb-3 md:hidden">
                  <Button
                    type="button"
                    variant="ghost"
                    size="sm"
                    onClick={() => setMobileView('nav')}
                    className="h-8 gap-1.5 rounded-lg px-2 text-primary-600 hover:bg-primary-100"
                  >
                    <HugeiconsIcon
                      icon={ArrowLeft01Icon}
                      size={16}
                      strokeWidth={1.5}
                    />
                    Back
                  </Button>
                </div>
                <ActiveContent />
              </div>
            </div>
          </SettingsErrorBoundary>

          <div className="sticky bottom-0 z-10 border-t border-primary-200 bg-primary-50/60 px-4 py-3 text-xs text-primary-500 dark:text-neutral-400 md:rounded-b-2xl md:px-5">
            Most changes save automatically; the default model commits only when you click Set as default.{' '}
            <a
              href="/settings"
              className="ml-2 font-medium underline underline-offset-2 hover:text-primary-700 dark:hover:text-neutral-200"
            >
              All settings →
            </a>
          </div>
        </div>
      </DialogContent>
    </DialogRoot>
  )
}
