<template>
  <!-- ═══ 性能设置(全局并发 / 单对话并发 / Agent 最大轮次 / 流式重试)═══ -->
  <section class="panel">
    <div class="panel-header">
      <h2>{{ $t('settings.sectionPerformance') }}</h2>
    </div>
    <div class="general-settings">
      <SettingRow
        ref="rowGlobalConcurrency"
        next-round
        :label="$t('settings.labelGlobalConcurrency')"
        :desc="$t('settings.descGlobalConcurrency')">
        <input type="number" class="setting-number" min="1" style="width:80px"
               v-model.number="settings.llmGlobalConcurrency"
               @change="onConcurrencyChange" />
      </SettingRow>
      <SettingRow
        ref="rowPerConvConcurrency"
        next-round
        :label="$t('settings.labelPerConvConcurrency')"
        :desc="$t('settings.descPerConvConcurrency')">
        <input type="number" class="setting-number" min="1" style="width:80px"
               v-model.number="settings.llmPerConvConcurrency"
               @change="onConcurrencyChange" />
      </SettingRow>
      <SettingRow
        ref="rowMaxIterations"
        next-round
        :label="$t('settings.labelAgentMaxIterations')"
        :desc="$t('settings.descAgentMaxIterations')">
        <label class="unlimited-toggle">
          <input type="checkbox" v-model="unlimited" @change="markSaved('iter')" />
          <span>{{ $t('settings.labelUnlimited') }}</span>
        </label>
        <input type="number" class="setting-number" min="1" max="50" style="width:80px"
               v-model.number="settings.agentMaxIterations"
               :disabled="unlimited"
               @change="onIterChange" />
      </SettingRow>
      <SettingRow
        ref="rowMaxRetries"
        next-round
        :label="$t('settings.labelAgentMaxRetries')"
        :desc="$t('settings.descAgentMaxRetries')">
        <input type="number" class="setting-number" min="0" max="10" style="width:80px"
               v-model.number="settings.agentMaxRetries"
               @change="onRetryChange" />
      </SettingRow>
    </div>
  </section>
</template>

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

// ============================================================
// 性能域 — 本地设置(localStorage):LLM 并发 / 单对话并发 / Agent 轮次 / 流式重试
// 拆自 GeneralPanel,本 Section 仅持有性能相关 key + 各自 debounce IPC 同步
// 阶段5:SettingRow 封装行布局 + nextRound badge(后端快照锁定边界,下次对话生效);
//        4 项变更后调 markSaved 显"已保存"
// ============================================================
const appSettings = useAppSettingsStore()

const settings = reactive({
  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),
})

// 即时生效反馈:SettingRow refs
const rowGlobalConcurrency = useTemplateRef<InstanceType<typeof SettingRow>>('rowGlobalConcurrency')
const rowPerConvConcurrency = useTemplateRef<InstanceType<typeof SettingRow>>('rowPerConvConcurrency')
const rowMaxIterations = useTemplateRef<InstanceType<typeof SettingRow>>('rowMaxIterations')
const rowMaxRetries = useTemplateRef<InstanceType<typeof SettingRow>>('rowMaxRetries')
function markSaved(key: 'global' | 'perConv' | 'iter' | 'retry') {
  const map = { global: rowGlobalConcurrency.value, perConv: rowPerConvConcurrency.value, iter: rowMaxIterations.value, retry: rowMaxRetries.value }
  map[key]?.markSaved()
}

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

// onMounted 期间调 sync 不应触发"已保存"反馈(那是启动恢复,非用户改动)
let _userInteracting = false

// 同步 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)
  if (_userInteracting) {
    markSaved('global')
    markSaved('perConv')
  }
}

// wrapper:并发变更(@change 用户触发)同时反馈两项(global/perConv 任一变动都同步两项)
function onConcurrencyChange() {
  _userInteracting = true
  syncConcurrencyConfig()
  _userInteracting = false
}
// wrapper:轮次 @change 用户触发,走 _userInteracting 守卫显反馈(onMounted 启动同步不显)
function onIterChange() {
  _userInteracting = true
  syncAgentMaxIterations()
  _userInteracting = false
}
// wrapper:重试 @change 用户触发,走 _userInteracting 守卫显反馈
function onRetryChange() {
  _userInteracting = true
  syncAgentMaxRetries()
  _userInteracting = false
}

// 同步 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() {
  // 0=不限透传;否则 clamp 1-50 防越界(过小致 agent 失能、过大致烧 token)
  if (settings.agentMaxIterations !== 0) {
    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)
  if (_userInteracting) {
    markSaved('iter')
  }
}

// 「不限」勾选:agentMaxIterations===0 即不限(后端 0→usize::MAX,loop 靠 stop/收敛/审批退出)
const unlimited = computed({
  get: () => settings.agentMaxIterations === 0,
  set(v: boolean) {
    if (v) {
      settings.agentMaxIterations = 0
    } else if (settings.agentMaxIterations === 0) {
      settings.agentMaxIterations = 10
    }
    syncAgentMaxIterations()
  },
})

// 同步流式失败重试次数到后端(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)
  if (_userInteracting) {
    markSaved('retry')
  }
}

onMounted(() => {
  // 启动同步一次 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>
/* 阶段5 UX 重构:复用 settings.css 全局 .panel/.panel-header/.general-settings/
   .setting-number + SettingRow(封装 .setting-row/.setting-info/.setting-label/
   .setting-desc/.setting-control + nextRound badge)。本 Section 无特有 scoped 样式
   (.unlimited-toggle 沿用默认 label)。 */
</style>
