<template>
  <!-- ═══ 通用设置 ═══ -->
  <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 class="setting-row">
        <div class="setting-info">
          <span class="setting-label">{{ $t('settings.labelAgentMaxIterations') }}</span>
          <span class="setting-desc">{{ $t('settings.descAgentMaxIterations') }}</span>
        </div>
        <div class="setting-control">
          <input type="number" class="setting-select" min="1" max="50" style="width:80px"
                 v-model.number="settings.agentMaxIterations"
                 @change="syncAgentMaxIterations" />
        </div>
      </div>
      <div class="setting-row">
        <div class="setting-info">
          <span class="setting-label">{{ $t('settings.labelAgentMaxRetries') }}</span>
          <span class="setting-desc">{{ $t('settings.descAgentMaxRetries') }}</span>
        </div>
        <div class="setting-control">
          <input type="number" class="setting-select" min="0" max="10" style="width:80px"
                 v-model.number="settings.agentMaxRetries"
                 @change="syncAgentMaxRetries" />
        </div>
      </div>
    </div>
  </section>
</template>

<script setup lang="ts">
import { reactive, watch, onMounted, onUnmounted } from 'vue'
import { aiApi } from '@/api'
import { useAppSettingsStore } from '@/stores/appSettings'
import i18n from '@/i18n'

// ============================================================
// 通用设置域 — 本地设置(localStorage):主题/语言/AI语言/并发/Agent 轮次等
// ============================================================
const appSettings = useAppSettingsStore()

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),
  // F-260616-01: Agentic 循环最大轮次，默认 10（与后端 DEFAULT_MAX_AGENT_ITERATIONS 对齐）
  agentMaxIterations: appSettings.get<number>('df-ai-agent-max-iterations', 10),
  // F-260616-07: 流式失败重试次数，默认 3（与后端 DEFAULT_MAX_AGENT_RETRIES 对齐）
  agentMaxRetries: appSettings.get<number>('df-ai-agent-max-retries', 3),
})

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)
})

watch(() => settings.agentMaxIterations, (v) => {
  void appSettings.set('df-ai-agent-max-iterations', v)
})

watch(() => settings.agentMaxRetries, (v) => {
  void appSettings.set('df-ai-agent-max-retries', 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)
}

// 同步 Agentic 最大轮次到后端(debounce 300ms)
// F-260616-01: 后端 loop 入口 load 快照锁定边界——热改后当前 loop 不受影响，
// 下次发消息才生效（与 llm_concurrency 传 Arc 实时反映的区别）。
// 双 clamp：此处 1-50 + 后端 command 再 clamp 1-50，防越界输入致 loop 失效/失控
let _agentIterTimer: ReturnType<typeof setTimeout> | null = null
function syncAgentMaxIterations() {
  // clamp 1-50，防越界(过小致 agent 失能、过大致烧 token)
  settings.agentMaxIterations = Math.min(50, Math.max(1, settings.agentMaxIterations || 10))
  if (_agentIterTimer) clearTimeout(_agentIterTimer)
  _agentIterTimer = setTimeout(async () => {
    try {
      await aiApi.setAgentMaxIterations(settings.agentMaxIterations)
    } catch (e) {
      console.error('同步 Agent 最大轮次失败:', e)
    }
  }, 300)
}

// 同步流式失败重试次数到后端(debounce 300ms)
// F-260616-07: 后端 loop 入口 load 快照锁定边界——热改后当前 loop 不受影响，
// 下次发消息才生效。双 clamp：此处 0-10 + 后端 command 再 clamp 0-10
let _agentRetryTimer: ReturnType<typeof setTimeout> | null = null
function syncAgentMaxRetries() {
  // clamp 0-10，防越界
  settings.agentMaxRetries = Math.min(10, Math.max(0, settings.agentMaxRetries ?? 3))
  if (_agentRetryTimer) clearTimeout(_agentRetryTimer)
  _agentRetryTimer = setTimeout(async () => {
    try {
      await aiApi.setAgentMaxRetries(settings.agentMaxRetries)
    } catch (e) {
      console.error('同步流式重试次数失败:', e)
    }
  }, 300)
}

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

onMounted(() => {
  applyTheme(settings.theme)
  // 启动同步一次 LLM 并发配置（防刷新页面后后端未恢复用户设定值）
  syncConcurrencyConfig()
  // F-260616-01: 启动同步一次 Agentic 最大轮次（防刷新页面后后端未恢复用户设定值）
  // F-260618-23: App.vue 根 onMounted 已在应用启动时恢复（覆盖用户没先进 Settings 直接用 AI Chat 的场景），
  // 此处保留双保险（IPC 幂等值相同无害）
  syncAgentMaxIterations()
  // F-260616-07: 启动同步一次流式失败重试次数（防刷新页面后后端未恢复用户设定值）
  // F-260618-23: 同上，App.vue 根 onMounted 已恢复，此处双保险保留
  syncAgentMaxRetries()
})

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

<style scoped>
/* ===== 面板容器(原 Settings.vue 抽出,各子组件自持 scoped 副本) ===== */
.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; }

/* ===== 通用设置 ===== */
.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); }

/* 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>
