<template>
  <div class="slot-definition-page">
    <div class="page-header">
      <div class="header-content">
        <div class="title-section">
          <h1 class="page-title">槽位定义管理</h1>
          <p class="page-desc">配置对话流程中的结构化槽位，用于信息收集和槽位填充。[AC-MRS-07,08]</p>
        </div>
        <div class="header-actions">
          <el-select v-model="filterRequired" placeholder="按必填筛选" clearable style="width: 140px;">
            <el-option label="必填" :value="true" />
            <el-option label="可选" :value="false" />
          </el-select>
          <el-button type="primary" @click="handleCreate">
            <el-icon><Plus /></el-icon>
            新建槽位
          </el-button>
        </div>
      </div>
    </div>

    <el-card shadow="hover" class="slot-card" v-loading="loading">
      <el-table :data="slots" stripe style="width: 100%">
        <el-table-column prop="slot_key" label="槽位标识" min-width="140">
          <template #default="{ row }">
            <div class="slot-key-cell">
              <code class="slot-key">{{ row.slot_key }}</code>
              <span v-if="row.display_name" class="display-name">{{ row.display_name }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="说明" min-width="180">
          <template #default="{ row }">
            <span v-if="row.description" class="slot-description">{{ row.description }}</span>
            <span v-else class="no-value">-</span>
          </template>
        </el-table-column>
        <el-table-column prop="type" label="类型" width="100">
          <template #default="{ row }">
            <el-tag size="small" type="info">{{ getTypeLabel(row.type) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="required" label="必填" width="80">
          <template #default="{ row }">
            <el-tag :type="row.required ? 'danger' : 'info'" size="small">
              {{ row.required ? '必填' : '可选' }}
            </el-tag>
          </template>
        </el-table-column>
        <!-- [AC-MRS-07-UPGRADE] 策略链展示 -->
        <el-table-column prop="extract_strategies" label="提取策略链" min-width="180">
          <template #default="{ row }">
            <div v-if="getEffectiveStrategies(row).length > 0" class="strategy-chain">
              <el-tag 
                v-for="(strategy, idx) in getEffectiveStrategies(row)" 
                :key="idx"
                size="small"
                :type="getStrategyTagType(strategy)"
                class="strategy-tag"
              >
                {{ idx + 1 }}. {{ getExtractStrategyLabel(strategy) }}
              </el-tag>
            </div>
            <span v-else class="no-value">-</span>
          </template>
        </el-table-column>
        <el-table-column prop="linked_field" label="关联字段" min-width="160">
          <template #default="{ row }">
            <div v-if="row.linked_field" class="linked-field">
              <code class="field-key">{{ row.linked_field.field_key }}</code>
              <el-tag size="small" type="success" class="linked-tag">已关联</el-tag>
            </div>
            <span v-else class="no-value">-</span>
          </template>
        </el-table-column>
        <el-table-column prop="ask_back_prompt" label="追问提示语" min-width="180">
          <template #default="{ row }">
            <span v-if="row.ask_back_prompt" class="ask-back-prompt">{{ row.ask_back_prompt }}</span>
            <span v-else class="no-value">-</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="150" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" link size="small" @click="handleEdit(row)">
              <el-icon><Edit /></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-empty v-if="!loading && slots.length === 0" description="暂无槽位定义" />
    </el-card>

    <el-dialog
      v-model="dialogVisible"
      :title="isEdit ? '编辑槽位定义' : '新建槽位定义'"
      width="700px"
      :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="slot_key">
              <el-input
                v-model="formData.slot_key"
                placeholder="如：grade, subject"
                :disabled="isEdit"
              />
              <div class="field-hint">仅允许小写字母、数字、下划线</div>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="槽位名称" prop="display_name">
              <el-input
                v-model="formData.display_name"
                placeholder="如：当前年级"
              />
              <div class="field-hint">给运营/教研看的中文名</div>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="槽位说明" prop="description">
          <el-input
            v-model="formData.description"
            type="textarea"
            :rows="2"
            placeholder="解释这个槽位采集什么、用于哪里，如：用于课程分层推荐和知识库过滤"
          />
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="槽位类型" prop="type">
              <el-select v-model="formData.type" style="width: 100%;">
                <el-option
                  v-for="opt in SLOT_TYPE_OPTIONS"
                  :key="opt.value"
                  :label="opt.label"
                  :value="opt.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否必填" prop="required">
              <el-switch v-model="formData.required" />
            </el-form-item>
          </el-col>
        </el-row>
        
        <!-- [AC-MRS-07-UPGRADE] 提取策略链配置 -->
        <el-form-item label="提取策略链" prop="extract_strategies">
          <div class="strategy-chain-editor">
            <div class="strategy-chain-header">
              <span class="chain-hint">按优先级排序，系统将依次尝试直到成功</span>
              <el-button 
                v-if="formData.extract_strategies.length > 0"
                type="danger" 
                link 
                size="small"
                @click="clearStrategies"
              >
                清空
              </el-button>
            </div>
            
            <div v-if="formData.extract_strategies.length > 0" class="strategy-chain-list">
              <draggable 
                v-model="formData.extract_strategies" 
                :item-key="(item: ExtractStrategy) => item"
                handle=".drag-handle"
                class="strategy-list"
              >
                <template #item="{ element, index }">
                  <div class="strategy-item">
                    <el-icon class="drag-handle"><Rank /></el-icon>
                    <span class="strategy-order">{{ index + 1 }}</span>
                    <el-tag size="small" :type="getStrategyTagType(element)">
                      {{ getExtractStrategyLabel(element) }}
                    </el-tag>
                    <el-button 
                      type="danger" 
                      link 
                      size="small"
                      class="remove-btn"
                      @click="removeStrategy(index)"
                    >
                      <el-icon><Close /></el-icon>
                    </el-button>
                  </div>
                </template>
              </draggable>
            </div>
            
            <div v-else class="strategy-empty">
              <el-text type="info">暂无策略，请从下方添加</el-text>
            </div>
            
            <div class="strategy-add-section">
              <el-select 
                v-model="selectedStrategy" 
                placeholder="选择要添加的策略"
                style="width: 200px;"
                clearable
              >
                <el-option
                  v-for="opt in availableStrategies"
                  :key="opt.value"
                  :label="opt.label"
                  :value="opt.value as ExtractStrategy"
                  :disabled="isStrategySelected(opt.value as ExtractStrategy)"
                >
                  <div class="extract-option">
                    <span>{{ opt.label }}</span>
                    <span class="extract-desc">{{ opt.description }}</span>
                  </div>
                </el-option>
              </el-select>
              <el-button 
                type="primary" 
                :disabled="!selectedStrategy"
                @click="addStrategy"
              >
                <el-icon><Plus /></el-icon>
                添加
              </el-button>
            </div>
            
            <div v-if="strategyError" class="strategy-error">
              <el-text type="danger">{{ strategyError }}</el-text>
            </div>
          </div>
        </el-form-item>
        
        <el-form-item label="关联字段" prop="linked_field_id">
          <el-select
            v-model="formData.linked_field_id"
            style="width: 100%;"
            clearable
            filterable
            placeholder="选择关联的元数据字段"
          >
            <el-option
              v-for="field in slotFields"
              :key="field.id"
              :label="`${field.label} (${field.field_key})`"
              :value="field.id"
            >
              <div class="field-option">
                <span class="field-label">{{ field.label }}</span>
                <code class="field-key-small">{{ field.field_key }}</code>
              </div>
            </el-option>
          </el-select>
          <div class="field-hint">关联字段后，槽位值可同步到元数据字段</div>
        </el-form-item>
        <el-form-item label="校验规则" prop="validation_rule">
          <el-input
            v-model="formData.validation_rule"
            type="textarea"
            :rows="2"
            placeholder="正则表达式或 JSON Schema 格式"
          />
        </el-form-item>
        <el-form-item label="追问提示语" prop="ask_back_prompt">
          <el-input
            v-model="formData.ask_back_prompt"
            type="textarea"
            :rows="2"
            placeholder="当槽位缺失时，系统将使用此提示语追问用户"
          />
        </el-form-item>
        <el-form-item label="默认值" prop="default_value">
          <el-input v-model="formData.default_value" placeholder="可选默认值" />
        </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>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, watch, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Edit, Delete, Rank, Close } from '@element-plus/icons-vue'
import type { FormInstance, FormRules } from 'element-plus'
import draggable from 'vuedraggable'
import { slotDefinitionApi } from '@/api/slot-definition'
import { metadataSchemaApi } from '@/api/metadata-schema'
import {
  SLOT_TYPE_OPTIONS,
  EXTRACT_STRATEGY_OPTIONS,
  type SlotDefinition,
  type SlotDefinitionCreateRequest,
  type SlotDefinitionUpdateRequest,
  type SlotType,
  type ExtractStrategy,
  validateExtractStrategies,
  getEffectiveStrategies
} from '@/types/slot-definition'
import type { MetadataFieldDefinition } from '@/types/metadata'

const loading = ref(false)
const slots = ref<SlotDefinition[]>([])
const slotFields = ref<MetadataFieldDefinition[]>([])
const filterRequired = ref<boolean | undefined>(undefined)
const dialogVisible = ref(false)
const isEdit = ref(false)
const submitting = ref(false)
const formRef = ref<FormInstance>()

// [AC-MRS-07-UPGRADE] 策略链相关
const selectedStrategy = ref<ExtractStrategy | ''>('')
const strategyError = ref('')

const formData = reactive({
  id: '',
  slot_key: '',
  display_name: '',
  description: '',
  type: 'string' as SlotType,
  required: false,
  // [AC-MRS-07-UPGRADE] 使用策略链数组
  extract_strategies: [] as ExtractStrategy[],
  validation_rule: '',
  ask_back_prompt: '',
  default_value: '',
  linked_field_id: ''
})

const formRules: FormRules = {
  slot_key: [
    { required: true, message: '请输入槽位标识', trigger: 'blur' },
    { pattern: /^[a-z][a-z0-9_]*$/, message: '以小写字母开头，仅允许小写字母、数字、下划线', trigger: 'blur' }
  ],
  type: [{ required: true, message: '请选择槽位类型', trigger: 'change' }],
  required: [{ required: true, message: '请选择是否必填', trigger: 'change' }]
}

// [AC-MRS-07-UPGRADE] 计算可用策略（未选择的）
const availableStrategies = computed(() => {
  return EXTRACT_STRATEGY_OPTIONS
})

// [AC-MRS-07-UPGRADE] 检查策略是否已选择
const isStrategySelected = (strategy: ExtractStrategy) => {
  return formData.extract_strategies.includes(strategy)
}

// [AC-MRS-07-UPGRADE] 添加策略到链
const addStrategy = () => {
  if (!selectedStrategy.value) return
  
  if (isStrategySelected(selectedStrategy.value)) {
    strategyError.value = '该策略已存在于链中'
    return
  }
  
  formData.extract_strategies.push(selectedStrategy.value)
  selectedStrategy.value = ''
  strategyError.value = ''
}

// [AC-MRS-07-UPGRADE] 从链中移除策略
const removeStrategy = (index: number) => {
  formData.extract_strategies.splice(index, 1)
  strategyError.value = ''
}

// [AC-MRS-07-UPGRADE] 清空策略链
const clearStrategies = () => {
  formData.extract_strategies = []
  strategyError.value = ''
}

const getTypeLabel = (type: SlotType) => {
  return SLOT_TYPE_OPTIONS.find(o => o.value === type)?.label || type
}

const getExtractStrategyLabel = (strategy: ExtractStrategy) => {
  return EXTRACT_STRATEGY_OPTIONS.find(o => o.value === strategy)?.label || strategy
}

// [AC-MRS-07-UPGRADE] 获取策略标签类型
const getStrategyTagType = (strategy: ExtractStrategy): any => {
  const typeMap: Record<ExtractStrategy, any> = {
    'rule': 'success',
    'llm': 'warning',
    'user_input': 'info'
  }
  return typeMap[strategy] || 'info'
}

const fetchSlots = async () => {
  loading.value = true
  try {
    const res = await slotDefinitionApi.list(filterRequired.value)
    slots.value = res || []
  } catch (error: any) {
    ElMessage.error(error.response?.data?.message || '获取槽位定义失败')
  } finally {
    loading.value = false
  }
}

const fetchSlotFields = async () => {
  try {
    const res = await metadataSchemaApi.getByRole('slot', true)
    // 后端返回数组格式，兼容处理
    slotFields.value = Array.isArray(res) ? res : (res.items || [])
  } catch (error: any) {
    console.error('获取槽位角色字段失败', error)
  }
}

const handleCreate = () => {
  isEdit.value = false
  Object.assign(formData, {
    id: '',
    slot_key: '',
    display_name: '',
    description: '',
    type: 'string',
    required: false,
    // [AC-MRS-07-UPGRADE] 初始化为空数组
    extract_strategies: [],
    validation_rule: '',
    ask_back_prompt: '',
    default_value: '',
    linked_field_id: ''
  })
  selectedStrategy.value = ''
  strategyError.value = ''
  dialogVisible.value = true
}

const handleEdit = (slot: SlotDefinition) => {
  isEdit.value = true
  Object.assign(formData, {
    id: slot.id,
    slot_key: slot.slot_key,
    display_name: slot.display_name || '',
    description: slot.description || '',
    type: slot.type,
    required: slot.required,
    // [AC-MRS-07-UPGRADE] 使用有效的策略链
    extract_strategies: [...getEffectiveStrategies(slot)],
    validation_rule: slot.validation_rule || '',
    ask_back_prompt: slot.ask_back_prompt || '',
    default_value: slot.default_value ?? '',
    linked_field_id: slot.linked_field_id || ''
  })
  selectedStrategy.value = ''
  strategyError.value = ''
  dialogVisible.value = true
}

const handleDelete = async (slot: SlotDefinition) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除槽位「${slot.slot_key}」吗？[AC-MRS-16]`,
      '删除确认',
      { type: 'warning' }
    )
    await slotDefinitionApi.delete(slot.id)
    ElMessage.success('删除成功')
    fetchSlots()
  } catch (error: any) {
    if (error !== 'cancel') {
      ElMessage.error(error.response?.data?.message || '删除失败')
    }
  }
}

const handleSubmit = async () => {
  if (!formRef.value) return

  await formRef.value.validate(async (valid) => {
    if (!valid) return

    // [AC-MRS-07-UPGRADE] 校验策略链
    if (formData.extract_strategies.length > 0) {
      const validation = validateExtractStrategies(formData.extract_strategies)
      if (!validation.valid) {
        strategyError.value = validation.error || '策略链校验失败'
        return
      }
    }

    submitting.value = true
    try {
      const data: SlotDefinitionCreateRequest | SlotDefinitionUpdateRequest = {
        slot_key: formData.slot_key,
        display_name: formData.display_name || undefined,
        description: formData.description || undefined,
        type: formData.type,
        required: formData.required,
        // [AC-MRS-07-UPGRADE] 提交策略链
        extract_strategies: formData.extract_strategies.length > 0 ? formData.extract_strategies : undefined,
        validation_rule: formData.validation_rule || undefined,
        ask_back_prompt: formData.ask_back_prompt || undefined,
        linked_field_id: formData.linked_field_id || undefined
      }

      if (formData.default_value !== '') {
        data.default_value = formData.default_value
      }

      if (isEdit.value) {
        await slotDefinitionApi.update(formData.id, data as SlotDefinitionUpdateRequest)
        ElMessage.success('更新成功')
      } else {
        await slotDefinitionApi.create(data as SlotDefinitionCreateRequest)
        ElMessage.success('创建成功')
      }

      dialogVisible.value = false
      fetchSlots()
    } catch (error: any) {
      ElMessage.error(error.response?.data?.message || '操作失败')
    } finally {
      submitting.value = false
    }
  })
}

watch(filterRequired, () => {
  fetchSlots()
})

onMounted(() => {
  fetchSlots()
  fetchSlotFields()
})
</script>

<style scoped lang="scss">
.slot-definition-page {
  padding: 20px;
}

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

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

.title-section {
  .page-title {
    font-size: 24px;
    font-weight: 600;
    margin: 0 0 8px 0;
    color: var(--el-text-color-primary);
  }

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

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

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

.slot-key {
  padding: 2px 6px;
  background-color: var(--el-fill-color-light);
  border-radius: 4px;
  font-family: monospace;
  font-size: 12px;
}

.slot-key-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.display-name {
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

.slot-description {
  color: var(--el-text-color-regular);
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: block;
  max-width: 180px;
}

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

.linked-field {
  display: flex;
  align-items: center;
  gap: 8px;

  .linked-tag {
    margin-left: 4px;
  }
}

.ask-back-prompt {
  color: var(--el-text-color-regular);
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: block;
  max-width: 180px;
}

.field-hint {
  margin-top: 4px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

// [AC-MRS-07-UPGRADE] 策略链样式
.strategy-chain {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.strategy-tag {
  margin-right: 4px;
}

.strategy-chain-editor {
  border: 1px solid var(--el-border-color);
  border-radius: 4px;
  padding: 12px;
  background-color: var(--el-fill-color-light);
}

.strategy-chain-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.chain-hint {
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

.strategy-chain-list {
  margin-bottom: 16px;
}

.strategy-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.strategy-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background-color: var(--el-bg-color);
  border-radius: 4px;
  border: 1px solid var(--el-border-color-light);
}

.drag-handle {
  cursor: move;
  color: var(--el-text-color-secondary);
  font-size: 16px;
}

.strategy-order {
  width: 20px;
  text-align: center;
  font-weight: 600;
  color: var(--el-text-color-secondary);
}

.remove-btn {
  margin-left: auto;
}

.strategy-empty {
  text-align: center;
  padding: 20px;
  color: var(--el-text-color-secondary);
}

.strategy-add-section {
  display: flex;
  gap: 8px;
  align-items: center;
  padding-top: 12px;
  border-top: 1px dashed var(--el-border-color);
}

.strategy-error {
  margin-top: 8px;
}

.extract-option {
  display: flex;
  flex-direction: column;
  gap: 2px;

  .extract-desc {
    font-size: 12px;
    color: var(--el-text-color-secondary);
  }
}

.field-option {
  display: flex;
  align-items: center;
  gap: 8px;

  .field-label {
    font-weight: 500;
  }

  .field-key-small {
    font-size: 11px;
    padding: 1px 4px;
    background-color: var(--el-fill-color-light);
    border-radius: 3px;
    font-family: monospace;
  }
}
</style>
