<template>
  <div class="metadata-schema-page">
    <div class="page-header">
      <div class="header-content">
        <div class="title-section">
          <h1 class="page-title">元数据字段配置</h1>
          <p class="page-desc">配置知识库、意图规则、话术流程、Prompt模板的动态元数据字段。[AC-IDSMETA-13]</p>
        </div>
        <div class="header-actions">
          <el-select v-model="filterStatus" placeholder="按状态筛选" clearable style="width: 140px;">
            <el-option
              v-for="opt in METADATA_STATUS_OPTIONS"
              :key="opt.value"
              :label="opt.label"
              :value="opt.value"
            />
          </el-select>
          <el-select v-model="filterRole" placeholder="按角色筛选" clearable style="width: 140px;">
            <el-option
              v-for="opt in FIELD_ROLE_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="schema-card" v-loading="loading">
      <el-table :data="fields" stripe style="width: 100%">
        <el-table-column prop="field_key" label="字段标识" min-width="120">
          <template #default="{ row }">
            <code class="field-key">{{ row.field_key }}</code>
          </template>
        </el-table-column>
        <el-table-column prop="label" label="显示名称" width="120" />
        <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>
        <el-table-column prop="scope" label="适用范围" min-width="180">
          <template #default="{ row }">
            <div class="scope-tags">
              <el-tag
                v-for="s in row.scope"
                :key="s"
                size="small"
                class="scope-tag"
              >
                {{ getScopeLabel(s) }}
              </el-tag>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="field_roles" label="字段角色" min-width="200">
          <template #default="{ row }">
            <div class="role-tags">
              <el-tag
                v-for="role in row.field_roles"
                :key="role"
                :type="FIELD_ROLE_TAG_MAP[role as FieldRole]"
                size="small"
                class="role-tag"
              >
                {{ getRoleLabel(role) }}
              </el-tag>
              <span v-if="!row.field_roles || row.field_roles.length === 0" class="no-role">-</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="100">
          <template #default="{ row }">
            <el-tag :type="STATUS_TAG_MAP[row.status as MetadataFieldStatus]" size="small">
              {{ getStatusLabel(row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" link size="small" @click="handleEdit(row)">
              <el-icon><Edit /></el-icon>
              编辑
            </el-button>
            <el-dropdown trigger="click" @command="(cmd: MetadataFieldStatus) => handleStatusChange(row, cmd)">
              <el-button type="warning" link size="small">
                <el-icon><Switch /></el-icon>
                状态
                <el-icon class="el-icon--right"><ArrowDown /></el-icon>
              </el-button>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item
                    v-for="opt in METADATA_STATUS_OPTIONS"
                    :key="opt.value"
                    :command="opt.value"
                    :disabled="opt.value === row.status"
                  >
                    <el-tag :type="STATUS_TAG_MAP[opt.value as MetadataFieldStatus]" size="small">{{ opt.label }}</el-tag>
                    <span class="status-desc">{{ opt.description }}</span>
                  </el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
            <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 && fields.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="field_key">
              <el-input
                v-model="formData.field_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="label">
              <el-input v-model="formData.label" placeholder="如：年级" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="字段类型" prop="type">
              <el-select v-model="formData.type" style="width: 100%;" @change="onTypeChange">
                <el-option
                  v-for="opt in METADATA_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="status">
              <el-select v-model="formData.status" style="width: 100%;">
                <el-option
                  v-for="opt in METADATA_STATUS_OPTIONS"
                  :key="opt.value"
                  :label="opt.label"
                  :value="opt.value"
                >
                  <div class="status-option">
                    <el-tag :type="STATUS_TAG_MAP[opt.value as MetadataFieldStatus]" size="small">{{ opt.label }}</el-tag>
                    <span class="status-option-desc">{{ opt.description }}</span>
                  </div>
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="适用范围" prop="scope">
          <el-checkbox-group v-model="formData.scope">
            <el-checkbox
              v-for="opt in METADATA_SCOPE_OPTIONS"
              :key="opt.value"
              :value="opt.value"
            >
              {{ opt.label }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="字段角色">
          <FieldRolesSelector v-model="formData.field_roles" />
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="是否必填">
              <el-switch v-model="formData.required" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="可过滤">
              <el-switch v-model="formData.is_filterable" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="排序特征">
              <el-switch v-model="formData.is_rank_feature" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="用途说明">
          <el-input
            v-model="formData.usage_description"
            type="textarea"
            :rows="2"
            placeholder="描述该字段的业务用途和使用场景"
          />
        </el-form-item>
        <el-form-item label="默认值">
          <el-input v-model="formData.default_value" placeholder="可选默认值" />
        </el-form-item>
        <el-form-item
          v-if="formData.type === 'enum' || formData.type === 'array_enum'"
          label="选项列表"
          prop="options"
        >
          <div class="options-container">
            <el-tag
              v-for="(opt, idx) in formData.options"
              :key="idx"
              closable
              @close="removeOption(idx)"
              class="option-tag"
            >
              {{ opt }}
            </el-tag>
            <el-input
              v-model="newOption"
              placeholder="输入后回车添加"
              size="small"
              class="option-input"
              @keyup.enter="addOption"
            />
          </div>
        </el-form-item>

        <el-divider content-position="left" v-if="isEdit && formData.status === 'deprecated'">
          <el-tag type="danger">废弃影响范围</el-tag>
        </el-divider>
        <div v-if="isEdit && formData.status === 'deprecated'" class="deprecated-impact">
          <el-alert type="warning" :closable="false" show-icon>
            <template #title>
              将此字段设为废弃后，以下影响将生效 [AC-IDSMETA-14]
            </template>
          </el-alert>
          <ul class="impact-list">
            <li>新建对象时，此字段将不再显示</li>
            <li>已有对象的历史数据仍可查看，但不可编辑</li>
            <li>作为过滤条件时，仅对历史数据生效</li>
          </ul>
        </div>
      </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 } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Edit, Delete, Switch, ArrowDown } from '@element-plus/icons-vue'
import type { FormInstance, FormRules } from 'element-plus'
import { metadataSchemaApi } from '@/api/metadata-schema'
import FieldRolesSelector from '@/components/metadata/FieldRolesSelector.vue'
import {
  METADATA_STATUS_OPTIONS,
  METADATA_SCOPE_OPTIONS,
  METADATA_TYPE_OPTIONS,
  STATUS_TAG_MAP,
  FIELD_ROLE_OPTIONS,
  FIELD_ROLE_TAG_MAP,
  type MetadataFieldDefinition,
  type MetadataFieldCreateRequest,
  type MetadataFieldUpdateRequest,
  type MetadataFieldStatus,
  type MetadataScope,
  type FieldRole
} from '@/types/metadata'

const loading = ref(false)
const fields = ref<MetadataFieldDefinition[]>([])
const filterStatus = ref<MetadataFieldStatus | ''>('')
const filterRole = ref<FieldRole | ''>('')
const dialogVisible = ref(false)
const isEdit = ref(false)
const submitting = ref(false)
const formRef = ref<FormInstance>()
const newOption = ref('')

const formData = reactive({
  id: '',
  field_key: '',
  label: '',
  type: 'string' as 'string' | 'number' | 'boolean' | 'enum' | 'array_enum',
  required: false,
  options: [] as string[],
  default_value: '' as string | number | boolean,
  scope: [] as MetadataScope[],
  is_filterable: true,
  is_rank_feature: false,
  usage_description: '',
  field_roles: [] as FieldRole[],
  status: 'draft' as MetadataFieldStatus
})

const formRules: FormRules = {
  field_key: [
    { required: true, message: '请输入字段标识', trigger: 'blur' },
    { pattern: /^[a-z0-9_]+$/, message: '仅允许小写字母、数字、下划线', trigger: 'blur' }
  ],
  label: [{ required: true, message: '请输入显示名称', trigger: 'blur' }],
  type: [{ required: true, message: '请选择字段类型', trigger: 'change' }],
  status: [{ required: true, message: '请选择状态', trigger: 'change' }],
  scope: [{ type: 'array', min: 1, message: '请至少选择一个适用范围', trigger: 'change' }],
  options: [
    {
      validator: (_rule, value, callback) => {
        if ((formData.type === 'enum' || formData.type === 'array_enum') && (!value || value.length === 0)) {
          callback(new Error('枚举类型必须至少有一个选项'))
        } else {
          callback()
        }
      },
      trigger: 'change'
    }
  ]
}

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

const getStatusLabel = (status: MetadataFieldStatus) => {
  return METADATA_STATUS_OPTIONS.find(o => o.value === status)?.label || status
}

const getScopeLabel = (scope: MetadataScope) => {
  return METADATA_SCOPE_OPTIONS.find(o => o.value === scope)?.label || scope
}

const getRoleLabel = (role: FieldRole) => {
  return FIELD_ROLE_OPTIONS.find(o => o.value === role)?.label || role
}

const fetchFields = async () => {
  loading.value = true
  try {
    const res: any = await metadataSchemaApi.list(filterStatus.value || undefined, filterRole.value || undefined)
    // 兼容多种后端返回格式：[] / {items: []} / {schemas: []} / {data: []}
    fields.value = Array.isArray(res)
      ? res
      : (res?.items || res?.schemas || res?.data || [])
  } catch (error: any) {
    ElMessage.error(error.response?.data?.message || '获取元数据字段失败')
  } finally {
    loading.value = false
  }
}

const handleCreate = () => {
  isEdit.value = false
  Object.assign(formData, {
    id: '',
    field_key: '',
    label: '',
    type: 'string',
    required: false,
    options: [],
    default_value: '',
    scope: [],
    is_filterable: true,
    is_rank_feature: false,
    usage_description: '',
    field_roles: [],
    status: 'draft'
  })
  dialogVisible.value = true
}

const handleEdit = (field: MetadataFieldDefinition) => {
  isEdit.value = true
  Object.assign(formData, {
    id: field.id,
    field_key: field.field_key,
    label: field.label,
    type: field.type,
    required: field.required,
    options: field.options || [],
    default_value: field.default ?? '',
    scope: [...field.scope],
    is_filterable: field.is_filterable,
    is_rank_feature: field.is_rank_feature,
    usage_description: field.usage_description || '',
    field_roles: field.field_roles || [],
    status: field.status
  })
  dialogVisible.value = true
}

const handleDelete = async (field: MetadataFieldDefinition) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除字段「${field.label}(${field.field_key})」吗？`,
      '删除确认',
      { type: 'warning' }
    )
    await metadataSchemaApi.delete(field.id)
    ElMessage.success('删除成功')
    fetchFields()
  } catch (error: any) {
    if (error !== 'cancel') {
      ElMessage.error(error.response?.data?.message || '删除失败')
    }
  }
}

const handleStatusChange = async (field: MetadataFieldDefinition, newStatus: MetadataFieldStatus) => {
  if (newStatus === field.status) return

  const statusDesc = METADATA_STATUS_OPTIONS.find(o => o.value === newStatus)?.description
  try {
    await ElMessageBox.confirm(
      `确定要将字段「${field.label}」状态改为「${getStatusLabel(newStatus)}」吗？\n\n${statusDesc}`,
      '状态变更确认',
      { type: 'warning' }
    )
    await metadataSchemaApi.update(field.id, { status: newStatus })
    ElMessage.success('状态更新成功')
    fetchFields()
  } catch (error: any) {
    if (error !== 'cancel') {
      ElMessage.error(error.response?.data?.message || '状态更新失败')
    }
  }
}

const onTypeChange = () => {
  if (formData.type !== 'enum' && formData.type !== 'array_enum') {
    formData.options = []
  }
}

const addOption = () => {
  const value = newOption.value.trim()
  if (value && !formData.options.includes(value)) {
    formData.options.push(value)
    newOption.value = ''
  }
}

const removeOption = (index: number) => {
  formData.options.splice(index, 1)
}

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

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

    submitting.value = true
    try {
      const data: MetadataFieldCreateRequest | MetadataFieldUpdateRequest = {
        field_key: formData.field_key,
        label: formData.label,
        type: formData.type,
        required: formData.required,
        scope: formData.scope,
        is_filterable: formData.is_filterable,
        is_rank_feature: formData.is_rank_feature,
        usage_description: formData.usage_description || undefined,
        field_roles: formData.field_roles,
        status: formData.status
      }

      if (formData.type === 'enum' || formData.type === 'array_enum') {
        data.options = formData.options
      }

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

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

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

watch(filterStatus, () => {
  fetchFields()
})

watch(filterRole, () => {
  fetchFields()
})

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

<style scoped lang="scss">
.metadata-schema-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;
}

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

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

.scope-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.scope-tag {
  margin: 0;
}

.role-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.role-tag {
  margin: 0;
}

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

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

.status-desc {
  margin-left: 8px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

.status-option {
  display: flex;
  align-items: center;
}

.status-option-desc {
  margin-left: 8px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

.options-container {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;

  .option-tag {
    margin: 0;
  }

  .option-input {
    width: 150px;
  }
}

.deprecated-impact {
  margin-top: 16px;
  padding: 12px;
  background-color: var(--el-color-warning-light-9);
  border-radius: 6px;
}

.impact-list {
  margin: 12px 0 0 0;
  padding-left: 20px;
  color: var(--el-text-color-regular);
  font-size: 13px;

  li {
    margin-bottom: 4px;
  }
}
</style>
