<template>
  <div class="manhole-container">
    <el-card class="search-card">
      <el-form :inline="true" :model="searchForm">
        <el-form-item label="窨井名称">
          <el-input v-model="searchForm.manholeName" placeholder="请输入名称" clearable />
        </el-form-item>
        <el-form-item label="窨井编码">
          <el-input v-model="searchForm.manholeCode" placeholder="请输入编码" clearable />
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="searchForm.status" placeholder="请选择" clearable style="width:160px">
            <el-option v-for="d in pipeNetworkStatusDict" :key="d.dictValue" :label="d.dictLabel" :value="d.dictValue" />
          </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-button @click="viewMode = viewMode === 'table' ? 'map' : 'table'">
            {{ viewMode === 'table' ? '地图模式' : '列表模式' }}
          </el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card v-if="viewMode === 'table'" class="table-card">
      <el-table :data="tableData" border stripe v-loading="loading">
        <el-table-column prop="manholeCode" label="窨井编码" min-width="120" />
        <el-table-column prop="manholeName" label="窨井名称" min-width="150" />
        <el-table-column prop="networkId" label="关联管网" min-width="150">
          <template #default="{ row }">
            <span v-if="row.networkId">{{ getNetworkName(row.networkId) }}</span>
            <el-tag v-else type="info" size="small">未关联</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="location" label="位置" min-width="180" />
        <el-table-column prop="manholeDepth" label="深度(米)" width="90" />
        <el-table-column prop="manholeShape" label="形状" width="80">
          <template #default="{ row }">{{ getDictLabel(manholeShapeDict, row.manholeShape) }}</template>
        </el-table-column>
        <el-table-column prop="material" label="材质" width="100" />
        <el-table-column prop="ownershipUnit" label="权属单位" min-width="150" />
        <el-table-column prop="status" label="状态" width="90">
          <template #default="{ row }">
            <el-tag :type="row.status === '0' ? 'success' : 'danger'">{{ getDictLabel(pipeNetworkStatusDict, row.status) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="240" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" size="small" @click="handleEdit(row)">编辑</el-button>
            <el-button type="success" size="small" @click="handleDeviceDialog(row)">关联设备</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-card v-else class="map-card">
      <div id="manholeMap" style="width: 100%; height: 600px"></div>
      <div v-if="mapError" style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#f56c6c;font-size:14px;">{{ mapError }}</div>
    </el-card>

    <el-dialog title="关联监测设备" v-model="deviceDialogVisible" width="950px" destroy-on-close>
      <el-form label-width="80px">
        <el-form-item label="当前窨井">
          <span>{{ currentManhole.manholeName || '-' }}</span>
        </el-form-item>
        <el-form-item label="选择设备">
          <el-select
            v-model="bindForm.equipmentId"
            filterable
            clearable
            placeholder="请选择要关联的设备"
            style="width: 100%"
          >
            <el-option
              v-for="item in unboundEquipmentOptions"
              :key="item.equipmentId"
              :label="`${item.equipmentName}（${item.equipmentCode}）`"
              :value="item.equipmentId"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <div style="margin-bottom: 12px">
        <el-button type="primary" @click="submitBind">添加关联</el-button>
      </div>
      <el-table :data="deviceList" border stripe v-loading="deviceLoading">
        <el-table-column label="设备编码" prop="equipmentCode" min-width="140" />
        <el-table-column label="设备名称" prop="equipmentName" min-width="180" show-overflow-tooltip />
        <el-table-column label="设备型号" prop="equipmentModel" min-width="120" />
        <el-table-column label="制造商" prop="manufacturer" min-width="140" show-overflow-tooltip />
        <el-table-column label="设备位置" prop="equipmentLocation" min-width="180" show-overflow-tooltip />
        <el-table-column label="操作" align="center" width="100">
          <template #default="{ row: dev }">
            <el-button link type="danger" icon="Close" @click="handleUnbind(dev)">解绑</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>

    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="650px" destroy-on-close>
      <el-form :model="formData" :rules="rules" ref="formRef" label-width="100px">
        <el-form-item label="窨井编码" prop="manholeCode">
          <el-input v-model="formData.manholeCode" placeholder="请输入窨井编码" />
        </el-form-item>
        <el-form-item label="窨井名称" prop="manholeName">
          <el-input v-model="formData.manholeName" placeholder="请输入窨井名称" />
        </el-form-item>
        <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}（${n.networkCode}）`" :value="n.networkId" />
          </el-select>
        </el-form-item>
        <el-form-item label="位置描述" prop="location">
          <el-input v-model="formData.location" placeholder="请输入位置描述" />
        </el-form-item>
        <el-form-item label="经度" prop="longitude">
          <el-input-number v-model="formData.longitude" :precision="10" :step="0.0001" style="width: 100%" />
        </el-form-item>
        <el-form-item label="纬度" prop="latitude">
          <el-input-number v-model="formData.latitude" :precision="10" :step="0.0001" style="width: 100%" />
        </el-form-item>
        <el-form-item label="深度(米)">
          <el-input-number v-model="formData.manholeDepth" :precision="2" :step="0.1" style="width: 100%" />
        </el-form-item>
        <el-form-item label="形状">
          <el-select v-model="formData.manholeShape">
            <el-option v-for="d in manholeShapeDict" :key="d.dictValue" :label="d.dictLabel" :value="d.dictValue" />
          </el-select>
        </el-form-item>
        <el-form-item label="材质">
          <el-input v-model="formData.material" placeholder="请输入材质" />
        </el-form-item>
        <el-form-item label="权属单位">
          <el-input v-model="formData.ownershipUnit" placeholder="请输入权属单位" />
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="formData.status">
            <el-option v-for="d in pipeNetworkStatusDict" :key="d.dictValue" :label="d.dictLabel" :value="d.dictValue" />
          </el-select>
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="formData.remark" type="textarea" :rows="3" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSubmit">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, nextTick, watch, onBeforeUnmount } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  getManholePage, addManhole, updateManhole, deleteManhole,
  getManholeDevices, addManholeDeviceRel, deleteManholeDeviceRel,
  getEquipmentByTopLevelType, getPipeNetworkOptions
} from '@/api/pipeNetwork/basic'
import { getDicts } from '@/api/system/dict/data'

const loading = ref(false)
const tableData = ref([])
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref(0)
const viewMode = ref('table')

const searchForm = reactive({ manholeName: '', manholeCode: '', status: '' })
const dialogVisible = ref(false)
const dialogTitle = ref('新增')
const formRef = ref(null)
const formData = reactive({
  manholeId: '', manholeCode: '', manholeName: '', networkId: '',
  location: '', longitude: null, latitude: null, manholeDepth: null,
  manholeShape: '', material: '', ownershipUnit: '', status: '0', remark: ''
})
const rules = {
  manholeCode: [{ required: true, message: '请输入窨井编码', trigger: 'blur' }],
  manholeName: [{ required: true, message: '请输入窨井名称', trigger: 'blur' }],
  longitude: [{ required: true, message: '请输入经度', trigger: 'blur' }],
  latitude: [{ required: true, message: '请输入纬度', trigger: 'blur' }],
  location: [{ required: true, message: '请输入位置描述', trigger: 'blur' }]
}

const pipeNetworkStatusDict = ref([])
const manholeShapeDict = ref([])
const networkOptions = ref([])

const deviceDialogVisible = ref(false)
const currentManhole = reactive({ manholeId: '', manholeName: '' })
const deviceList = ref([])
const deviceLoading = ref(false)
const bindForm = reactive({ equipmentId: '' })
const equipmentOptions = ref([])
const unboundEquipmentOptions = computed(() => {
  const boundIds = deviceList.value.map(d => d.equipmentId)
  return equipmentOptions.value.filter(e => !boundIds.includes(e.equipmentId))
})
function getDictLabel(dict, value) {
  const item = dict.find(d => d.dictValue === value)
  return item ? item.dictLabel : value
}
function getNetworkName(networkId) {
  const found = networkOptions.value.find(n => n.networkId === networkId)
  return found ? found.networkName : networkId
}

async function loadDicts() {
  const [statusRes, shapeRes] = await Promise.all([
    getDicts('pipe_network_status'),
    getDicts('manhole_shape')
  ])
  pipeNetworkStatusDict.value = statusRes.data
  manholeShapeDict.value = shapeRes.data
}

async function loadData() {
  loading.value = true
  try {
    const res = await getManholePage(pageNum.value, pageSize.value, searchForm)
    tableData.value = res.data.records || []
    total.value = res.data.total || 0
    if (viewMode.value === 'map' && mapInitialized) { renderMarkers() }
  } catch (e) { console.error(e) } finally { loading.value = false }
}

function handleSearch() { pageNum.value = 1; loadData() }
function handleReset() { Object.assign(searchForm, { manholeName: '', manholeCode: '', status: '' }); handleSearch() }
async function loadNetworkOptions() {
  if (networkOptions.value.length > 0) return
  try {
    const res = await getPipeNetworkOptions()
    networkOptions.value = res.data || []
  } catch (e) { console.error(e) }
}
function handleAdd() {
  dialogTitle.value = '新增'
  Object.assign(formData, { manholeId: '', manholeCode: '', manholeName: '', networkId: '', location: '', longitude: null, latitude: null, manholeDepth: null, manholeShape: '', material: '', ownershipUnit: '', status: '0', remark: '' })
  dialogVisible.value = true
  loadNetworkOptions()
}
function handleEdit(row) { dialogTitle.value = '编辑'; Object.assign(formData, row); dialogVisible.value = true; loadNetworkOptions() }
async function handleSubmit() {
  const valid = await formRef.value.validate().catch(() => false)
  if (!valid) return
  try {
    if (formData.manholeId) { await updateManhole(formData); ElMessage.success('修改成功') }
    else { await addManhole(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 deleteManhole(row.manholeId); ElMessage.success('删除成功'); loadData()
  }).catch(() => {})
}

async function handleDeviceDialog(row) {
  Object.assign(currentManhole, { manholeId: row.manholeId, manholeName: row.manholeName })
  bindForm.equipmentId = ''
  deviceDialogVisible.value = true
  if (equipmentOptions.value.length === 0) { await loadEquipmentOptions() }
  loadDeviceList()
}
async function loadDeviceList() {
  deviceLoading.value = true
  try {
    const res = await getManholeDevices(currentManhole.manholeId)
    const raw = res.data || []
    deviceList.value = raw.map(r => ({
      relId: r.relId,
      equipmentId: r.equipmentId,
      equipmentName: r.equipmentName,
      equipmentType: r.equipmentType,
      equipmentCode: '',
      equipmentModel: '',
      manufacturer: '',
      equipmentLocation: ''
    }))
    if (raw.length > 0) {
      const eqMap = new Map(equipmentOptions.value.map(e => [e.equipmentId, e]))
      deviceList.value = raw.map(r => {
        const full = eqMap.get(r.equipmentId)
        return {
          relId: r.relId,
          equipmentId: r.equipmentId,
          equipmentName: r.equipmentName || (full ? full.equipmentName : ''),
          equipmentCode: full ? full.equipmentCode : '',
          equipmentModel: full ? full.equipmentModel : '',
          manufacturer: full ? full.manufacturer : '',
          equipmentLocation: full ? full.equipmentLocation : ''
        }
      })
    }
  } catch (e) { console.error(e) } finally { deviceLoading.value = false }
}
async function loadEquipmentOptions() {
  try {
    const res = await getEquipmentByTopLevelType('燃气')
    equipmentOptions.value = res.data || []
  } catch (e) { console.error(e) }
}
async function submitBind() {
  if (!bindForm.equipmentId) { ElMessage.warning('请先选择设备'); return }
  const eq = equipmentOptions.value.find(e => e.equipmentId === bindForm.equipmentId)
  try {
    await addManholeDeviceRel({
      manholeId: currentManhole.manholeId,
      equipmentId: bindForm.equipmentId,
      equipmentName: eq ? eq.equipmentName : '',
      equipmentType: eq ? (eq.equipmentTypeId || '') : ''
    })
    ElMessage.success('关联成功')
    bindForm.equipmentId = ''
    loadDeviceList()
  } catch (e) { console.error(e) }
}
function handleUnbind(dev) {
  ElMessageBox.confirm('确认解除该设备关联？', '提示', { type: 'warning' }).then(async () => {
    await deleteManholeDeviceRel(dev.relId)
    ElMessage.success('解绑成功')
    loadDeviceList()
  }).catch(() => {})
}

let mapInstance = null
let mapInitialized = false
const mapError = ref('')

function waitForBMapGL() {
  return new Promise((resolve, reject) => {
    if (window.BMapGL) { resolve(window.BMapGL); return }
    let attempts = 0
    const timer = setInterval(() => {
      attempts++
      if (window.BMapGL) { clearInterval(timer); resolve(window.BMapGL); return }
      if (attempts >= 80) { clearInterval(timer); reject(new Error('百度地图加载超时')) }
    }, 200)
  })
}

async function initMap() {
  await nextTick()
  const el = document.getElementById('manholeMap')
  if (!el || mapInitialized) return

  try {
    const BMapGL = await waitForBMapGL()
    mapInstance = new BMapGL.Map(el, { enableMapClick: true })
    const center = tableData.value.length > 0 && tableData.value[0].longitude
      ? [Number(tableData.value[0].longitude), Number(tableData.value[0].latitude)]
      : [110.3965, 28.4638]
    mapInstance.centerAndZoom(new BMapGL.Point(center[0], center[1]), 15)
    mapInstance.enableScrollWheelZoom(true)
    mapInitialized = true
    renderMarkers()
  } catch (e) {
    console.error(e)
    mapError.value = '百度地图加载失败，请刷新页面重试'
  }
}

function renderMarkers() {
  if (!mapInstance || typeof BMapGL === 'undefined') return
  try { mapInstance.clearOverlays() } catch (_) {}

  const data = tableData.value.filter(m => m.longitude && m.latitude)
  if (data.length === 0) return

  data.forEach(m => {
    const lng = Number(m.longitude)
    const lat = Number(m.latitude)
    const pt = new BMapGL.Point(lng, lat)
    const marker = new BMapGL.Marker(pt)
    mapInstance.addOverlay(marker)

    const shapeLabel = getDictLabel(manholeShapeDict.value, m.manholeShape)
    const statusLabel = getDictLabel(pipeNetworkStatusDict.value, m.status)
    const html = `<div style="font-size:13px;line-height:1.8;max-width:260px;">
      <b>${m.manholeName}</b><br/>
      编码：${m.manholeCode}<br/>
      位置：${m.location || '-'}<br/>
      深度：${m.manholeDepth != null ? m.manholeDepth + 'm' : '-'}<br/>
      形状：${shapeLabel}<br/>
      材质：${m.material || '-'}<br/>
      状态：${statusLabel}
    </div>`

    marker.addEventListener('click', () => {
      const infoWindow = new BMapGL.InfoWindow(html, { width: 240 })
      mapInstance.openInfoWindow(infoWindow, pt)
    })
  })
}

watch(viewMode, (v) => { if (v === 'map') { initMap() } else { mapInitialized = false } })

onMounted(async () => { await loadDicts(); loadData(); loadNetworkOptions() })

onBeforeUnmount(() => {
  if (mapInstance) {
    try { mapInstance.destroy() } catch (_) {}
    mapInstance = null
    mapInitialized = false
  }
})
</script>

<style scoped>
.manhole-container { padding: 16px; }
.search-card { margin-bottom: 16px; }
.map-card { position: relative; }
</style>
