<template>
  <div class="prompt-template-page">
    <div class="page-header">
      <div class="header-content">
        <div class="title-section">
          <h1 class="page-title">Prompt 模板管理</h1>
          <p class="page-desc">管理不同场景的 Prompt 模板，支持版本管理和一键回滚。[AC-IDSMETA-16]</p>
        </div>
        <div class="header-actions">
          <el-select v-model="filterScene" placeholder="按场景筛选" clearable style="width: 150px;">
            <el-option v-for="opt in SCENE_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" />
          </el-select>
          <el-button type="primary" @click="handleCreate">
            <el-icon><Plus /></el-icon>
            新建模板
          </el-button>
        </div>
      </div>
    </div>

    <el-card shadow="hover" class="template-card" v-loading="loading">
      <el-table :data="templates" stripe style="width: 100%">
        <el-table-column prop="name" label="模板名称" min-width="180">
          <template #default="{ row }">
            <div class="template-name">
              <span class="name-text">{{ row.name }}</span>
              <el-tag v-if="row.is_default" type="success" size="small" style="margin-left: 8px;">默认</el-tag>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="scene" label="场景" width="120">
          <template #default="{ row }">
            <el-tag size="small" :type="getSceneTagType(row.scene)">
              {{ getSceneLabel(row.scene) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="published_version" label="发布版本" width="120">
          <template #default="{ row }">
            <span v-if="row.published_version" class="version-badge">
              v{{ row.published_version.version }}
            </span>
            <span v-else class="no-version">未发布</span>
          </template>
        </el-table-column>
        <el-table-column label="元数据" width="120">
          <template #default="{ row }">
            <el-tag v-if="row.metadata && Object.keys(row.metadata).length > 0" size="small" type="info">
              {{ Object.keys(row.metadata).length }} 个字段
            </el-tag>
            <span v-else class="no-metadata">-</span>
          </template>
        </el-table-column>
        <el-table-column prop="updated_at" label="更新时间" width="180">
          <template #default="{ row }">
            {{ formatDate(row.updated_at) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="320" fixed="right">
          <template #default="{ row }">
            <el-button type="info" link size="small" @click="handlePreview(row)">
              <el-icon><View /></el-icon>
              预览
            </el-button>
            <el-button type="primary" link size="small" @click="handleEdit(row)">
              <el-icon><Edit /></el-icon>
              编辑
            </el-button>
            <el-button type="success" link size="small" @click="handlePublish(row)" v-if="row.published_version">
              <el-icon><Upload /></el-icon>
              发布
            </el-button>
            <el-button type="warning" link size="small" @click="handleViewDetail(row)">
              <el-icon><View /></el-icon>
              详情
            </el-button>
            <el-button type="danger" link size="small" @click="handleDelete(row)">
              <el-icon><Delete /></el-icon>
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <el-dialog
      v-model="dialogVisible"
      :title="isEdit ? '编辑模板' : '新建模板'"
      width="950px"
      :close-on-click-modal="false"
      destroy-on-close
    >
      <el-form :model="formData" :rules="formRules" ref="formRef" label-width="100px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="模板名称" prop="name">
              <el-input v-model="formData.name" placeholder="请输入模板名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="场景" prop="scene">
              <el-select v-model="formData.scene" placeholder="请选择场景" style="width: 100%;">
                <el-option v-for="opt in SCENE_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="描述">
          <el-input v-model="formData.description" type="textarea" :rows="2" placeholder="请输入模板描述（可选）" />
        </el-form-item>

        <el-divider content-position="left">元数据配置 [AC-IDSMETA-16]</el-divider>

        <MetadataForm
          ref="metadataFormRef"
          scope="prompt_template"
          v-model="formData.metadata"
          :is-new-object="!isEdit"
          :col-span="8"
        />

        <el-divider content-position="left">系统指令</el-divider>

        <el-form-item label="系统指令" prop="system_instruction">
          <div class="content-editor">
            <div class="editor-main">
              <el-input
                v-model="formData.system_instruction"
                type="textarea"
                :rows="12"
                placeholder="请输入系统指令内容，支持 {{variable}} 变量语法"
                class="content-textarea"
              />
            </div>
            <div class="variables-panel">
              <div class="panel-title">内置变量</div>
              <div class="variable-list">
                <div
                  v-for="v in BUILTIN_VARIABLES"
                  :key="v.name"
                  class="variable-item"
                  @click="insertVariable(v.name)"
                >
                  <span class="var-name">{{ getVarSyntax(v.name) }}</span>
                  <span class="var-desc">{{ v.description }}</span>
                </div>
              </div>
              <div class="panel-divider"></div>
              <div class="panel-title">自定义变量</div>
              <div class="variable-list" v-if="formData.variables && formData.variables.length > 0">
                <div
                  v-for="v in formData.variables"
                  :key="v.name"
                  class="variable-item"
                  @click="insertVariable(v.name)"
                >
                  <span class="var-name">{{ getVarSyntax(v.name) }}</span>
                  <span class="var-desc">{{ v.description || v.default_value }}</span>
                </div>
              </div>
              <div v-else class="empty-hint">暂无自定义变量</div>
            </div>
          </div>
        </el-form-item>
        <el-form-item label="自定义变量">
          <variable-manager :model-value="formData.variables || []" @update:model-value="formData.variables = $event" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="submitting" @click="handleSubmit">
          {{ isEdit ? '保存' : '创建' }}
        </el-button>
      </template>
    </el-dialog>

    <el-drawer v-model="detailDrawer" title="模板详情" size="600px" destroy-on-close>
      <template-detail
        v-if="currentTemplate"
        :template="currentTemplate"
        @publish="handlePublishVersion"
        @rollback="handleRollback"
      />
    </el-drawer>

    <PreviewDialog
      v-model:visible="previewDialogVisible"
      :template-id="previewTemplateId"
      :template-variables="previewVariables"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Edit, Delete, Upload, View } from '@element-plus/icons-vue'
import {
  listPromptTemplates,
  createPromptTemplate,
  updatePromptTemplate,
  deletePromptTemplate,
  getPromptTemplate,
  publishPromptTemplate,
  rollbackPromptTemplate
} from '@/api/prompt-template'
import { MetadataForm } from '@/components/metadata'
import { SCENE_OPTIONS, BUILTIN_VARIABLES } from '@/types/prompt-template'
import type { PromptTemplate, PromptTemplateDetail, PromptTemplateCreate, PromptTemplateUpdate, PromptVariable } from '@/types/prompt-template'
import TemplateDetail from './components/TemplateDetail.vue'
import VariableManager from './components/VariableManager.vue'
import PreviewDialog from './components/PreviewDialog.vue'

const loading = ref(false)
const templates = ref<PromptTemplate[]>([])
const filterScene = ref('')
const dialogVisible = ref(false)
const detailDrawer = ref(false)
const isEdit = ref(false)
const submitting = ref(false)
const formRef = ref()
const metadataFormRef = ref()
const currentTemplate = ref<PromptTemplateDetail | null>(null)
const currentEditId = ref('')
const previewDialogVisible = ref(false)
const previewTemplateId = ref('')
const previewVariables = ref<PromptVariable[]>([])

const formData = ref<PromptTemplateCreate>({
  name: '',
  scene: '',
  description: '',
  system_instruction: '',
  variables: [],
  metadata: {}
})

const formRules = {
  name: [{ required: true, message: '请输入模板名称', trigger: 'blur' }],
  scene: [{ required: true, message: '请选择场景', trigger: 'change' }],
  system_instruction: [{ required: true, message: '请输入系统指令内容', trigger: 'blur' }]
}

const getSceneLabel = (scene: string) => {
  const opt = SCENE_OPTIONS.find(o => o.value === scene)
  return opt?.label || scene
}

const getVarSyntax = (name: string) => {
  return `{{${name}}}`
}

const getSceneTagType = (scene: string): '' | 'success' | 'warning' | 'danger' | 'info' => {
  const typeMap: Record<string, '' | 'success' | 'warning' | 'danger' | 'info'> = {
    chat: '',
    qa: 'success',
    summary: 'warning',
    translation: 'danger',
    code: 'info',
    custom: ''
  }
  return typeMap[scene] || ''
}

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 loadTemplates = async () => {
  loading.value = true
  try {
    const res = await listPromptTemplates({ scene: filterScene.value || undefined })
    templates.value = res.data || []
  } catch (error) {
    ElMessage.error('加载模板列表失败')
  } finally {
    loading.value = false
  }
}

const handleCreate = () => {
  isEdit.value = false
  currentEditId.value = ''
  formData.value = {
    name: '',
    scene: '',
    description: '',
    system_instruction: '',
    variables: [],
    metadata: {}
  }
  dialogVisible.value = true
}

const handleEdit = async (row: PromptTemplate) => {
  isEdit.value = true
  currentEditId.value = row.id
  try {
    const detail = await getPromptTemplate(row.id)
    formData.value = {
      name: detail.name,
      scene: detail.scene,
      description: detail.description || '',
      system_instruction: detail.current_content || '',
      variables: detail.variables || [],
      metadata: detail.metadata || {}
    }
    dialogVisible.value = true
  } catch (error) {
    ElMessage.error('加载模板详情失败')
  }
}

const handleDelete = async (row: PromptTemplate) => {
  try {
    await ElMessageBox.confirm('确定要删除该模板吗？删除后无法恢复。', '确认删除', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    await deletePromptTemplate(row.id)
    ElMessage.success('删除成功')
    loadTemplates()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败')
    }
  }
}

const handlePublish = async (row: PromptTemplate) => {
  if (!row.published_version) {
    ElMessage.warning('该模板暂无可发布版本')
    return
  }
  try {
    await ElMessageBox.confirm(`确定要发布版本 v${row.published_version.version} 吗？`, '确认发布', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'info'
    })
    await publishPromptTemplate(row.id, { version: row.published_version.version })
    ElMessage.success('发布成功')
    loadTemplates()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('发布失败')
    }
  }
}

const handleViewDetail = async (row: PromptTemplate) => {
  try {
    currentTemplate.value = await getPromptTemplate(row.id)
    detailDrawer.value = true
  } catch (error) {
    ElMessage.error('加载模板详情失败')
  }
}

const handlePreview = async (row: PromptTemplate) => {
  try {
    const detail = await getPromptTemplate(row.id)
    previewTemplateId.value = row.id
    previewVariables.value = detail.variables || []
    previewDialogVisible.value = true
  } catch (error) {
    ElMessage.error('加载模板详情失败')
  }
}

const handleSubmit = async () => {
  try {
    await formRef.value.validate()
  } catch {
    return
  }

  if (metadataFormRef.value) {
    const validation = await metadataFormRef.value.validate()
    if (!validation.valid) {
      ElMessage.warning('请完善必填的元数据字段')
      return
    }
  }

  submitting.value = true
  try {
    if (isEdit.value) {
      const updateData: PromptTemplateUpdate = {
        name: formData.value.name,
        scene: formData.value.scene,
        description: formData.value.description,
        system_instruction: formData.value.system_instruction,
        variables: formData.value.variables,
        metadata: formData.value.metadata
      }
      await updatePromptTemplate(currentEditId.value, updateData)
      ElMessage.success('保存成功')
    } else {
      await createPromptTemplate(formData.value)
      ElMessage.success('创建成功')
    }
    dialogVisible.value = false
    loadTemplates()
  } catch (error) {
    ElMessage.error(isEdit.value ? '保存失败' : '创建失败')
  } finally {
    submitting.value = false
  }
}

const insertVariable = (varName: string) => {
  const textarea = document.querySelector('.content-textarea textarea') as HTMLTextAreaElement
  if (textarea) {
    const start = textarea.selectionStart
    const end = textarea.selectionEnd
    const text = formData.value.system_instruction || ''
    const insertText = `{{${varName}}}`
    formData.value.system_instruction = text.substring(0, start) + insertText + text.substring(end)
    setTimeout(() => {
      textarea.focus()
      textarea.setSelectionRange(start + insertText.length, start + insertText.length)
    }, 0)
  } else {
    formData.value.system_instruction = (formData.value.system_instruction || '') + `{{${varName}}}`
  }
}

const handlePublishVersion = async (version: number) => {
  if (!currentTemplate.value) return
  try {
    await publishPromptTemplate(currentTemplate.value.id, { version })
    ElMessage.success('发布成功')
    currentTemplate.value = await getPromptTemplate(currentTemplate.value.id)
    loadTemplates()
  } catch (error) {
    ElMessage.error('发布失败')
  }
}

const handleRollback = async (version: number) => {
  if (!currentTemplate.value) return
  try {
    await ElMessageBox.confirm(`确定要回滚到版本 v${version} 吗？`, '确认回滚', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    await rollbackPromptTemplate(currentTemplate.value.id, { version })
    ElMessage.success('回滚成功')
    currentTemplate.value = await getPromptTemplate(currentTemplate.value.id)
    loadTemplates()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('回滚失败')
    }
  }
}

watch(filterScene, () => {
  loadTemplates()
})

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

<style scoped>
.prompt-template-page {
  padding: 24px;
}

.page-header {
  margin-bottom: 24px;
}

.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(--el-text-color-primary);
}

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

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

.template-card {
  border-radius: 8px;
}

.template-name {
  display: flex;
  align-items: center;
}

.name-text {
  font-weight: 500;
}

.version-badge {
  display: inline-block;
  padding: 2px 8px;
  background-color: var(--el-color-success-light-9);
  color: var(--el-color-success);
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
}

.no-version {
  color: var(--el-text-color-placeholder);
  font-size: 12px;
}

.no-metadata {
  color: var(--el-text-color-placeholder);
}

.content-editor {
  display: flex;
  gap: 16px;
  width: 100%;
}

.editor-main {
  flex: 1;
}

.variables-panel {
  width: 200px;
  border: 1px solid var(--el-border-color-light);
  border-radius: 6px;
  overflow: hidden;
}

.panel-title {
  padding: 10px 12px;
  background-color: var(--el-fill-color-light);
  font-size: 13px;
  font-weight: 600;
  color: var(--el-text-color-secondary);
  border-bottom: 1px solid var(--el-border-color-light);
}

.variable-list {
  max-height: 280px;
  overflow-y: auto;
}

.variable-item {
  padding: 8px 12px;
  cursor: pointer;
  transition: background-color 0.2s;
  border-bottom: 1px solid var(--el-border-color-extra-light);
}

.variable-item:last-child {
  border-bottom: none;
}

.variable-item:hover {
  background-color: var(--el-fill-color-light);
}

.var-name {
  display: block;
  font-family: monospace;
  font-size: 12px;
  color: var(--el-color-primary);
  margin-bottom: 2px;
}

.var-desc {
  display: block;
  font-size: 11px;
  color: var(--el-text-color-placeholder);
}

.panel-divider {
  height: 1px;
  background-color: var(--el-border-color-light);
  margin: 8px 0;
}

.empty-hint {
  padding: 12px;
  text-align: center;
  font-size: 12px;
  color: var(--el-text-color-placeholder);
}
</style>
