<template>
  <div class="llm-config-page">
    <div class="page-header">
      <div class="header-content">
        <div class="title-section">
          <h1 class="page-title">LLM 模型配置</h1>
          <p class="page-desc">配置和管理系统使用的大语言模型，支持多种提供者切换。配置修改后需保存才能生效。</p>
        </div>
        <div class="header-actions" v-if="currentConfig.updated_at">
          <div class="update-info">
            <el-icon class="update-icon"><Clock /></el-icon>
            <span>上次更新: {{ formatDate(currentConfig.updated_at) }}</span>
          </div>
        </div>
      </div>
    </div>

    <el-row :gutter="24" v-loading="pageLoading" element-loading-text="加载中...">
      <el-col :xs="24" :sm="24" :md="12" :lg="12">
        <el-card shadow="hover" class="config-card">
          <template #header>
            <div class="card-header">
              <div class="header-left">
                <div class="icon-wrapper llm-icon">
                  <el-icon><Cpu /></el-icon>
                </div>
                <span class="header-title">模型配置</span>
              </div>
            </div>
          </template>

          <div class="card-content">
            <div class="provider-select-section">
              <div class="section-label">
                <el-icon><Connection /></el-icon>
                <span>选择提供者</span>
              </div>
              <ProviderSelect
                v-model="currentConfig.provider"
                :providers="providers"
                :loading="providersLoading"
                placeholder="请选择 LLM 提供者"
                @change="handleProviderChange"
              />
              <transition name="fade">
                <div v-if="currentProvider" class="provider-info">
                  <el-icon class="info-icon"><InfoFilled /></el-icon>
                  <span class="info-text">{{ currentProvider.description }}</span>
                </div>
              </transition>
            </div>

            <el-divider />

            <transition name="slide-fade" mode="out-in">
              <div v-if="currentConfig.provider" key="form" class="config-form-section">
                <ConfigForm
                  ref="configFormRef"
                  :schema="configSchema"
                  v-model="currentConfig.config"
                  label-width="140px"
                />
              </div>
              <el-empty v-else key="empty" description="请先选择一个 LLM 提供者" :image-size="120">
                <template #image>
                  <div class="empty-icon">
                    <el-icon><Box /></el-icon>
                  </div>
                </template>
              </el-empty>
            </transition>
          </div>

          <template #footer>
            <div class="card-footer">
              <el-button size="large" @click="handleReset">
                <el-icon><RefreshLeft /></el-icon>
                重置
              </el-button>
              <el-button type="primary" size="large" :loading="saving" @click="handleSave">
                <el-icon><Check /></el-icon>
                保存配置
              </el-button>
            </div>
          </template>
        </el-card>
      </el-col>

      <el-col :xs="24" :sm="24" :md="12" :lg="12">
        <TestPanel
          :test-fn="handleTest"
          :can-test="!!currentConfig.provider"
          title="LLM 连接测试"
          input-label="测试提示词"
          input-placeholder="请输入测试提示词（可选，默认使用系统预设提示词）"
          :show-token-stats="true"
        />
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Cpu, Connection, InfoFilled, Box, RefreshLeft, Check, Clock } from '@element-plus/icons-vue'
import { useLLMStore } from '@/stores/llm'
import ProviderSelect from '@/components/common/ProviderSelect.vue'
import ConfigForm from '@/components/common/ConfigForm.vue'
import TestPanel from '@/components/common/TestPanel.vue'
import type { TestResult } from '@/components/common/TestPanel.vue'

const llmStore = useLLMStore()

const configFormRef = ref<InstanceType<typeof ConfigForm>>()
const saving = ref(false)
const pageLoading = ref(false)

const providers = computed(() => llmStore.providers)
const currentConfig = computed(() => llmStore.currentConfig)
const currentProvider = computed(() => llmStore.currentProvider)
const configSchema = computed(() => llmStore.configSchema)
const providersLoading = computed(() => llmStore.providersLoading)

const formatDate = (dateStr: string) => {
  if (!dateStr) return ''
  const date = new Date(dateStr)
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  })
}

const handleProviderChange = (provider: any) => {
  if (provider?.name) {
    llmStore.setProvider(provider.name)
  }
}

const handleSave = async () => {
  if (!currentConfig.value.provider) {
    ElMessage.warning('请先选择 LLM 提供者')
    return
  }

  try {
    const valid = await configFormRef.value?.validate()
    if (!valid) {
      return
    }
  } catch (error) {
    ElMessage.warning('请检查配置表单中的必填项')
    return
  }

  saving.value = true
  try {
    await llmStore.saveCurrentConfig()
    ElMessage.success('配置保存成功')
  } catch (error) {
    ElMessage.error('配置保存失败')
  } finally {
    saving.value = false
  }
}

const handleReset = async () => {
  try {
    await ElMessageBox.confirm('确定要重置配置吗？将恢复为当前保存的配置。', '确认重置', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    await llmStore.loadConfig()
    ElMessage.success('配置已重置')
  } catch (error) {
  }
}

const handleTest = async (input?: string): Promise<TestResult> => {
  return await llmStore.runTest(input)
}

const initPage = async () => {
  pageLoading.value = true
  try {
    await Promise.all([
      llmStore.loadProviders(),
      llmStore.loadConfig()
    ])
  } catch (error) {
    ElMessage.error('初始化页面失败')
  } finally {
    pageLoading.value = false
  }
}

onMounted(() => {
  initPage()
})
</script>

<style scoped>
.llm-config-page {
  padding: 24px;
  min-height: calc(100vh - 60px);
}

.page-header {
  margin-bottom: 24px;
  animation: slideDown 0.4s ease-out;
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 20px;
  flex-wrap: wrap;
}

.title-section {
  flex: 1;
  min-width: 300px;
}

.page-title {
  margin: 0 0 8px 0;
  font-size: 24px;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: -0.5px;
}

.page-desc {
  margin: 0;
  font-size: 14px;
  color: var(--text-secondary);
  line-height: 1.6;
}

.header-actions {
  display: flex;
  align-items: center;
}

.update-info {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  background-color: var(--bg-tertiary);
  border-radius: 8px;
  font-size: 13px;
  color: var(--text-secondary);
}

.update-icon {
  font-size: 14px;
  color: var(--text-tertiary);
}

.config-card {
  animation: fadeInUp 0.5s ease-out;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.icon-wrapper {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--primary-lighter);
  border-radius: 10px;
  color: var(--primary-color);
  font-size: 18px;
}

.icon-wrapper.llm-icon {
  background: linear-gradient(135deg, #E0F2FE 0%, #BAE6FD 100%);
  color: #0284C7;
}

.header-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
}

.card-content {
  padding: 8px 0;
}

.provider-select-section {
  margin-bottom: 16px;
}

.section-label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
}

.section-label .el-icon {
  color: var(--primary-color);
}

.provider-info {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 14px;
  padding: 14px 16px;
  background-color: var(--bg-tertiary);
  border-radius: 10px;
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.6;
  border-left: 3px solid var(--primary-color);
}

.info-icon {
  margin-top: 2px;
  color: var(--primary-color);
  font-size: 16px;
}

.info-text {
  flex: 1;
}

.config-form-section {
  max-height: 400px;
  overflow-y: auto;
  padding-right: 8px;
}

.config-form-section::-webkit-scrollbar {
  width: 6px;
}

.config-form-section::-webkit-scrollbar-track {
  background: var(--bg-tertiary);
  border-radius: 3px;
}

.config-form-section::-webkit-scrollbar-thumb {
  background: var(--text-tertiary);
  border-radius: 3px;
}

.config-form-section::-webkit-scrollbar-thumb:hover {
  background: var(--text-secondary);
}

.card-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding-top: 8px;
}

.empty-icon {
  width: 100px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--bg-tertiary);
  border-radius: 50%;
  margin: 0 auto;
}

.empty-icon .el-icon {
  font-size: 48px;
  color: var(--text-tertiary);
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.25s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.slide-fade-enter-active {
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.slide-fade-leave-active {
  transition: all 0.2s cubic-bezier(1, 0.5, 0.8, 1);
}

.slide-fade-enter-from {
  opacity: 0;
  transform: translateX(-16px);
}

.slide-fade-leave-to {
  opacity: 0;
  transform: translateX(16px);
}

@media (max-width: 768px) {
  .llm-config-page {
    padding: 16px;
  }

  .page-title {
    font-size: 20px;
  }

  .header-content {
    flex-direction: column;
  }

  .title-section {
    min-width: 100%;
  }

  .config-form-section {
    max-height: 300px;
  }
}
</style>
