<template>
  <div class="settings">
    <Transition name="toast">
      <div v-if="toast.visible" class="toast" :class="'toast-' + toast.type">{{ toast.msg }}</div>
    </Transition>
    <Transition name="confirm">
      <div v-if="confirmState.visible" class="confirm-mask" @click.self="answerConfirm(false)">
        <div class="confirm-box">
          <div class="confirm-msg">{{ confirmState.msg }}</div>
          <div class="confirm-actions">
            <button class="btn btn-ghost btn-sm" @click="answerConfirm(false)">{{ $t('common.cancel') }}</button>
            <button class="btn btn-danger btn-sm" @click="answerConfirm(true)">{{ $t('common.delete') }}</button>
          </div>
        </div>
      </div>
    </Transition>
    <!-- 页面头部 -->
    <header class="page-header">
      <h1>{{ $t('settings.title') }}</h1>
    </header>

    <div class="settings-grid">
      <!-- ═══ AI 模型配置 ═══ -->
      <section class="panel">
        <div class="panel-header">
          <h2>{{ $t('settings.panelAiProvider') }}</h2>
          <button class="btn btn-ghost btn-sm" @click="openProviderForm()">{{ $t('settings.addProvider') }}</button>
        </div>
        <div class="provider-list" v-if="aiProviders.length > 0">
          <div class="provider-card" :class="{ 'provider-card--default': p.is_default }" v-for="p in aiProviders" :key="p.id">
            <div class="provider-top">
              <div class="provider-info">
                <span class="provider-name">{{ p.name }}</span>
                <span v-if="p.is_default" class="default-badge">{{ $t('settings.badgeDefault') }}</span>
              </div>
              <div class="provider-actions">
                <button class="btn-link" @click="setDefaultProvider(p.id)" v-if="!p.is_default">{{ $t('settings.actionSetDefault') }}</button>
                <button class="btn-link" @click="openProviderForm(p)">{{ $t('common.edit') }}</button>
                <button class="btn-link btn-link-danger" @click="deleteProvider(p.id)">{{ $t('common.delete') }}</button>
              </div>
            </div>
            <div class="provider-detail">
              <div class="detail-row">
                <span class="detail-label">{{ $t('settings.detailBaseUrl') }}</span>
                <span class="detail-value">{{ p.base_url }}</span>
              </div>
              <div class="detail-row">
                <span class="detail-label">{{ $t('settings.detailModel') }}</span>
                <span class="detail-value">{{ p.default_model }}</span>
              </div>
              <div class="detail-row">
                <span class="detail-label">{{ $t('settings.detailApiKey') }}</span>
                <span class="detail-value mask">{{ maskKey(p.api_key) }}</span>
              </div>
            </div>
          </div>
        </div>
        <div class="empty-hint" v-else>{{ $t('settings.emptyProvider') }}</div>
      </section>

      <!-- ═══ AI 提供商表单 ═══ -->
      <section class="panel" v-if="providerForm.visible">
        <div class="panel-header">
          <h2>{{ providerForm.editId ? $t('settings.editProviderTitle') : $t('settings.addProviderTitle') }}</h2>
          <button class="btn btn-ghost btn-sm" @click="providerForm.visible = false">{{ $t('common.cancel') }}</button>
        </div>
        <div class="form-grid">
          <div class="form-field">
            <label class="form-label">{{ $t('settings.labelName') }}</label>
            <input v-model="providerForm.name" class="setting-input" :placeholder="$t('settings.phProviderName')" />
          </div>
          <div class="form-field">
            <label class="form-label">{{ $t('settings.labelProviderType') }}</label>
            <select v-model="providerForm.providerType" class="setting-select">
              <option value="openai_compat">{{ $t('settings.providerTypeOpenaiCompat') }}</option>
              <option value="anthropic">{{ $t('settings.providerTypeAnthropic') }}</option>
            </select>
          </div>
          <div class="form-field">
            <label class="form-label">{{ $t('settings.labelBaseUrl') }}</label>
            <input v-model="providerForm.baseUrl" class="setting-input" :placeholder="$t('settings.phBaseUrl')" />
          </div>
          <div class="form-field">
            <label class="form-label">{{ $t('settings.labelApiKey') }}</label>
            <input v-model="providerForm.apiKey" class="setting-input" type="password" :placeholder="$t('settings.phApiKey')" />
          </div>
          <div class="form-field">
            <label class="form-label">{{ $t('settings.labelDefaultModel') }}</label>
            <input v-model="providerForm.defaultModel" class="setting-input" :placeholder="$t('settings.phDefaultModel')" />
          </div>
          <div class="form-actions">
            <button class="btn btn-primary" @click="saveProvider" :disabled="providerForm.saving">
              {{ providerForm.saving ? $t('settings.saving') : $t('common.save') }}
            </button>
          </div>
        </div>
      </section>

      <!-- ═══ 连接管理 ═══ -->
      <section class="panel">
        <div class="panel-header">
          <h2>{{ $t('settings.panelConnection') }}</h2>
          <button class="btn btn-ghost btn-sm" @click="openConnForm()">{{ $t('settings.addConnection') }}</button>
        </div>
        <div class="connection-list" v-if="connections.length > 0">
          <div class="connection-card" v-for="conn in connections" :key="conn.id">
            <div class="conn-left">
              <span class="conn-icon">{{ typeIcon(conn.type) }}</span>
              <div class="conn-info">
                <div class="conn-name-row">
                  <span class="conn-name">{{ conn.name }}</span>
                  <span class="conn-type" :class="'type-' + conn.type">{{ typeLabel(conn.type) }}</span>
                </div>
                <span class="conn-host">{{ conn.host }}{{ conn.port ? ':' + conn.port : '' }}</span>
                <span class="conn-user" v-if="conn.user">{{ conn.user }}</span>
              </div>
            </div>
            <div class="conn-actions">
              <button class="btn-link" @click="openConnForm(conn)">{{ $t('common.edit') }}</button>
              <button class="btn-link btn-link-danger" @click="removeConn(conn.id)">{{ $t('common.delete') }}</button>
            </div>
          </div>
        </div>
        <div class="empty-hint" v-else>{{ $t('settings.emptyConnection') }}</div>
      </section>

      <!-- ═══ 连接表单 ═══ -->
      <section class="panel" v-if="connForm.visible">
        <div class="panel-header">
          <h2>{{ connForm.editId ? $t('settings.editConnectionTitle') : $t('settings.addConnectionTitle') }}</h2>
          <button class="btn btn-ghost btn-sm" @click="connForm.visible = false">{{ $t('common.cancel') }}</button>
        </div>
        <div class="form-grid">
          <div class="form-field">
            <label class="form-label">{{ $t('settings.labelName') }}</label>
            <input v-model="connForm.name" class="setting-input" :placeholder="$t('settings.phConnName')" />
          </div>
          <div class="form-field">
            <label class="form-label">{{ $t('settings.labelType') }}</label>
            <select v-model="connForm.type" class="setting-select">
              <option value="mysql">MySQL</option>
              <option value="ssh">SSH</option>
              <option value="redis">Redis</option>
              <option value="mongo">MongoDB</option>
            </select>
          </div>
          <div class="form-field">
            <label class="form-label">{{ $t('settings.labelHost') }}</label>
            <input v-model="connForm.host" class="setting-input" :placeholder="$t('settings.phHost')" />
          </div>
          <div class="form-field">
            <label class="form-label">{{ $t('settings.labelPort') }}</label>
            <input v-model.number="connForm.port" class="setting-input" type="number" :placeholder="$t('settings.phPort')" />
          </div>
          <div class="form-field">
            <label class="form-label">{{ $t('settings.labelUser') }}</label>
            <input v-model="connForm.user" class="setting-input" :placeholder="$t('settings.phUser')" />
          </div>
          <div class="form-actions">
            <button class="btn btn-primary" @click="saveConn">{{ $t('common.save') }}</button>
          </div>
        </div>
      </section>

      <!-- ═══ 通用设置 ═══ -->
      <section class="panel">
        <div class="panel-header">
          <h2>{{ $t('settings.panelGeneral') }}</h2>
        </div>
        <div class="general-settings">
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelTheme') }}</span>
              <span class="setting-desc">{{ $t('settings.descTheme') }}</span>
            </div>
            <div class="setting-control">
              <select v-model="settings.theme" class="setting-select">
                <option value="dark">{{ $t('settings.themeDark') }}</option>
                <option value="light">{{ $t('settings.themeLight') }}</option>
                <option value="system">{{ $t('settings.themeSystem') }}</option>
              </select>
            </div>
          </div>
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelLanguage') }}</span>
              <span class="setting-desc">{{ $t('settings.descLanguage') }}</span>
            </div>
            <div class="setting-control">
              <select v-model="settings.language" class="setting-select">
                <option value="zh-CN">{{ $t('settings.aiLanguageZh') }}</option>
                <option value="en">{{ $t('settings.aiLanguageEn') }}</option>
              </select>
            </div>
          </div>
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelAiLanguage') }}</span>
              <span class="setting-desc">{{ $t('settings.descAiLanguage') }}</span>
            </div>
            <div class="setting-control">
              <select v-model="settings.aiLanguage" class="setting-select">
                <option value="auto">{{ $t('settings.aiLanguageAuto') }}</option>
                <option value="zh-CN">{{ $t('settings.aiLanguageZh') }}</option>
                <option value="en">{{ $t('settings.aiLanguageEn') }}</option>
              </select>
            </div>
          </div>
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelAutoExecute') }}</span>
              <span class="setting-desc">{{ $t('settings.descAutoExecute') }}</span>
            </div>
            <div class="setting-control">
              <label class="toggle">
                <input type="checkbox" v-model="settings.autoExecute" />
                <span class="toggle-slider"></span>
              </label>
            </div>
          </div>
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelLogLevel') }}</span>
              <span class="setting-desc">{{ $t('settings.descLogLevel') }}</span>
            </div>
            <div class="setting-control">
              <select v-model="settings.logLevel" class="setting-select">
                <option value="error">Error</option>
                <option value="warn">Warning</option>
                <option value="info">Info</option>
                <option value="debug">Debug</option>
              </select>
            </div>
          </div>
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelShowTokenUsage') }}</span>
              <span class="setting-desc">{{ $t('settings.descShowTokenUsage') }}</span>
            </div>
            <div class="setting-control">
              <label class="toggle">
                <input type="checkbox" v-model="settings.showTokenUsage" />
                <span class="toggle-slider"></span>
              </label>
            </div>
          </div>
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelGlobalConcurrency') }}</span>
              <span class="setting-desc">{{ $t('settings.descGlobalConcurrency') }}</span>
            </div>
            <div class="setting-control">
              <input type="number" class="setting-select" min="1" style="width:80px"
                     v-model.number="settings.llmGlobalConcurrency"
                     @change="syncConcurrencyConfig" />
            </div>
          </div>
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelPerConvConcurrency') }}</span>
              <span class="setting-desc">{{ $t('settings.descPerConvConcurrency') }}</span>
            </div>
            <div class="setting-control">
              <input type="number" class="setting-select" min="1" style="width:80px"
                     v-model.number="settings.llmPerConvConcurrency"
                     @change="syncConcurrencyConfig" />
            </div>
          </div>
        </div>
      </section>

      <section class="panel">
        <div class="panel-header">
          <h2>{{ $t('settings.panelKnowledge') }}</h2>
        </div>
        <div class="general-settings">
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelAutoExtract') }}</span>
              <span class="setting-desc">{{ $t('settings.descAutoExtract') }}</span>
            </div>
            <div class="setting-control">
              <label class="toggle">
                <input type="checkbox" v-model="knowledgeConfig.auto_extract" />
                <span class="toggle-slider"></span>
              </label>
            </div>
          </div>
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelTriggerMode') }}</span>
              <span class="setting-desc">{{ $t('settings.descTriggerMode') }}</span>
            </div>
            <div class="setting-control">
              <select v-model="knowledgeConfig.trigger_mode" class="setting-select">
                <option value="on_complete">{{ $t('settings.triggerOnComplete') }}</option>
                <option value="on_idle">{{ $t('settings.triggerOnIdle') }}</option>
                <option value="manual_only">{{ $t('settings.triggerManualOnly') }}</option>
              </select>
            </div>
          </div>
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelMinMessages') }}</span>
              <span class="setting-desc">{{ $t('settings.descMinMessages') }}</span>
            </div>
            <div class="setting-control">
              <input type="number" min="2" max="50" v-model.number="knowledgeConfig.min_messages" class="setting-select" style="width:80px" />
            </div>
          </div>
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelIdleTimeout') }}</span>
              <span class="setting-desc">{{ $t('settings.descIdleTimeout') }}</span>
            </div>
            <div class="setting-control">
              <input type="number" min="5" max="600" :value="Math.round(knowledgeConfig.idle_timeout_ms / 1000)" @input="knowledgeConfig.idle_timeout_ms = ($event.target as HTMLInputElement).valueAsNumber * 1000 || 30000" class="setting-select" style="width:80px" />
            </div>
          </div>
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelAutoInject') }}</span>
              <span class="setting-desc">{{ $t('settings.descAutoInject') }}</span>
            </div>
            <div class="setting-control">
              <label class="toggle">
                <input type="checkbox" v-model="knowledgeConfig.auto_inject" />
                <span class="toggle-slider"></span>
              </label>
            </div>
          </div>
          <div class="setting-row">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelVectorEnabled') }}</span>
              <span class="setting-desc">{{ $t('settings.descVectorEnabled') }}</span>
            </div>
            <div class="setting-control">
              <label class="toggle">
                <input type="checkbox" v-model="knowledgeConfig.vector_enabled" />
                <span class="toggle-slider"></span>
              </label>
            </div>
          </div>
          <div class="setting-row" v-if="knowledgeConfig.vector_enabled">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelEmbeddingProvider') }}</span>
              <span class="setting-desc">{{ $t('settings.descEmbeddingProvider') }}</span>
            </div>
            <div class="setting-control">
              <select v-model="knowledgeConfig.embedding_provider_id" class="setting-select">
                <option :value="null">{{ $t('settings.embeddingProviderNone') }}</option>
                <option v-for="p in embeddingProviders" :key="p.id" :value="p.id">{{ p.name }}</option>
              </select>
            </div>
          </div>
          <div class="setting-row" v-if="knowledgeConfig.vector_enabled">
            <div class="setting-info">
              <span class="setting-label">{{ $t('settings.labelEmbeddingModel') }}</span>
              <span class="setting-desc">{{ $t('settings.descEmbeddingModel') }}</span>
            </div>
            <div class="setting-control">
              <input type="text" :value="knowledgeConfig.embedding_model ?? ''" @input="knowledgeConfig.embedding_model = ($event.target as HTMLInputElement).value || null" class="setting-select" :placeholder="$t('settings.phEmbeddingModel')" style="width:220px" />
            </div>
          </div>
        </div>
      </section>
    </div>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, computed, watch, onMounted, onUnmounted } from 'vue'
import { useI18n } from 'vue-i18n'
import { aiApi, knowledgeApi } from '../api'
import { useAppSettingsStore } from '../stores/appSettings'
import type { AiProviderConfig } from '../api/types'
import i18n from '../i18n'

const { t } = useI18n()
const appSettings = useAppSettingsStore()

// ============================================================
// AI 提供商 — 真实后端 CRUD
// ============================================================

const aiProviders = ref<AiProviderConfig[]>([])

// 顶部轻量提示（错误/警告/完成），3s 自动消失；零依赖，替代未接入的 Arco Message
const toast = reactive({ visible: false, msg: '', type: 'info' as 'error' | 'warning' | 'info' })
let _toastTimer: ReturnType<typeof setTimeout> | null = null
/** 安全提取错误消息——Tauri IPC 错误是字符串非 Error 对象 */
function errMsg(e: unknown): string { return e instanceof Error ? e.message : String(e) }

function showToast(msg: string, type: 'error' | 'warning' | 'info' = 'info') {
  toast.msg = msg
  toast.type = type
  toast.visible = true
  if (_toastTimer) clearTimeout(_toastTimer)
  _toastTimer = setTimeout(() => { toast.visible = false }, 3000)
}

// 自建确认弹层（替代 window.confirm —— 后者带 webview 来源域名/端口，无法去除）
const confirmState = reactive({
  visible: false,
  msg: '',
  resolve: null as null | ((v: boolean) => void),
})
function confirmDialog(msg: string): Promise<boolean> {
  return new Promise(resolve => {
    confirmState.msg = msg
    confirmState.visible = true
    confirmState.resolve = resolve
  })
}
function answerConfirm(ok: boolean) {
  confirmState.visible = false
  confirmState.resolve?.(ok)
  confirmState.resolve = null
}

const providerForm = reactive({
  visible: false,
  editId: '' as string,
  name: '',
  providerType: 'openai_compat',
  baseUrl: '',
  apiKey: '',
  defaultModel: '',
  saving: false,
})

async function loadProviders() {
  try {
    aiProviders.value = await aiApi.listProviders()
  } catch (e) {
    console.error(t('settings.toastLoadProviderFail'), e)
    showToast(t('settings.toastLoadProviderFail'), 'error')
  }
}

function openProviderForm(p?: AiProviderConfig) {
  if (p) {
    providerForm.editId = p.id
    providerForm.name = p.name
    providerForm.baseUrl = p.base_url
    providerForm.apiKey = p.api_key
    providerForm.defaultModel = p.default_model
    providerForm.providerType = p.provider_type || 'openai_compat'
  } else {
    providerForm.editId = ''
    providerForm.name = ''
    providerForm.providerType = 'openai_compat'
    providerForm.baseUrl = ''
    providerForm.apiKey = ''
    providerForm.defaultModel = ''
  }
  providerForm.visible = true
}

async function saveProvider() {
  if (!providerForm.name || !providerForm.baseUrl || !providerForm.apiKey || !providerForm.defaultModel) {
    showToast(t('settings.toastSaveIncomplete'), 'warning')
    return
  }
  providerForm.saving = true
  try {
    await aiApi.saveProvider({
      id: providerForm.editId || undefined,
      name: providerForm.name,
      providerType: providerForm.providerType,
      baseUrl: providerForm.baseUrl,
      apiKey: providerForm.apiKey,
      defaultModel: providerForm.defaultModel,
    })
    providerForm.visible = false
    await loadProviders()
    showToast(t('settings.toastSaved'), 'info')
  } catch (e) {
    console.error(t('settings.toastSaveFail', { msg: errMsg(e) }), e)
    showToast(t('settings.toastSaveFail', { msg: errMsg(e) }), 'error')
  } finally {
    providerForm.saving = false
  }
}

async function deleteProvider(id: string) {
  const p = aiProviders.value.find(x => x.id === id)
  if (!await confirmDialog(t('settings.confirmDeleteProvider', { name: p?.name || id }))) return
  try {
    await aiApi.deleteProvider(id)
    await loadProviders()
    showToast(t('settings.toastDeleted'), 'info')
  } catch (e) {
    console.error(t('settings.toastDeleteFail', { msg: errMsg(e) }), e)
    showToast(t('settings.toastDeleteFail', { msg: errMsg(e) }), 'error')
  }
}

async function setDefaultProvider(id: string) {
  try {
    await aiApi.setProvider(id)
    await loadProviders()
    showToast(t('settings.toastSetDefaultOk'), 'info')
  } catch (e) {
    console.error(t('settings.toastSetDefaultFail', { msg: errMsg(e) }), e)
    showToast(t('settings.toastSetDefaultFail', { msg: errMsg(e) }), 'error')
  }
}

function maskKey(key: string): string {
  if (!key || key.length < 8) return '••••••••'
  return key.slice(0, 4) + '••••••••' + key.slice(-4)
}

// ============================================================
// 连接管理 — localStorage CRUD
// ============================================================

interface ConnRecord {
  id: string
  name: string
  type: string
  host: string
  port: number
  user: string
}

const connections = ref<ConnRecord[]>([])

const connForm = reactive({
  visible: false,
  editId: '' as string,
  name: '',
  type: 'mysql',
  host: '',
  port: 3306,
  user: '',
})

const CONN_STORAGE_KEY = 'df-connections'

function loadConnections() {
  const stored = appSettings.get<ConnRecord[] | null>(CONN_STORAGE_KEY, null)
  if (stored) connections.value = stored
}

function persistConnections() {
  void appSettings.set(CONN_STORAGE_KEY, connections.value)
}

function typeIcon(type: string) {
  const map: Record<string, string> = { mysql: '🗄️', ssh: '🔐', redis: '⚡', mongo: '🍃' }
  return map[type] || '🔗'
}

function typeLabel(type: string) {
  const map: Record<string, string> = { mysql: 'MySQL', ssh: 'SSH', redis: 'Redis', mongo: 'MongoDB' }
  return map[type] || type
}

function openConnForm(conn?: ConnRecord) {
  if (conn) {
    connForm.editId = conn.id
    connForm.name = conn.name
    connForm.type = conn.type
    connForm.host = conn.host
    connForm.port = conn.port
    connForm.user = conn.user
  } else {
    connForm.editId = ''
    connForm.name = ''
    connForm.type = 'mysql'
    connForm.host = ''
    connForm.port = 3306
    connForm.user = ''
  }
  connForm.visible = true
}

function saveConn() {
  if (!connForm.name || !connForm.host) {
    showToast(t('settings.toastConnIncomplete'), 'warning')
    return
  }
  const record: ConnRecord = {
    id: connForm.editId || Date.now().toString(36),
    name: connForm.name,
    type: connForm.type,
    host: connForm.host,
    port: connForm.port,
    user: connForm.user,
  }
  if (connForm.editId) {
    const idx = connections.value.findIndex(c => c.id === connForm.editId)
    if (idx >= 0) connections.value[idx] = record
  } else {
    connections.value.push(record)
  }
  persistConnections()
  connForm.visible = false
}

async function removeConn(id: string) {
  const c = connections.value.find(x => x.id === id)
  if (!await confirmDialog(t('settings.confirmDeleteConn', { name: c?.name || id }))) return
  connections.value = connections.value.filter(c => c.id !== id)
  persistConnections()
  showToast(t('settings.toastDeleted'), 'info')
}

// ============================================================
// 通用设置
// ============================================================

const settings = reactive({
  theme: appSettings.get<string>('df-theme', 'dark'),
  language: appSettings.get<string>('df-language', 'zh-CN'),
  aiLanguage: appSettings.get<string>('df-ai-language', 'auto'),
  autoExecute: false,
  logLevel: 'info',
  showTokenUsage: appSettings.get<boolean>('df-show-token-usage', false),
  llmGlobalConcurrency: appSettings.get<number>('df-llm-global-concurrency', 3),
  llmPerConvConcurrency: appSettings.get<number>('df-llm-per-conv-concurrency', 2),
})

function applyTheme(theme: string) {
  if (theme === 'system') {
    const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
    document.documentElement.removeAttribute('data-theme')
    if (!prefersDark) document.documentElement.setAttribute('data-theme', 'light')
  } else if (theme === 'light') {
    document.documentElement.setAttribute('data-theme', 'light')
  } else {
    document.documentElement.removeAttribute('data-theme')
  }
}

watch(() => settings.theme, (val) => {
  applyTheme(val)
  void appSettings.set('df-theme', val)
})

watch(() => settings.aiLanguage, (val) => {
  void appSettings.set('df-ai-language', val)
})

watch(() => settings.showTokenUsage, (val) => {
  void appSettings.set('df-show-token-usage', val)
})

watch(() => settings.llmGlobalConcurrency, (v) => {
  void appSettings.set('df-llm-global-concurrency', v)
})
watch(() => settings.llmPerConvConcurrency, (v) => {
  void appSettings.set('df-llm-per-conv-concurrency', v)
})

// 同步 LLM 并发上限到后端(debounce 300ms,防快速连续调整时频繁 IPC)
// 持久化已由上方 watch 写 appSettings(SQLite) 完成;此处只负责同步内存限流器
let _concurrencyTimer: ReturnType<typeof setTimeout> | null = null
function syncConcurrencyConfig() {
  // clamp 到合理区间,防越界输入(缓存被篡改 / 手动输超限)致限流失效;
  // 修正后值同步回 v-model(input 显示) + watch 持久化
  // 下限 1,无上限;约束单对话并发不超过全局并发
  settings.llmGlobalConcurrency = Math.max(1, settings.llmGlobalConcurrency || 3)
  settings.llmPerConvConcurrency = Math.max(1, settings.llmPerConvConcurrency || 2)
  if (settings.llmPerConvConcurrency > settings.llmGlobalConcurrency) {
    settings.llmPerConvConcurrency = settings.llmGlobalConcurrency
  }
  if (_concurrencyTimer) clearTimeout(_concurrencyTimer)
  _concurrencyTimer = setTimeout(async () => {
    try {
      await aiApi.setConcurrencyConfig(settings.llmGlobalConcurrency, settings.llmPerConvConcurrency)
    } catch (e) {
      console.error('同步 LLM 并发配置失败:', e)
    }
  }, 300)
}

watch(() => settings.language, (val) => {
  void appSettings.set('df-language', val)
  // 同步 i18n 实例，让界面立即跟随语言切换
  i18n.global.locale.value = val as 'zh-CN' | 'en'
})

// ============================================================
// 知识库配置(提取 + 注入) — 走后端 IPC,非 localStorage
// ============================================================

const knowledgeConfig = reactive({
  loaded: false,
  auto_extract: true,
  trigger_mode: 'on_complete' as 'on_complete' | 'on_idle' | 'manual_only',
  min_messages: 4,
  idle_timeout_ms: 30000,
  auto_inject: true,
  vector_enabled: false,
  embedding_provider_id: null as string | null,
  embedding_model: null as string | null,
})

// 可做 embedding 的 provider(仅 openai_compat,Anthropic 无 embed API)
const embeddingProviders = computed(() =>
  aiProviders.value.filter(p => p.provider_type !== 'anthropic')
)

async function loadKnowledgeConfig() {
  try {
    const cfg = await knowledgeApi.getConfig()
    Object.assign(knowledgeConfig, cfg)
    knowledgeConfig.loaded = true
  } catch (e) {
    console.error('加载知识库配置失败:', e)
  }
}

let _knowledgeSaveTimer: ReturnType<typeof setTimeout> | null = null
function saveKnowledgeConfigDebounced() {
  if (_knowledgeSaveTimer) clearTimeout(_knowledgeSaveTimer)
  _knowledgeSaveTimer = setTimeout(async () => {
    try {
      const { loaded, ...cfg } = knowledgeConfig
      void loaded
      await knowledgeApi.saveConfig(cfg as any)
    } catch (e) {
      console.error('保存知识库配置失败:', e)
    }
  }, 500)
}

watch(
  () => ({ ...knowledgeConfig }),
  () => {
    if (knowledgeConfig.loaded) saveKnowledgeConfigDebounced()
  },
  { deep: true },
)

onMounted(() => {
  applyTheme(settings.theme)
  loadProviders()
  loadConnections()
  loadKnowledgeConfig()
  // 启动同步一次 LLM 并发配置（防刷新页面后后端未恢复用户设定值）
  syncConcurrencyConfig()
})

// 组件卸载清全部 debounce timer,防 unmount 后旧 timer 仍 fire 写已销毁 reactive(timer 泄漏 FR-C3)
onUnmounted(() => {
  if (_concurrencyTimer) clearTimeout(_concurrencyTimer)
  if (_knowledgeSaveTimer) clearTimeout(_knowledgeSaveTimer)
  if (_toastTimer) clearTimeout(_toastTimer)
})
</script>

<style scoped>
.settings { padding: 16px 20px 20px; }

/* ===== 顶部 Toast 提示 ===== */
.toast {
  position: fixed;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  padding: 8px 16px;
  border-radius: var(--df-radius-sm);
  font-size: 13px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.3);
}
.toast-error { background: var(--df-danger-bg); color: var(--df-danger); border: 0.5px solid var(--df-danger); }
.toast-warning { background: var(--df-warning-bg); color: var(--df-warning); border: 0.5px solid var(--df-warning); }
.toast-info { background: var(--df-accent-bg); color: var(--df-accent); border: 0.5px solid var(--df-accent); }
.toast-enter-active, .toast-leave-active { transition: opacity 0.2s, transform 0.2s; }
.toast-enter-from, .toast-leave-to { opacity: 0; transform: translate(-50%, -8px); }

/* ===== 确认弹层 ===== */
.confirm-mask {
  position: fixed;
  inset: 0;
  z-index: 1100;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
}
.confirm-box {
  background: var(--df-bg-card);
  border: 0.5px solid var(--df-border);
  border-radius: var(--df-radius-lg);
  padding: 20px;
  min-width: 280px;
  max-width: 360px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.4);
}
.confirm-msg { font-size: 13px; color: var(--df-text); line-height: 1.5; margin-bottom: 16px; }
.confirm-actions { display: flex; justify-content: flex-end; gap: 8px; }
.btn-danger { background: var(--df-danger); color: #fff; }
.btn-danger:hover { filter: brightness(1.1); }
.confirm-enter-active, .confirm-leave-active { transition: opacity 0.15s; }
.confirm-enter-from, .confirm-leave-to { opacity: 0; }

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--df-gap-page);
}
.page-header h1 { font-size: 24px; font-weight: 500; color: var(--df-text); }

/* ===== 按钮 ===== */
.btn {
  padding: 8px 16px;
  border: none;
  border-radius: var(--df-radius-sm);
  font-size: 13px;
  cursor: pointer;
  transition: all 0.15s;
}
.btn-primary { background: var(--df-accent); color: #fff; }
.btn-primary:hover { background: var(--df-accent-hover); }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-ghost { background: transparent; color: var(--df-text-secondary); border: 0.5px solid var(--df-border); }
.btn-ghost:hover { background: var(--df-bg-card); color: var(--df-text); }
.btn-sm { padding: 4px 12px; font-size: 12px; }

.btn-link {
  background: none;
  border: none;
  color: var(--df-accent);
  font-size: 12px;
  cursor: pointer;
  padding: 2px 6px;
}
.btn-link:hover { text-decoration: underline; }
.btn-link-danger { color: var(--df-danger); }

/* ===== 设置网格 ===== */
.settings-grid {
  display: flex;
  flex-direction: column;
  gap: var(--df-gap-grid);
}

/* ===== 面板 ===== */
.panel {
  background: var(--df-bg-card);
  border: 0.5px solid var(--df-border);
  border-radius: var(--df-radius-lg);
  padding: var(--df-pad-panel);
}
.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--df-gap-head);
}
.panel-header h2 { font-size: 15px; font-weight: 500; }

.empty-hint {
  font-size: 13px;
  color: var(--df-text-dim);
  padding: 12px 0;
}

/* ===== Provider 卡片 ===== */
.provider-list { display: flex; flex-direction: column; gap: 12px; }
.provider-card {
  background: var(--df-bg);
  border: 0.5px solid var(--df-border);
  border-radius: var(--df-radius);
  padding: 14px 16px;
}
.provider-card--default {
  border-color: var(--df-accent);
  box-shadow: inset 3px 0 0 var(--df-accent);
}
.provider-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}
.provider-info { display: flex; align-items: center; gap: 8px; }
.provider-name { font-size: 14px; font-weight: 500; color: var(--df-text); }
.default-badge {
  font-size: 10px;
  padding: 1px 6px;
  border-radius: var(--df-radius-xs);
  background: rgba(100,255,218,0.15);
  color: var(--df-success);
  font-weight: 500;
}
.provider-actions { display: flex; gap: 4px; }

.provider-detail { display: flex; flex-direction: column; gap: 6px; }
.detail-row { display: flex; align-items: flex-start; gap: 12px; }
.detail-label {
  font-size: 12px;
  color: var(--df-text-dim);
  min-width: 60px;
}
.detail-value {
  font-size: 12px;
  color: var(--df-text-secondary);
  font-family: var(--df-font-mono);
}
.detail-value.mask { color: var(--df-text-dim); letter-spacing: 1px; }

/* ===== 表单 ===== */
.form-grid {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.form-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.form-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--df-text-secondary);
}
.form-actions {
  display: flex;
  justify-content: flex-end;
  padding-top: 4px;
}

/* ===== 连接卡片 ===== */
.connection-list { display: flex; flex-direction: column; gap: 8px; }
.connection-card {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 14px;
  background: var(--df-bg);
  border: 0.5px solid var(--df-border);
  border-radius: var(--df-radius);
}
.conn-left { display: flex; align-items: center; gap: 10px; }
.conn-icon { font-size: 18px; }
.conn-info { display: flex; flex-direction: column; gap: 2px; }
.conn-name-row { display: flex; align-items: center; gap: 8px; }
.conn-name { font-size: 14px; font-weight: 500; color: var(--df-text); }
.conn-type {
  font-size: 10px;
  padding: 2px 6px;
  border-radius: var(--df-radius-sm);
  font-weight: 500;
}
.type-mysql { background: rgba(100,181,246,0.15); color: var(--df-info); }
.type-ssh { background: rgba(108,99,255,0.15); color: var(--df-accent); }
.type-redis { background: rgba(255,107,107,0.15); color: var(--df-danger); }
.type-mongo { background: rgba(100,255,218,0.15); color: var(--df-success); }

.conn-host, .conn-user {
  font-size: 12px;
  color: var(--df-text-dim);
  font-family: var(--df-font-mono);
}
.conn-user {
  background: rgba(90,99,128,0.2);
  padding: 1px 6px;
  border-radius: var(--df-radius-sm);
}
.conn-actions { display: flex; gap: 4px; }

/* ===== 通用设置 ===== */
.general-settings { display: flex; flex-direction: column; }
.setting-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 0;
  border-bottom: 0.5px solid var(--df-border);
}
.setting-row:last-child { border-bottom: none; }
.setting-info { display: flex; flex-direction: column; gap: 2px; }
.setting-label { font-size: 14px; font-weight: 500; color: var(--df-text); }
.setting-desc { font-size: 12px; color: var(--df-text-dim); }

.setting-control { display: flex; align-items: center; }

.setting-select {
  padding: 6px 12px;
  background: var(--df-bg);
  border: 0.5px solid var(--df-border);
  border-radius: var(--df-radius-sm);
  color: var(--df-text);
  font-size: 13px;
  outline: none;
  cursor: pointer;
  min-width: 160px;
}
.setting-select:focus { border-color: var(--df-accent); }

.setting-input {
  padding: 6px 12px;
  background: var(--df-bg);
  border: 0.5px solid var(--df-border);
  border-radius: var(--df-radius-sm);
  color: var(--df-text);
  font-size: 13px;
  outline: none;
  min-width: 260px;
}
.setting-input:focus { border-color: var(--df-accent); }

/* ===== Toggle 开关 ===== */
.toggle {
  position: relative;
  display: inline-block;
  width: 40px;
  height: 22px;
  cursor: pointer;
}
.toggle input { opacity: 0; width: 0; height: 0; }
.toggle-slider {
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
  background: var(--df-border);
  border-radius: var(--df-radius-lg);
  transition: background 0.2s;
}
.toggle-slider::before {
  content: '';
  position: absolute;
  width: 16px;
  height: 16px;
  left: 3px;
  bottom: 3px;
  background: var(--df-text-dim);
  border-radius: 50%;
  transition: transform 0.2s, background 0.2s;
}
.toggle input:checked + .toggle-slider { background: var(--df-accent); }
.toggle input:checked + .toggle-slider::before {
  transform: translateX(18px);
  background: #fff;
}
</style>
