<template>
  <div class="reason-page">
    <section class="reason-hero">
      <div class="hero-copy">
        <span>KNOWLEDGE LIBRARY</span>
        <h1>预警原因库管理</h1>
        <p>按“预警类型 + 等级”沉淀标准原因，提升处置人员选择效率和后续分析数据质量。</p>
      </div>
      <div class="hero-visual">
        <div class="visual-ring"><el-icon><CollectionTag /></el-icon></div>
        <div class="visual-stat"><strong>{{ total }}</strong><span>原因条目</span></div>
      </div>
    </section>

    <el-card class="reason-card" shadow="never">
      <div class="toolbar">
        <el-form :model="query" :inline="true">
          <el-form-item>
            <el-input v-model="query.reasonCode" :prefix-icon="Search" placeholder="原因编码" clearable @keyup.enter="handleQuery" />
          </el-form-item>
          <el-form-item>
            <el-input v-model="query.reasonName" placeholder="原因名称" clearable @keyup.enter="handleQuery" />
          </el-form-item>
          <el-form-item>
            <el-select v-model="query.warningType" placeholder="预警类型" clearable>
              <el-option v-for="item in warningTypes" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-select v-model="query.warningLevel" placeholder="预警级别" clearable>
              <el-option v-for="item in warningLevels" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-select v-model="query.status" placeholder="使用状态" clearable>
              <el-option label="正常使用" value="0" />
              <el-option label="已停用" value="1" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" :icon="Search" @click="handleQuery">查询</el-button>
            <el-button :icon="Refresh" @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-form>
        <el-button v-hasPermi="['warning:reason:add']" type="primary" :icon="Plus" @click="openCreate">新增原因</el-button>
      </div>

      <div class="library-layout">
        <aside class="category-panel">
          <button :class="{ active: !query.warningType }" @click="selectType('')">
            <span class="category-icon all"><el-icon><Grid /></el-icon></span>
            <div><strong>全部类型</strong><small>查看完整原因库</small></div>
          </button>
          <button
            v-for="item in warningTypes"
            :key="item.value"
            :class="{ active: query.warningType === item.value }"
            @click="selectType(item.value)"
          >
            <span class="category-icon"><el-icon><Warning /></el-icon></span>
            <div><strong>{{ item.label }}</strong><small>{{ item.value }}</small></div>
          </button>
        </aside>

        <main class="reason-list">
          <div v-loading="loading" class="reason-grid">
            <article v-for="row in tableData" :key="row.reasonId" class="reason-item" :class="{ disabled: row.status === '1' }">
              <div class="reason-top">
                <span class="reason-code">{{ row.reasonCode }}</span>
                <el-switch
                  v-hasPermi="['warning:reason:edit']"
                  :model-value="row.status === '0'"
                  inline-prompt
                  active-text="启"
                  inactive-text="停"
                  @change="value => changeStatus(row, value)"
                />
              </div>
              <h3>{{ row.reasonName }}</h3>
              <p>{{ row.description || '暂无原因描述' }}</p>
              <div class="reason-tags">
                <el-tag effect="plain">{{ typeLabel(row.warningType) }}</el-tag>
                <el-tag :type="levelMeta(row.warningLevel).tagType" effect="light">{{ levelMeta(row.warningLevel).shortLabel }}预警</el-tag>
                <span>排序 {{ row.sortOrder ?? 0 }}</span>
              </div>
              <div class="reason-actions">
                <span>{{ row.updateTime || row.createTime || '-' }}</span>
                <div>
                  <el-button v-hasPermi="['warning:reason:query']" link type="primary" @click="openDetail(row)">详情</el-button>
                  <el-button v-hasPermi="['warning:reason:edit']" link type="primary" @click="openEdit(row)">修改</el-button>
                </div>
              </div>
            </article>
          </div>
          <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"
          />
        </main>
      </div>
    </el-card>

    <el-dialog v-model="editorVisible" :title="form.reasonId ? '修改预警原因' : '新增预警原因'" width="620px" destroy-on-close>
      <el-form ref="formRef" :model="form" :rules="rules" label-position="top">
        <el-row :gutter="16">
          <el-col :span="12">
            <el-form-item label="预警类型" prop="warningType">
              <el-select v-model="form.warningType" placeholder="请选择">
                <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="请选择">
                <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="16">
            <el-form-item label="原因名称" prop="reasonName">
              <el-input v-model="form.reasonName" maxlength="100" show-word-limit placeholder="请输入简明、可直接选择的原因名称" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="显示排序" prop="sortOrder">
              <el-input-number v-model="form.sortOrder" :min="0" :max="999" controls-position="right" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="原因编码">
          <el-input v-model="form.reasonCode" placeholder="留空时后端自动生成" />
        </el-form-item>
        <el-form-item label="原因描述" prop="description">
          <el-input v-model="form.description" type="textarea" :rows="5" maxlength="500" show-word-limit placeholder="描述判断依据、典型场景或处置提示" />
        </el-form-item>
        <el-form-item label="使用状态">
          <el-radio-group v-model="form.status">
            <el-radio-button label="0">正常使用</el-radio-button>
            <el-radio-button label="1">停用</el-radio-button>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="editorVisible = false">取消</el-button>
        <el-button type="primary" :loading="saving" @click="submitForm">保存原因</el-button>
      </template>
    </el-dialog>

    <el-drawer v-model="detailVisible" title="原因详情" size="480px">
      <div class="reason-detail">
        <span>{{ detail.reasonCode }}</span>
        <h2>{{ detail.reasonName }}</h2>
        <div class="detail-badges">
          <el-tag>{{ typeLabel(detail.warningType) }}</el-tag>
          <el-tag :type="levelMeta(detail.warningLevel).tagType">{{ levelMeta(detail.warningLevel).label }}</el-tag>
        </div>
        <div class="detail-description">{{ detail.description || '暂无原因描述' }}</div>
        <el-descriptions :column="1" border>
          <el-descriptions-item label="使用状态">{{ detail.status === '0' ? '正常使用' : '已停用' }}</el-descriptions-item>
          <el-descriptions-item label="显示排序">{{ detail.sortOrder ?? 0 }}</el-descriptions-item>
          <el-descriptions-item label="创建时间">{{ detail.createTime || '-' }}</el-descriptions-item>
          <el-descriptions-item label="更新时间">{{ detail.updateTime || '-' }}</el-descriptions-item>
        </el-descriptions>
      </div>
    </el-drawer>
  </div>
</template>

<script setup name="WarningReasonManage">
import { onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { CollectionTag, Grid, Plus, Refresh, Search, Warning } from '@element-plus/icons-vue'
import { getDicts } from '@/api/system/dict/data'
import {
  addWarningReason,
  getWarningReasonDetail,
  listWarningReasons,
  updateWarningReason,
  updateWarningReasonStatus
} from '@/api/warning/list'
import {
  fallbackWarningTypes,
  levelMeta,
  normalizeWarningTypeDict,
  optionLabel,
  warningLevels
} from '../shared'

const loading = ref(false)
const saving = ref(false)
const editorVisible = ref(false)
const detailVisible = ref(false)
const formRef = ref()
const tableData = ref([])
const total = ref(0)
const warningTypes = ref(fallbackWarningTypes)
const detail = reactive({})
const query = reactive({
  pageNum: 1,
  pageSize: 10,
  reasonCode: '',
  reasonName: '',
  warningType: '',
  warningLevel: '',
  status: ''
})
const form = reactive(emptyForm())
const rules = {
  warningType: [{ required: true, message: '请选择预警类型', trigger: 'change' }],
  warningLevel: [{ required: true, message: '请选择预警级别', trigger: 'change' }],
  reasonName: [{ required: true, message: '请输入原因名称', trigger: 'blur' }],
  description: [{ required: true, message: '请输入原因描述', trigger: 'blur' }]
}

function emptyForm() {
  return { reasonId: '', reasonCode: '', reasonName: '', warningType: '', warningLevel: '', description: '', sortOrder: 0, status: '0' }
}
function typeLabel(value) {
  return optionLabel(warningTypes.value, value)
}
function resetForm(data = emptyForm()) {
  Object.keys(form).forEach(key => delete form[key])
  Object.assign(form, data)
}
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 res = await listWarningReasons(query)
    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, reasonCode: '', reasonName: '', warningType: '', warningLevel: '', status: '' })
  loadData()
}
function selectType(value) {
  query.warningType = value
  handleQuery()
}
function openCreate() {
  resetForm({ ...emptyForm(), warningType: query.warningType, warningLevel: query.warningLevel })
  editorVisible.value = true
}
async function openEdit(row) {
  const res = await getWarningReasonDetail(row.reasonId)
  resetForm(res.data || row)
  editorVisible.value = true
}
async function openDetail(row) {
  const res = await getWarningReasonDetail(row.reasonId)
  Object.keys(detail).forEach(key => delete detail[key])
  Object.assign(detail, res.data || row)
  detailVisible.value = true
}
async function submitForm() {
  await formRef.value?.validate()
  saving.value = true
  try {
    if (form.reasonId) {
      await updateWarningReason(form)
      ElMessage.success('预警原因修改成功')
    } else {
      await addWarningReason(form)
      ElMessage.success('预警原因新增成功')
    }
    editorVisible.value = false
    loadData()
  } finally {
    saving.value = false
  }
}
async function changeStatus(row, enabled) {
  const status = enabled ? '0' : '1'
  try {
    await ElMessageBox.confirm(`确认${enabled ? '启用' : '停用'}原因“${row.reasonName}”？`, '状态变更', { type: 'warning' })
    await updateWarningReasonStatus(row.reasonId, status)
    ElMessage.success('原因状态已更新')
    loadData()
  } catch {
    // 取消操作时恢复由数据源控制的开关状态
  }
}

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

<style scoped lang="scss">
.reason-page {
  min-height: calc(100vh - 84px);
  padding: 20px;
  background:
    radial-gradient(circle at 10% 10%, rgba(14, 165, 233, .08), transparent 25%),
    #f4f7fb;
}
.reason-hero {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  padding: 26px 32px;
  color: #fff;
  border-radius: 18px;
  background: linear-gradient(120deg, #12354f, #0c6175 58%, #0e8b91);
  box-shadow: 0 15px 40px rgba(10, 86, 104, .2);
}
.hero-copy {
  span { color: #7ee7df; font-size: 11px; letter-spacing: 3px; }
  h1 { margin: 6px 0 8px; font-size: 27px; }
  p { margin: 0; color: rgba(255, 255, 255, .75); }
}
.hero-visual { display: flex; align-items: center; gap: 15px; }
.visual-ring {
  display: grid;
  width: 62px;
  height: 62px;
  font-size: 27px;
  border: 1px solid rgba(255, 255, 255, .2);
  border-radius: 50%;
  background: rgba(255, 255, 255, .1);
  place-items: center;
}
.visual-stat { display: flex; flex-direction: column; strong { font-size: 25px; } span { color: #b8dce1; font-size: 12px; } }
.reason-card { border: 1px solid #e2e8f0; border-radius: 16px; }
.toolbar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 16px;
  border-bottom: 1px solid #edf0f4;
  :deep(.el-form-item) { margin-bottom: 0; }
  :deep(.el-select) { width: 145px; }
}
.library-layout { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 18px; margin-top: 18px; }
.category-panel {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding-right: 16px;
  border-right: 1px solid #edf0f4;
  button {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px;
    text-align: left;
    border: 0;
    border-radius: 10px;
    background: transparent;
    cursor: pointer;
    &:hover { background: #f4f8fb; }
    &.active { background: #eaf8f8; }
    div { display: flex; min-width: 0; flex-direction: column; gap: 3px; }
    strong { overflow: hidden; color: #334155; font-size: 13px; text-overflow: ellipsis; white-space: nowrap; }
    small { overflow: hidden; color: #94a3b8; font-size: 10px; text-overflow: ellipsis; white-space: nowrap; }
  }
}
.category-icon {
  display: grid;
  flex: 0 0 34px;
  width: 34px;
  height: 34px;
  color: #0f8890;
  border-radius: 9px;
  background: #e5f5f5;
  place-items: center;
  &.all { color: #2563eb; background: #eaf2ff; }
}
.reason-grid { display: grid; min-height: 300px; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.reason-item {
  position: relative;
  display: flex;
  min-height: 210px;
  flex-direction: column;
  padding: 16px;
  border: 1px solid #e4eaf0;
  border-radius: 13px;
  background: linear-gradient(150deg, #fff, #fbfcfd);
  transition: .2s ease;
  &:hover { transform: translateY(-2px); border-color: #9fd2d4; box-shadow: 0 10px 25px rgba(30, 80, 92, .09); }
  &.disabled { opacity: .65; filter: grayscale(.25); }
  h3 { margin: 12px 0 7px; color: #23364d; font-size: 16px; }
  > p { display: -webkit-box; overflow: hidden; margin: 0; color: #718096; line-height: 1.65; -webkit-box-orient: vertical; -webkit-line-clamp: 3; }
}
.reason-top { display: flex; align-items: center; justify-content: space-between; }
.reason-code { color: #0c7c83; font: 11px Consolas, monospace; letter-spacing: .4px; }
.reason-tags { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: auto; padding-top: 12px; > span:last-child { margin-left: auto; color: #94a3b8; font-size: 11px; } }
.reason-actions { display: flex; align-items: center; justify-content: space-between; margin-top: 13px; padding-top: 10px; border-top: 1px dashed #e5eaf0; > span { color: #a0aaba; font-size: 10px; } }
.reason-detail {
  > span { color: #0c7c83; font: 12px Consolas, monospace; }
  h2 { margin: 8px 0 14px; color: #203047; }
}
.detail-badges { display: flex; gap: 8px; }
.detail-description { margin: 20px 0; padding: 16px; color: #526477; line-height: 1.8; border-left: 4px solid #14a3a8; border-radius: 8px; background: #f1fafa; }
:deep(.el-dialog .el-select), :deep(.el-dialog .el-input-number) { width: 100%; }
@media (max-width: 1250px) { .reason-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 900px) {
  .toolbar { flex-direction: column; }
  .library-layout { grid-template-columns: 1fr; }
  .category-panel { display: grid; grid-template-columns: repeat(2, 1fr); padding-right: 0; border-right: 0; }
}
</style>
