<template>
  <div class="manage-page">
    <header class="manage-header">
      <div>
        <span class="header-kicker">CONFIGURATION CENTER</span>
        <h1>预警事项管理</h1>
        <p>维护预警编码、类型、等级、时长与处置环节，形成标准化预警清单。</p>
      </div>
      <el-button
        v-hasPermi="['warning:item:add']"
        type="primary"
        size="large"
        :icon="Plus"
        @click="openCreate"
      >
        新增预警事项
      </el-button>
    </header>

    <div class="workspace">
      <aside class="side-panel">
        <div class="side-title">快速筛选</div>
        <el-input v-model="query.itemName" :prefix-icon="Search" placeholder="事项名称 / 编码" clearable @keyup.enter="handleQuery" />
        <div class="filter-label">预警类型</div>
        <el-select v-model="query.warningType" placeholder="全部类型" clearable @change="handleQuery">
          <el-option v-for="item in warningTypes" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
        <div class="filter-label">预警级别</div>
        <div class="level-filter">
          <button
            v-for="item in warningLevels"
            :key="item.value"
            :class="{ active: query.warningLevel === item.value }"
            :style="{ '--level-color': item.color }"
            @click="toggleLevel(item.value)"
          >
            <span></span>{{ item.shortLabel }}
          </button>
        </div>
        <div class="filter-label">事项状态</div>
        <div class="status-filter">
          <button
            v-for="item in itemStatuses"
            :key="item.value"
            :class="{ active: query.status === item.value }"
            @click="toggleStatus(item.value)"
          >
            {{ item.label }}
          </button>
        </div>
        <el-button class="reset-button" :icon="Refresh" @click="resetQuery">清空筛选</el-button>
      </aside>

      <main class="main-panel">
        <el-card class="table-card" shadow="never">
          <template #header>
            <div class="table-heading">
              <div>
                <strong>事项配置清单</strong>
                <span>{{ total }} 条配置记录</span>
              </div>
              <el-button :icon="RefreshRight" circle @click="loadData" />
            </div>
          </template>
          <el-table v-loading="loading" :data="tableData" row-key="itemId">
            <el-table-column label="事项信息" min-width="270">
              <template #default="{ row }">
                <div class="item-cell">
                  <div class="item-mark" :style="{ background: levelMeta(row.warningLevel).color }"></div>
                  <div>
                    <strong>{{ row.itemName }}</strong>
                    <span>{{ row.itemCode }}</span>
                  </div>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="类型 / 专项" min-width="200">
              <template #default="{ row }">
                <div class="stack-cell">
                  <span>{{ typeLabel(row.warningType) }}</span>
                  <small>{{ row.warningSpecial || '通用专项' }}</small>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="级别" width="110">
              <template #default="{ row }">
                <el-tag :type="levelMeta(row.warningLevel).tagType">{{ levelMeta(row.warningLevel).shortLabel }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column label="响应时长" width="110">
              <template #default="{ row }"><strong>{{ row.duration || '-' }}</strong> 小时</template>
            </el-table-column>
            <el-table-column label="环节数" width="90">
              <template #default="{ row }">{{ parseLinkConfig(row.linkConfig).length }} 个</template>
            </el-table-column>
            <el-table-column label="状态" width="100">
              <template #default="{ row }">
                <el-tag :type="statusMeta(row.status).type" effect="light">{{ statusMeta(row.status).label }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="250" fixed="right">
              <template #default="{ row }">
                <el-button v-hasPermi="['warning:item:query']" link type="primary" :icon="View" @click="openPreview(row)">详情</el-button>
                <el-button v-hasPermi="['warning:item:edit']" link type="primary" :icon="Edit" @click="openEdit(row)">修改</el-button>
                <el-dropdown v-hasPermi="['warning:item:edit']" trigger="click" @command="command => changeStatus(row, command)">
                  <el-button link type="primary">状态<el-icon class="el-icon--right"><ArrowDown /></el-icon></el-button>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item command="ENABLED" :disabled="row.status === 'ENABLED'">启用</el-dropdown-item>
                      <el-dropdown-item command="DISABLED" :disabled="row.status === 'DISABLED'">禁用</el-dropdown-item>
                      <el-dropdown-item command="INVALID" :disabled="row.status === 'INVALID'" divided>作废</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </template>
            </el-table-column>
          </el-table>
          <el-empty v-if="!loading && !tableData.length" description="暂无预警事项配置" />
          <pagination
            v-show="total > 0"
            v-model:page="query.pageNum"
            v-model:limit="query.pageSize"
            :total="total"
            @pagination="loadData"
          />
        </el-card>
      </main>
    </div>

    <el-drawer
      v-model="editorVisible"
      :title="form.itemId ? '修改预警事项' : '新增预警事项'"
      size="720px"
      destroy-on-close
      class="editor-drawer"
    >
      <el-form ref="formRef" :model="form" :rules="rules" label-position="top" class="editor-form">
        <div class="form-section">
          <div class="form-section-title"><span>01</span> 基本信息</div>
          <el-row :gutter="16">
            <el-col :span="16">
              <el-form-item label="事项名称" prop="itemName">
                <el-input v-model="form.itemName" maxlength="100" show-word-limit placeholder="请输入清晰、可识别的事项名称" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="所属行业" prop="industry">
                <el-select v-model="form.industry" placeholder="请选择">
                  <el-option v-for="item in industryOptions" :key="item" :label="item" :value="item" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="16">
            <el-col :span="12">
              <el-form-item label="预警类型" prop="warningType">
                <el-select v-model="form.warningType" placeholder="请选择预警类型" @change="handleCodeDependencyChange">
                  <el-option v-for="item in warningTypes" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="预警级别" prop="warningLevel">
                <el-select v-model="form.warningLevel" placeholder="请选择预警级别" @change="handleCodeDependencyChange">
                  <el-option v-for="item in warningLevels" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="16">
            <el-col :span="14">
              <el-form-item label="事项编码" prop="itemCode">
                <el-input v-model="form.itemCode" placeholder="选择类型和等级后自动生成">
                  <template #append>
                    <el-button :icon="MagicStick" :loading="codeLoading" @click="generateCode">生成</el-button>
                  </template>
                </el-input>
              </el-form-item>
            </el-col>
            <el-col :span="10">
              <el-form-item label="预警专项" prop="warningSpecial">
                <el-input v-model="form.warningSpecial" placeholder="如：城市内涝专项" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="16">
            <el-col :span="12">
              <el-form-item label="预警时长（小时）" prop="duration">
                <el-input-number v-model="form.duration" :min="1" :max="720" controls-position="right" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="初始状态" prop="status">
                <el-radio-group v-model="form.status">
                  <el-radio-button label="ENABLED">启用</el-radio-button>
                  <el-radio-button label="DISABLED">禁用</el-radio-button>
                </el-radio-group>
              </el-form-item>
            </el-col>
          </el-row>
        </div>

        <div class="form-section">
          <div class="form-section-title">
            <div><span>02</span> 预警环节配置</div>
            <el-button link type="primary" :icon="Plus" @click="addLink">增加环节</el-button>
          </div>
          <div class="link-builder">
            <div v-for="(link, index) in form.links" :key="index" class="link-row">
              <div class="step-number">{{ String(index + 1).padStart(2, '0') }}</div>
              <div class="link-fields">
                <el-row :gutter="12">
                  <el-col :span="9"><el-input v-model="link.name" placeholder="环节名称" /></el-col>
                  <el-col :span="8"><el-input v-model="link.handler" placeholder="责任角色/部门" /></el-col>
                  <el-col :span="7">
                    <el-input-number v-model="link.timeLimit" :min="1" :max="1440" controls-position="right" />
                    <small>分钟</small>
                  </el-col>
                </el-row>
                <el-input v-model="link.description" type="textarea" :rows="2" placeholder="描述该环节的触发条件和处置要求" />
              </div>
              <el-button type="danger" link :icon="Delete" :disabled="form.links.length === 1" @click="removeLink(index)" />
            </div>
          </div>
        </div>

        <div class="form-section">
          <div class="form-section-title"><span>03</span> 补充说明</div>
          <el-form-item label="备注">
            <el-input v-model="form.remark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="填写适用范围、口径或其他说明" />
          </el-form-item>
        </div>
      </el-form>
      <template #footer>
        <el-button @click="editorVisible = false">取消</el-button>
        <el-button type="primary" :loading="saving" @click="submitForm">保存事项配置</el-button>
      </template>
    </el-drawer>

    <el-dialog v-model="previewVisible" title="预警事项详情" width="760px">
      <div class="preview-title">
        <div>
          <span>{{ preview.itemCode }}</span>
          <h3>{{ preview.itemName }}</h3>
        </div>
        <el-tag :type="statusMeta(preview.status).type">{{ statusMeta(preview.status).label }}</el-tag>
      </div>
      <el-descriptions :column="3" border>
        <el-descriptions-item label="预警类型">{{ typeLabel(preview.warningType) }}</el-descriptions-item>
        <el-descriptions-item label="预警级别">{{ levelMeta(preview.warningLevel).label }}</el-descriptions-item>
        <el-descriptions-item label="时长">{{ preview.duration || '-' }} 小时</el-descriptions-item>
        <el-descriptions-item label="预警专项">{{ preview.warningSpecial || '-' }}</el-descriptions-item>
        <el-descriptions-item label="所属行业">{{ preview.industry || '-' }}</el-descriptions-item>
        <el-descriptions-item label="更新时间">{{ preview.updateTime || preview.createTime || '-' }}</el-descriptions-item>
        <el-descriptions-item label="备注" :span="3">{{ preview.remark || '-' }}</el-descriptions-item>
      </el-descriptions>
      <div class="preview-links">
        <div v-for="(link, index) in parseLinkConfig(preview.linkConfig)" :key="index" class="preview-link">
          <span>{{ index + 1 }}</span>
          <div><strong>{{ link.name }}</strong><small>{{ link.handler }} · {{ link.timeLimit || '-' }} 分钟</small></div>
          <p>{{ link.description }}</p>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup name="WarningItemManage">
import { onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ArrowDown, Delete, Edit, MagicStick, Plus, Refresh, RefreshRight, Search, View } from '@element-plus/icons-vue'
import { getDicts } from '@/api/system/dict/data'
import {
  addWarningItem,
  generateWarningItemCode,
  getWarningItemDetail,
  listWarningItems,
  updateWarningItem,
  updateWarningItemStatus
} from '@/api/warning/list'
import {
  cloneDefaultLinks,
  fallbackWarningTypes,
  industryOptions,
  itemStatuses,
  levelMeta,
  normalizeWarningTypeDict,
  optionLabel,
  parseLinkConfig,
  statusMeta,
  warningLevels
} from '../shared'

const loading = ref(false)
const saving = ref(false)
const codeLoading = ref(false)
const editorVisible = ref(false)
const previewVisible = ref(false)
const formRef = ref()
const tableData = ref([])
const total = ref(0)
const warningTypes = ref(fallbackWarningTypes)
const preview = reactive({})
const query = reactive({ pageNum: 1, pageSize: 10, itemName: '', warningType: '', warningLevel: '', status: '' })
const form = reactive(createEmptyForm())
const rules = {
  itemName: [{ required: true, message: '请输入事项名称', trigger: 'blur' }],
  warningType: [{ required: true, message: '请选择预警类型', trigger: 'change' }],
  warningLevel: [{ required: true, message: '请选择预警级别', trigger: 'change' }],
  itemCode: [{ required: true, message: '请生成或填写事项编码', trigger: 'blur' }],
  industry: [{ required: true, message: '请选择所属行业', trigger: 'change' }],
  duration: [{ required: true, message: '请设置预警时长', trigger: 'change' }]
}

function createEmptyForm() {
  return {
    itemId: '',
    itemCode: '',
    itemName: '',
    warningType: '',
    warningLevel: '',
    warningSpecial: '',
    industry: '',
    duration: 24,
    status: 'ENABLED',
    remark: '',
    links: cloneDefaultLinks()
  }
}

function typeLabel(value) {
  return optionLabel(warningTypes.value, value)
}

async function loadTypes() {
  try {
    const res = await getDicts('warning_type')
    warningTypes.value = normalizeWarningTypeDict(res.data)
  } catch {
    warningTypes.value = fallbackWarningTypes
  }
}

async function loadData() {
  loading.value = true
  try {
    const params = { ...query }
    if (query.itemName && /^WI/i.test(query.itemName.trim())) {
      params.itemCode = query.itemName.trim()
      params.itemName = ''
    }
    const res = await listWarningItems(params)
    tableData.value = res.data?.records || []
    total.value = Number(res.data?.total || 0)
  } finally {
    loading.value = false
  }
}

function handleQuery() {
  query.pageNum = 1
  loadData()
}
function resetQuery() {
  Object.assign(query, { pageNum: 1, pageSize: 10, itemName: '', warningType: '', warningLevel: '', status: '' })
  loadData()
}
function toggleLevel(value) {
  query.warningLevel = query.warningLevel === value ? '' : value
  handleQuery()
}
function toggleStatus(value) {
  query.status = query.status === value ? '' : value
  handleQuery()
}
function resetForm(data = createEmptyForm()) {
  Object.keys(form).forEach(key => delete form[key])
  Object.assign(form, data)
}
function openCreate() {
  resetForm()
  editorVisible.value = true
}
async function openEdit(row) {
  const res = await getWarningItemDetail(row.itemId)
  const data = res.data || row
  resetForm({ ...data, links: parseLinkConfig(data.linkConfig).length ? parseLinkConfig(data.linkConfig) : cloneDefaultLinks() })
  editorVisible.value = true
}
async function openPreview(row) {
  const res = await getWarningItemDetail(row.itemId)
  Object.keys(preview).forEach(key => delete preview[key])
  Object.assign(preview, res.data || row)
  previewVisible.value = true
}
function handleCodeDependencyChange() {
  if (!form.itemId) form.itemCode = ''
}
async function generateCode() {
  if (!form.warningType || !form.warningLevel) {
    ElMessage.warning('请先选择预警类型和预警级别')
    return
  }
  codeLoading.value = true
  try {
    const res = await generateWarningItemCode(form.warningType, form.warningLevel)
    form.itemCode = res.data
  } finally {
    codeLoading.value = false
  }
}
function addLink() {
  form.links.push({ name: '', handler: '', timeLimit: 15, description: '' })
}
function removeLink(index) {
  form.links.splice(index, 1)
}
async function submitForm() {
  await formRef.value?.validate()
  if (form.links.some(item => !item.name || !item.handler || !item.timeLimit)) {
    ElMessage.warning('请完整填写每个预警环节的名称、责任方和时限')
    return
  }
  saving.value = true
  try {
    const { links, ...payload } = form
    payload.linkConfig = JSON.stringify(links)
    if (payload.itemId) {
      await updateWarningItem(payload)
      ElMessage.success('预警事项修改成功')
    } else {
      await addWarningItem(payload)
      ElMessage.success('预警事项新增成功')
    }
    editorVisible.value = false
    loadData()
  } finally {
    saving.value = false
  }
}
async function changeStatus(row, status) {
  const meta = statusMeta(status)
  await ElMessageBox.confirm(
    status === 'INVALID' ? '事项作废后将不再用于新预警，确认作废？' : `确认将该事项设置为“${meta.label}”？`,
    '状态变更确认',
    { type: status === 'INVALID' ? 'warning' : 'info' }
  )
  await updateWarningItemStatus(row.itemId, status)
  ElMessage.success('事项状态已更新')
  loadData()
}

onMounted(async () => {
  await loadTypes()
  loadData()
})
</script>

<style scoped lang="scss">
.manage-page {
  min-height: calc(100vh - 84px);
  padding: 20px;
  background: linear-gradient(180deg, #eef4fb 0, #f7f9fc 260px);
}
.manage-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 18px;
  padding: 26px 30px;
  color: #fff;
  border-radius: 18px;
  background: linear-gradient(120deg, #111d38, #173b72 58%, #2065a8);
  box-shadow: 0 14px 35px rgba(20, 50, 95, .2);
  h1 { margin: 5px 0 7px; font-size: 27px; }
  p { margin: 0; color: #b9cae1; }
}
.header-kicker { color: #65d4ff; font-size: 11px; letter-spacing: 2.6px; }
.workspace { display: grid; grid-template-columns: 230px minmax(0, 1fr); gap: 16px; }
.side-panel {
  align-self: start;
  padding: 20px;
  border: 1px solid #e1e8f1;
  border-radius: 16px;
  background: #fff;
  box-shadow: 0 8px 24px rgba(42, 67, 96, .06);
  :deep(.el-select) { width: 100%; }
}
.side-title { margin-bottom: 16px; color: #1e293b; font-size: 16px; font-weight: 700; }
.filter-label { margin: 20px 0 9px; color: #64748b; font-size: 12px; font-weight: 600; }
.level-filter {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  button {
    padding: 8px;
    color: #64748b;
    border: 1px solid #e5eaf1;
    border-radius: 8px;
    background: #fff;
    cursor: pointer;
    span { display: inline-block; width: 7px; height: 7px; margin-right: 5px; border-radius: 50%; background: var(--level-color); }
    &.active { color: var(--level-color); border-color: var(--level-color); background: color-mix(in srgb, var(--level-color) 7%, #fff); }
  }
}
.status-filter {
  display: flex;
  flex-direction: column;
  gap: 7px;
  button {
    padding: 9px 12px;
    color: #64748b;
    text-align: left;
    border: 0;
    border-radius: 8px;
    background: #f6f8fb;
    cursor: pointer;
    &.active { color: #1d5fd1; font-weight: 600; background: #eaf2ff; }
  }
}
.reset-button { width: 100%; margin-top: 20px; }
.table-card { border: 1px solid #e1e8f1; border-radius: 16px; }
.table-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  div { display: flex; flex-direction: column; gap: 3px; }
  strong { color: #1e293b; font-size: 16px; }
  span { color: #94a3b8; font-size: 12px; }
}
.table-card :deep(th.el-table__cell) { color: #52647a; background: #f7f9fc; }
.item-cell {
  display: flex;
  align-items: center;
  gap: 12px;
  .item-mark { width: 5px; height: 38px; border-radius: 8px; }
  div:last-child { display: flex; flex-direction: column; gap: 4px; }
  strong { color: #1f2d3d; }
  span { color: #8a98aa; font-family: Consolas, monospace; font-size: 12px; }
}
.stack-cell { display: flex; flex-direction: column; gap: 4px; color: #334155; small { color: #94a3b8; } }
.form-section {
  margin-bottom: 18px;
  padding: 20px;
  border: 1px solid #e5eaf1;
  border-radius: 14px;
  background: #fff;
}
.form-section-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 18px;
  color: #1e293b;
  font-weight: 700;
  > span, > div span {
    display: inline-grid;
    width: 28px;
    height: 28px;
    margin-right: 8px;
    color: #2563eb;
    font-size: 11px;
    border-radius: 8px;
    background: #eaf2ff;
    place-items: center;
  }
}
.editor-form :deep(.el-select), .editor-form :deep(.el-input-number) { width: 100%; }
.link-builder { display: flex; flex-direction: column; gap: 12px; }
.link-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px;
  border: 1px solid #e7ebf1;
  border-radius: 12px;
  background: #f8fafc;
}
.step-number {
  display: grid;
  flex: 0 0 34px;
  width: 34px;
  height: 34px;
  color: #fff;
  font-size: 12px;
  border-radius: 10px;
  background: #255fc1;
  place-items: center;
}
.link-fields {
  flex: 1;
  :deep(.el-textarea) { margin-top: 10px; }
  .el-col:last-child { display: flex; align-items: center; gap: 6px; small { color: #94a3b8; } }
}
.preview-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  padding: 18px;
  border-radius: 12px;
  background: linear-gradient(110deg, #eaf2ff, #f7fbff);
  span { color: #5f78a0; font: 12px Consolas, monospace; }
  h3 { margin: 5px 0 0; color: #1d3557; }
}
.preview-links {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin-top: 18px;
}
.preview-link {
  display: grid;
  grid-template-columns: 30px 1fr;
  gap: 8px;
  padding: 13px;
  border: 1px solid #e6ebf2;
  border-radius: 10px;
  > span { display: grid; width: 28px; height: 28px; color: #2563eb; border-radius: 8px; background: #edf4ff; place-items: center; }
  div { display: flex; flex-direction: column; gap: 3px; }
  small { color: #8a98aa; }
  p { grid-column: 2; margin: 3px 0 0; color: #64748b; line-height: 1.5; }
}
@media (max-width: 900px) {
  .workspace { grid-template-columns: 1fr; }
  .manage-header { align-items: flex-start; gap: 16px; }
}
</style>
