<template>
  <PermissionGuard widget-id="ConfigCenter">
    <div class="sys-page">
      <el-card shadow="never" class="sys-card">
        <template #header>
          <div class="sys-header">
            <div class="sys-title-wrap">
              <span class="sys-title">系统配置</span>
              <span class="sys-desc">{{ headerDesc }}</span>
            </div>
            <div class="sys-actions">
              <el-button @click="onReset">重置</el-button>
              <el-button type="primary" :loading="saving" @click="onSave">保存</el-button>
            </div>
          </div>
        </template>

        <el-tabs v-model="group" class="sys-tabs">
          <el-tab-pane label="界面主题" name="theme">
            <p class="tab-hint">为各主题单独调色，修改后立即预览。当前主题会同步到全站。</p>
            <ThemeCustomizer />
          </el-tab-pane>

          <el-tab-pane name="ai">
            <template #label>
              <span>AI 服务</span>
              <el-tag
                size="small"
                :type="aiCfg.configured ? 'success' : 'warning'"
                effect="plain"
                class="ai-tab-tag">
                {{ aiCfg.configured ? '已配置' : '未配置' }}
              </el-tag>
            </template>
            <p class="tab-hint">地图编辑器「AI 生图」所依赖的对话接口。</p>
            <div class="sys-fields">
              <label class="sys-field sys-field--wide">
                <span>Endpoint</span>
                <el-input v-model="aiCfg.endpoint" placeholder="https://api.openai.com/v1/chat/completions" />
              </label>
              <label class="sys-field sys-field--wide">
                <span>API Key</span>
                <el-input v-model="aiCfg.apiKey" type="password" show-password placeholder="sk-..." />
              </label>
              <label class="sys-field sys-field--wide">
                <span>模型</span>
                <el-input v-model="aiCfg.model" placeholder="gpt-4o-mini" />
              </label>
              <label class="sys-field sys-field--wide">
                <span>System Prompt</span>
                <el-input v-model="aiCfg.systemPrompt" type="textarea" :rows="4" />
              </label>
              <label class="sys-field">
                <span>Temperature</span>
                <el-input-number v-model="aiCfg.temperature" :min="0" :max="2" :step="0.1" />
              </label>
              <label class="sys-field">
                <span>Max Tokens</span>
                <el-input-number v-model="aiCfg.maxTokens" :min="64" :max="32000" :step="64" />
              </label>
              <label class="sys-field">
                <span>超时 (秒)</span>
                <el-input-number v-model="aiCfg.timeoutSec" :min="5" :max="600" />
              </label>
            </div>
            <div class="tab-toolbar">
              <el-button :loading="aiTesting" @click="onTestAi">测试连通</el-button>
            </div>
          </el-tab-pane>

          <el-tab-pane label="日志清理" name="logs">
            <p class="tab-hint">清理 Simple3 工作目录 log/ 下过期的 *.log，并监测日志所在盘剩余空间。保存后立即生效。</p>
            <div class="sys-fields">
              <label class="sys-field">
                <span>启用自动清理</span>
                <el-switch v-model="logCfg.enabled" />
              </label>
              <label class="sys-field">
                <span>启动时先清一次</span>
                <el-switch v-model="logCfg.runOnStartup" />
              </label>
              <label class="sys-field">
                <span>保留天数</span>
                <el-input-number v-model="logCfg.retentionDays" :min="1" :max="3650" :step="1" />
              </label>
              <label class="sys-field">
                <span>清理间隔（小时）</span>
                <el-input-number v-model="logCfg.checkIntervalHours" :min="1" :max="168" :step="1" />
              </label>
              <label class="sys-field">
                <span>启用磁盘告警</span>
                <el-switch v-model="logCfg.diskAlertEnabled" />
              </label>
              <label class="sys-field">
                <span>告警阈值（GB）</span>
                <el-input-number v-model="logCfg.diskFreeAlertGB" :min="0.5" :max="1024" :step="0.5" />
              </label>
              <label class="sys-field">
                <span>磁盘检测间隔（分钟）</span>
                <el-input-number v-model="logCfg.diskCheckIntervalMinutes" :min="1" :max="1440" :step="1" />
              </label>
            </div>
            <div class="tab-toolbar">
              <el-button :loading="logCleaning" @click="onCleanNow">立即清理</el-button>
            </div>
          </el-tab-pane>
        </el-tabs>
      </el-card>
    </div>
  </PermissionGuard>
</template>

<script setup lang="ts">
import PermissionGuard from '@/components/PermissionGuard.vue'
import ThemeCustomizer from '@/components/ThemeCustomizer.vue'
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { aiConfigApi, mapEditApi, type AiConfig } from '@/api/mapEdit'
import { logsApi, type LogCleanupConfig } from '@/api/logs'
import { ElMessage } from 'element-plus'

type GroupId = 'theme' | 'ai' | 'logs'
const TAB_NAMES: GroupId[] = ['theme', 'ai', 'logs']

const route = useRoute()
const router = useRouter()

function readGroup(): GroupId {
  const q = route.query.tab
  if (q === 'log') return 'logs'
  return typeof q === 'string' && (TAB_NAMES as string[]).includes(q) ? (q as GroupId) : 'theme'
}

const group = ref<GroupId>(readGroup())
const headerDesc = computed(() => {
  if (group.value === 'ai') return 'AI 服务需点保存后写入。'
  if (group.value === 'logs') return '日志清理保存后立即重排后台任务。'
  return '界面主题立即生效。'
})
const saving = computed(() => aiSaving.value || logSaving.value)

const aiCfg = reactive<AiConfig>({
  endpoint: 'https://api.openai.com/v1/chat/completions',
  apiKey: '',
  model: 'gpt-4o-mini',
  systemPrompt: '你是一个 AGV 路网设计师。',
  temperature: 0.4,
  maxTokens: 4096,
  timeoutSec: 60,
  configured: false
})

const logCfg = reactive<LogCleanupConfig>({
  enabled: true,
  retentionDays: 30,
  checkIntervalHours: 24,
  runOnStartup: true,
  diskAlertEnabled: true,
  diskFreeAlertGB: 5,
  diskCheckIntervalMinutes: 30
})

const aiSaving = ref(false)
const aiTesting = ref(false)
const logSaving = ref(false)
const logCleaning = ref(false)

watch(group, (t) => {
  if (route.query.tab !== t) router.replace({ query: { ...route.query, tab: t } })
})
watch(() => route.query.tab, () => { group.value = readGroup() })

onMounted(async () => {
  group.value = readGroup()
  await Promise.all([loadAi(), loadLogs()])
})

async function loadAi() {
  try {
    const r = await aiConfigApi.get()
    Object.assign(aiCfg, r)
  } catch (err) {
    ElMessage.warning(`无法读取 AI 配置：${(err as Error).message}`)
  }
}

async function loadLogs() {
  try {
    Object.assign(logCfg, await logsApi.cleanupConfig())
  } catch (err) {
    ElMessage.warning(`无法读取日志清理配置：${(err as Error).message}`)
  }
}

async function onSave() {
  if (group.value === 'theme') {
    ElMessage.info('主题已即时生效，无需保存')
    return
  }
  if (group.value === 'ai') {
    try {
      aiSaving.value = true
      await aiConfigApi.save({ ...aiCfg })
      aiCfg.configured = !!aiCfg.apiKey
      ElMessage.success('已保存')
    } catch (err) {
      ElMessage.error(`AI 配置保存失败：${(err as Error).message}`)
    } finally {
      aiSaving.value = false
    }
    return
  }
  try {
    logSaving.value = true
    Object.assign(logCfg, await logsApi.saveCleanupConfig({ ...logCfg }))
    ElMessage.success('日志清理配置已保存')
  } catch (err) {
    ElMessage.error(`日志清理配置保存失败：${(err as Error).message}`)
  } finally {
    logSaving.value = false
  }
}

async function onReset() {
  if (group.value === 'logs') await loadLogs()
  else await loadAi()
}

async function onTestAi() {
  try {
    aiTesting.value = true
    const r = await mapEditApi.aiMapGenerate({
      prompt: '测试连通：仅返回 "ok"，不要生成任何站点或路径。',
      mode: 'sites',
      bounds: [0, 0, 0, 0]
    })
    ElMessage.success(`AI 服务连通正常：返回工具调用 ${r.usedTools} 次`)
  } catch (err) {
    ElMessage.error(`连通失败：${(err as Error).message}`)
  } finally {
    aiTesting.value = false
  }
}

async function onCleanNow() {
  try {
    logCleaning.value = true
    const r = await logsApi.cleanupNow()
    ElMessage.success(`已清理 ${r.deletedFiles} 个文件，释放 ${r.freedMB} MB`)
  } catch (err) {
    ElMessage.error(`立即清理失败：${(err as Error).message}`)
  } finally {
    logCleaning.value = false
  }
}
</script>

<style scoped>
.sys-page {
  padding: 16px;
  height: 100%;
  min-height: 0;
  overflow: auto;
}
.sys-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.sys-title-wrap {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.sys-title {
  font-weight: 600;
  font-size: 16px;
  color: var(--mg-text-light);
}
.sys-desc {
  font-size: 12.5px;
  color: var(--mg-text-muted);
}
.sys-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.tab-hint {
  margin: 0 0 14px;
  font-size: 13px;
  color: var(--mg-text-muted);
  line-height: 1.5;
}
.tab-toolbar {
  margin-top: 16px;
}
.ai-tab-tag {
  margin-left: 6px;
  vertical-align: middle;
}
.sys-fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 280px));
  gap: 16px 28px;
}
.sys-field {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  margin: 0;
}
.sys-field > span {
  font-size: 12px;
  font-weight: 500;
  color: var(--mg-text-muted);
}
.sys-field--wide {
  grid-column: 1 / -1;
}
@media (max-width: 860px) {
  .sys-header {
    flex-direction: column;
  }
  .sys-fields {
    grid-template-columns: 1fr;
  }
}
</style>
