<template>
  <div class="hazard-container">
    <el-card class="search-card">
      <el-form :inline="true" :model="searchForm">
        <el-form-item label="隐患类型">
          <el-select v-model="searchForm.hazardType" placeholder="请选择" clearable style="width:140px">
            <el-option v-for="d in hazardTypeDict" :key="d.dictValue" :label="d.dictLabel" :value="d.dictValue" />
          </el-select>
        </el-form-item>
        <el-form-item label="隐患等级">
          <el-select v-model="searchForm.hazardLevel" placeholder="请选择" clearable style="width:140px">
            <el-option v-for="d in hazardLevelDict" :key="d.dictValue" :label="d.dictLabel" :value="d.dictValue" />
          </el-select>
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="searchForm.hazardStatus" placeholder="请选择" clearable style="width:140px">
            <el-option v-for="d in hazardStatusDict" :key="d.dictValue" :label="d.dictLabel" :value="d.dictValue" />
          </el-select>
        </el-form-item>
        <el-form-item label="报送状态">
          <el-select v-model="searchForm.isSubmitted" placeholder="请选择" clearable style="width:140px">
            <el-option label="未报送" :value="0" />
            <el-option label="已报送" :value="1" />
          </el-select>
        </el-form-item>
        <el-form-item label="关联管网">
          <el-select v-model="searchForm.networkId" placeholder="请选择" clearable style="width:160px">
            <el-option v-for="n in networkOptions" :key="n.networkId" :label="n.networkName" :value="n.networkId" />
          </el-select>
        </el-form-item>
        <el-form-item label="关联设备">
          <el-select v-model="searchForm.equipmentId" placeholder="请选择" clearable style="width:160px">
            <el-option v-for="e in equipmentOptions" :key="e.equipmentId" :label="e.equipmentName" :value="e.equipmentId" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">查询</el-button>
          <el-button @click="handleReset">重置</el-button>
          <el-button type="success" @click="handleAdd">新增</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card class="table-card">
      <el-table :data="tableData" border stripe v-loading="loading">
        <el-table-column prop="hazardNo" label="隐患编号" width="120" />
        <el-table-column prop="hazardType" label="隐患类型" width="100">
          <template #default="{ row }">{{ getDictLabel(hazardTypeDict, row.hazardType) }}</template>
        </el-table-column>
        <el-table-column prop="hazardLevel" label="隐患等级" width="90">
          <template #default="{ row }">
            <el-tag :type="levelTag(row.hazardLevel)">{{ getDictLabel(hazardLevelDict, row.hazardLevel) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="hazardDesc" label="隐患描述" min-width="180" show-overflow-tooltip />
        <el-table-column prop="hazardSource" label="隐患来源" width="100">
          <template #default="{ row }">{{ getDictLabel(hazardSourceDict, row.hazardSource) }}</template>
        </el-table-column>
        <el-table-column prop="hazardStatus" label="状态" width="90">
          <template #default="{ row }">
            <el-tag :type="statusTag(row.hazardStatus)">{{ getDictLabel(hazardStatusDict, row.hazardStatus) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="隐患图片" width="90">
          <template #default="{ row }">
            <template v-if="parseImageUrls(row.hazardImages).length">
              <el-image
                :src="parseImageUrls(row.hazardImages)[0]"
                fit="cover"
                :preview-src-list="parseImageUrls(row.hazardImages)"
                preview-teleported
                hide-on-click-modal
                class="table-image"
              />
            </template>
            <el-tag v-else type="info" size="small">无</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="关联管网" width="140">
          <template #default="{ row }">{{ getNetworkName(row.networkId) }}</template>
        </el-table-column>
        <el-table-column label="关联设备" width="140">
          <template #default="{ row }">{{ getEquipmentName(row.equipmentId) }}</template>
        </el-table-column>
        <el-table-column prop="reportUnit" label="上报单位" width="120" />
        <el-table-column prop="reportTime" label="上报时间" width="160" />
        <el-table-column label="操作" width="350" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" size="small" @click="handleEdit(row)">编辑</el-button>
            <el-button type="info" size="small" @click="handleDetail(row)">详情</el-button>
            <el-button type="success" size="small" @click="handleSubmitHazard(row)" :disabled="row.isSubmitted === 1">
              {{ row.isSubmitted === 1 ? '已报送' : '报送并生成工单' }}
            </el-button>
            <el-button type="danger" size="small" @click="handleDelete(row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        v-model:current-page="pageNum" v-model:page-size="pageSize" :total="total"
        layout="total, prev, pager, next, sizes" :page-sizes="[10, 20, 50]"
        @change="loadData" style="margin-top: 16px; justify-content: flex-end"
      />
    </el-card>

    <!-- 新增/编辑对话框 -->
    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="750px" destroy-on-close>
      <el-form :model="formData" ref="formRef" label-width="100px" :rules="rules">
        <el-row :gutter="16">
          <el-col :span="12">
            <el-form-item label="隐患编号" prop="hazardNo">
              <el-input v-model="formData.hazardNo" placeholder="保存时自动生成" readonly />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="隐患类型" prop="hazardType">
              <el-select v-model="formData.hazardType" style="width: 100%">
                <el-option v-for="d in hazardTypeDict" :key="d.dictValue" :label="d.dictLabel" :value="d.dictValue" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="隐患等级" prop="hazardLevel">
              <el-select v-model="formData.hazardLevel" style="width: 100%">
                <el-option v-for="d in hazardLevelDict" :key="d.dictValue" :label="d.dictLabel" :value="d.dictValue" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="隐患来源" prop="hazardSource">
              <el-select v-model="formData.hazardSource" style="width: 100%" placeholder="请选择隐患来源">
                <el-option v-for="d in hazardSourceDict" :key="d.dictValue" :label="d.dictLabel" :value="d.dictValue" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="关联管网">
              <el-select v-model="formData.networkId" placeholder="请选择" clearable style="width: 100%">
                <el-option v-for="n in networkOptions" :key="n.networkId" :label="n.networkName" :value="n.networkId" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="关联设备" prop="equipmentId">
              <el-select v-model="formData.equipmentId" placeholder="请选择" clearable style="width: 100%">
                <el-option v-for="e in equipmentOptions" :key="e.equipmentId" :label="e.equipmentName" :value="e.equipmentId" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="上报单位">
              <el-input v-model="formData.reportUnit" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="上报时间" prop="reportTime">
              <el-date-picker v-model="formData.reportTime" type="datetime" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" placeholder="请选择上报时间" />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="隐患描述" prop="hazardDesc">
              <el-input v-model="formData.hazardDesc" type="textarea" :rows="3" placeholder="请输入隐患描述" />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="整改方案">
              <el-input v-model="formData.rectifyPlan" type="textarea" :rows="3" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="整改期限">
              <el-date-picker v-model="formData.rectifyDeadline" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="整改责任人">
              <el-input v-model="formData.rectifyPerson" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="经度">
              <el-input-number v-model="formData.longitude" :precision="10" style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="纬度">
              <el-input-number v-model="formData.latitude" :precision="10" style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="隐患图片">
              <el-upload
                action="#"
                :auto-upload="false"
                :show-file-list="false"
                :http-request="() => {}"
                :on-change="handleImageChange"
                accept="image/jpeg,image/png,image/jpg"
                multiple
              >
                <el-button type="primary" plain :loading="imageUploading">
                  {{ imageUploading ? '上传中...' : '选择图片' }}
                </el-button>
                <template #tip>
                  <div class="el-upload__tip">支持 JPG/PNG 格式，单张不超过 5MB，可多选</div>
                </template>
              </el-upload>
              <div v-if="imageList.length" class="image-list">
                <div v-for="(img, index) in imageList" :key="index" class="image-item">
                  <img :src="img" class="image-thumb" @click="previewImage(index)" />
                  <el-icon class="image-remove" @click="removeImage(index)"><Close /></el-icon>
                </div>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSave">确定</el-button>
      </template>
    </el-dialog>

    <!-- 详情对话框 -->
    <el-dialog title="隐患详情" v-model="detailVisible" width="900px">
      <el-descriptions v-if="detailData" :column="2" border>
        <el-descriptions-item label="隐患编号">{{ detailData.hazardNo }}</el-descriptions-item>
        <el-descriptions-item label="隐患类型">{{ getDictLabel(hazardTypeDict, detailData.hazardType) }}</el-descriptions-item>
        <el-descriptions-item label="隐患等级">
          <el-tag :type="levelTag(detailData.hazardLevel)">{{ getDictLabel(hazardLevelDict, detailData.hazardLevel) }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="隐患来源">{{ getDictLabel(hazardSourceDict, detailData.hazardSource) }}</el-descriptions-item>
        <el-descriptions-item label="状态">
          <el-tag :type="statusTag(detailData.hazardStatus)">{{ getDictLabel(hazardStatusDict, detailData.hazardStatus) }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="报送状态">
          <el-tag :type="detailData.isSubmitted === 1 ? 'success' : 'info'">{{ detailData.isSubmitted === 1 ? '已报送' : '未报送' }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="关联管网">{{ getNetworkName(detailData.networkId) }}</el-descriptions-item>
        <el-descriptions-item label="关联设备">{{ getEquipmentName(detailData.equipmentId) }}</el-descriptions-item>
        <el-descriptions-item label="上报单位">{{ detailData.reportUnit || '-' }}</el-descriptions-item>
        <el-descriptions-item label="上报时间">{{ detailData.reportTime || '-' }}</el-descriptions-item>
        <el-descriptions-item label="隐患描述" :span="2">{{ detailData.hazardDesc || '-' }}</el-descriptions-item>
        <el-descriptions-item label="整改方案" :span="2">{{ detailData.rectifyPlan || '-' }}</el-descriptions-item>
        <el-descriptions-item label="整改期限">{{ detailData.rectifyDeadline || '-' }}</el-descriptions-item>
        <el-descriptions-item label="整改责任人">{{ detailData.rectifyPerson || '-' }}</el-descriptions-item>
        <el-descriptions-item label="经度">{{ detailData.longitude || '-' }}</el-descriptions-item>
        <el-descriptions-item label="纬度">{{ detailData.latitude || '-' }}</el-descriptions-item>
        <el-descriptions-item label="隐患图片" :span="2">
          <div v-if="parseImageUrls(detailData.hazardImages).length" class="detail-image-list">
            <el-image
              v-for="(img, index) in parseImageUrls(detailData.hazardImages)"
              :key="index"
              :src="img"
              fit="cover"
              :preview-src-list="parseImageUrls(detailData.hazardImages)"
              :initial-index="index"
              preview-teleported
              hide-on-click-modal
              class="detail-image"
            />
          </div>
          <span v-else>-</span>
        </el-descriptions-item>
        <el-descriptions-item label="备注" :span="2">{{ detailData.remark || '-' }}</el-descriptions-item>
      </el-descriptions>
    </el-dialog>

    <!-- 图片预览 -->
    <el-image-viewer
      v-if="previewVisible"
      :url-list="previewList"
      :initial-index="previewIndex"
      hide-on-click-modal
      @close="previewVisible = false"
    />
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Close } from '@element-plus/icons-vue'
import request from '@/utils/request'
import { getHazardPage, getHazardById, addHazard, updateHazard, deleteHazard, submitHazard } from '@/api/pipeNetwork/hazard'
import { getDicts } from '@/api/system/dict/data'
import { getPipeNetworkOptions, getEquipmentByTopLevelType } from '@/api/pipeNetwork/basic'

const loading = ref(false)
const tableData = ref([])
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref(0)
const searchForm = reactive({ hazardType: '', hazardLevel: '', hazardStatus: '', isSubmitted: null, networkId: '', equipmentId: '' })
const dialogVisible = ref(false)
const dialogTitle = ref('新增')
const formRef = ref(null)

// 表单校验规则
const rules = {
  hazardType: [{ required: true, message: '请选择隐患类型', trigger: 'change' }],
  hazardLevel: [{ required: true, message: '请选择隐患等级', trigger: 'change' }],
  hazardSource: [{ required: true, message: '请选择隐患来源', trigger: 'change' }],
  equipmentId: [{ required: true, message: '请选择关联设备', trigger: 'change' }],
  reportTime: [{ required: true, message: '请选择上报时间', trigger: 'change' }],
  hazardDesc: [{ required: true, message: '请输入隐患描述', trigger: 'blur' }]
}

const formData = reactive({
  hazardId: '', hazardNo: '', hazardType: '', hazardLevel: '', hazardDesc: '',
  hazardSource: '', hazardStatus: '待核查', reportUnit: '', reportTime: '',
  rectifyPlan: '', rectifyDeadline: '', rectifyPerson: '',
  networkId: '', equipmentId: '', longitude: null, latitude: null,
  hazardImages: ''
})

const hazardTypeDict = ref([])
const hazardLevelDict = ref([])
const hazardStatusDict = ref([])
const hazardSourceDict = ref([])
const networkOptions = ref([])
const equipmentOptions = ref([])

// 详情相关
const detailVisible = ref(false)
const detailData = ref(null)

// 图片相关
const imageList = ref([])
const imageUrls = ref([])
const imageUploading = ref(false)
const previewVisible = ref(false)
const previewList = ref([])
const previewIndex = ref(0)

function getDictLabel(dict, value) {
  const item = dict.find(d => d.dictValue === value)
  return item ? item.dictLabel : value
}

function levelTag(value) {
  const map = { '0': 'danger', '1': 'warning', '2': 'info', '3': '' }
  return map[value] || 'info'
}
function statusTag(value) {
  const map = { '待核查': 'info', '整改中': 'warning', '已整改': 'success', '已闭环': '' }
  return map[value] || 'info'
}

/** 将存储的 hazardImages 字符串转为 URL 数组 */
function parseImageUrls(hazardImages) {
  if (!hazardImages) return []
  return hazardImages.split(',').map(s => s.trim()).filter(Boolean)
}

/** 图片选择后立即上传到 MinIO */
async function handleImageChange(file) {
  if (!file.raw) return
  const isImage = file.raw.type === 'image/jpeg' || file.raw.type === 'image/png' || file.raw.type === 'image/jpg'
  if (!isImage) { ElMessage.error('只能上传图片文件 (JPG/PNG)!'); return }
  if (file.raw.size / 1024 / 1024 >= 5) { ElMessage.error('图片大小不能超过 5MB!'); return }

  imageUploading.value = true
  try {
    const uploadFormData = new FormData()
    uploadFormData.append('file', file.raw)
    uploadFormData.append('dir', 'upload')
    const uploadResponse = await request({
      url: '/minio/upload',
      method: 'post',
      data: uploadFormData
    })
    const url = uploadResponse.url || uploadResponse.fileName
    imageUrls.value.push(url)
    imageList.value.push(url)
  } catch (e) {
    ElMessage.error('图片上传失败')
  } finally {
    imageUploading.value = false
  }
}

/** 删除图片 */
function removeImage(index) {
  imageUrls.value.splice(index, 1)
  imageList.value.splice(index, 1)
}

/** 预览大图 */
function previewImage(index) {
  previewList.value = [...imageList.value]
  previewIndex.value = index
  previewVisible.value = true
}

async function loadDicts() {
  const [typeRes, levelRes, statusRes, sourceRes] = await Promise.all([
    getDicts('hazard_type'),
    getDicts('hazard_level'),
    getDicts('hazard_status'),
    getDicts('hazard_source')
  ])
  hazardTypeDict.value = typeRes.data
  hazardLevelDict.value = levelRes.data
  hazardStatusDict.value = statusRes.data
  hazardSourceDict.value = sourceRes.data
}

async function loadData() {
  loading.value = true
  try {
    const res = await getHazardPage(pageNum.value, pageSize.value, searchForm)
    tableData.value = res.data.records || []
    total.value = res.data.total || 0
  } catch (e) { console.error(e) } finally { loading.value = false }
}
function handleSearch() { pageNum.value = 1; loadData() }
function handleReset() {
  Object.assign(searchForm, { hazardType: '', hazardLevel: '', hazardStatus: '', isSubmitted: null, networkId: '', equipmentId: '' })
  handleSearch()
}
async function loadNetworkOptions() {
  if (networkOptions.value.length > 0) return
  try { const res = await getPipeNetworkOptions(); networkOptions.value = res.data || [] } catch (e) { console.error(e) }
}
async function loadEquipmentOptions() {
  if (equipmentOptions.value.length > 0) return
  try { const res = await getEquipmentByTopLevelType('燃气'); equipmentOptions.value = res.data || [] } catch (e) { console.error(e) }
}
function getNetworkName(id) {
  const found = networkOptions.value.find(n => n.networkId === id)
  return found ? found.networkName : id || '-'
}
function getEquipmentName(id) {
  const found = equipmentOptions.value.find(e => e.equipmentId === id)
  return found ? found.equipmentName : id || '-'
}
/** 自动生成隐患编号：YH-YYYYMMDDHHmmss */
function generateHazardNo() {
  const now = new Date()
  const pad = (n) => String(n).padStart(2, '0')
  const dateStr = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}`
  const timeStr = `${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`
  return `YH-${dateStr}${timeStr}`
}
function handleAdd() {
  dialogTitle.value = '新增'
  Object.assign(formData, { hazardId: '', hazardNo: generateHazardNo(), hazardType: '', hazardLevel: '', hazardDesc: '', hazardSource: '', hazardStatus: '待核查', reportUnit: '', reportTime: '', rectifyPlan: '', rectifyDeadline: '', rectifyPerson: '', networkId: '', equipmentId: '', longitude: null, latitude: null, hazardImages: '', isSubmitted: null, submitTime: null, verifyPerson: null, verifyTime: null })
  imageList.value = []
  imageUrls.value = []
  dialogVisible.value = true
  loadNetworkOptions(); loadEquipmentOptions()
}
function handleEdit(row) {
  dialogTitle.value = '编辑'
  Object.assign(formData, row)
  // 回显已有图片
  const urls = parseImageUrls(row.hazardImages)
  imageUrls.value = [...urls]
  imageList.value = [...urls]
  dialogVisible.value = true
  loadNetworkOptions(); loadEquipmentOptions()
}
async function handleSave() {
  if (!formRef.value) return
  try {
    await formRef.value.validate()
    if (imageUploading.value) { ElMessage.warning('图片正在上传，请稍候'); return }
    // 将图片URL列表拼接为逗号分隔字符串
    formData.hazardImages = imageUrls.value.join(',')
    if (formData.hazardId) { await updateHazard(formData); ElMessage.success('修改成功') }
    else { await addHazard(formData); ElMessage.success('新增成功') }
    dialogVisible.value = false; loadData()
  } catch (e) {
    const msg = e?.response?.data?.msg || e?.message || '操作失败'
    ElMessage.error(msg)
  }
}
function handleDelete(row) {
  ElMessageBox.confirm('确认删除该隐患记录？', '提示', { type: 'warning' }).then(async () => {
    await deleteHazard(row.hazardId); ElMessage.success('删除成功'); loadData()
  }).catch(() => {})
}
/** 报送（同时自动生成工单） */
async function handleSubmitHazard(row) {
  ElMessageBox.confirm('确认报送该隐患？报送后将自动创建工单进入待派单状态。', '提示', { type: 'warning' }).then(async () => {
    try {
      const res = await submitHazard(row.hazardId)
      if (res.code === 200) {
        const msg = res.data ? '报送成功，已自动创建工单' : '报送成功'
        ElMessage.success(msg)
        loadData()
      } else {
        ElMessage.error(res.msg || '报送失败')
      }
    } catch (e) {
      ElMessage.error(e?.response?.data?.msg || e?.message || '报送失败')
    }
  }).catch(() => {})
}

async function handleDetail(row) {
  try {
    const res = await getHazardById(row.hazardId)
    detailData.value = res.data || row
    detailVisible.value = true
  } catch (e) {
    // 接口失败时降级使用表格行数据
    detailData.value = row
    detailVisible.value = true
  }
}

onMounted(async () => { await loadDicts(); loadData(); loadNetworkOptions(); loadEquipmentOptions() })
</script>

<style scoped>
.hazard-container { padding: 16px; }
.search-card { margin-bottom: 16px; }

/* 表格图片样式 */
.table-image {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  cursor: pointer;
}

/* 多图上传列表样式 */
.image-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}
.image-item {
  position: relative;
  width: 80px;
  height: 80px;
  border-radius: 4px;
  overflow: visible;
}
.image-thumb {
  width: 80px;
  height: 80px;
  object-fit: cover;
  border-radius: 4px;
  border: 1px solid #dcdfe6;
  cursor: pointer;
}
.image-thumb:hover {
  border-color: #409eff;
}
.image-remove {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 18px;
  height: 18px;
  background: #f56c6c;
  color: #fff;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  z-index: 1;
}
.image-remove:hover {
  background: #e64a4a;
}

/* 详情图片样式 */
.detail-image-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.detail-image {
  width: 120px;
  height: 120px;
  border-radius: 6px;
  cursor: pointer;
  object-fit: cover;
}
</style>
