<template>
  <div class="water-page">
    <div class="page-heading">
      <div class="page-title"><span class="page-title-icon"><el-icon><component :is="pageIcon" /></el-icon></span><div><h2>{{ title }}</h2><span class="muted">{{ view === 'gis' ? '设施分类图层、空间分布与详情联动' : '设施规模、状态与分类统计分析' }}</span></div></div>
      <div class="heading-actions">
        <el-checkbox-group v-if="view === 'gis'" v-model="selectedTypes" @change="loadData">
          <el-checkbox-button v-for="item in facilityTypes" :key="item.value" :value="item.value">{{ item.label }}</el-checkbox-button>
        </el-checkbox-group>
        <el-button v-if="view === 'stats'" type="success" plain icon="Download" @click="exportData">导出</el-button>
        <el-button :icon="Refresh" @click="loadData">刷新</el-button>
      </div>
    </div>

    <div class="metric-grid">
      <div v-for="(item, index) in overview.slice(0, 5)" :key="item.label" class="metric">
        <el-icon class="metric-icon"><component :is="metricIcons[index % metricIcons.length]" /></el-icon><span>{{ item.label }}</span><strong>{{ item.value }}</strong><small>{{ item.unit }}</small>
      </div>
    </div>

    <template v-if="view === 'gis'">
      <el-card shadow="never" class="map-card" v-loading="loading">
        <div class="map-legend"><span v-for="item in facilityTypes" :key="item.value"><i :style="{ background: item.color }"></i>{{ item.label }}</span></div>
        <div class="facility-map">
          <svg class="pipe-layer" viewBox="0 0 100 100" preserveAspectRatio="none">
            <polyline v-for="line in mapLines" :key="line.id" :points="line.points" fill="none" stroke="#64748b" stroke-width="0.75" vector-effect="non-scaling-stroke" />
          </svg>
          <button v-for="point in mapPoints" :key="point.id" class="facility-point" :style="pointStyle(point)" :title="point.name" @click="openFeature(point)">
            <span></span><b>{{ point.name || point.code || point.typeName }}</b>
          </button>
          <el-empty v-if="!mapPoints.length && !mapLines.length" description="暂无设施空间数据" />
        </div>
      </el-card>
    </template>

    <template v-else>
      <div class="chart-grid">
        <el-card shadow="never"><div class="card-title">设施数量与状态</div><div ref="barChartRef" class="chart"></div></el-card>
        <el-card shadow="never"><div class="card-title">设施类型占比</div><div ref="pieChartRef" class="chart"></div></el-card>
      </div>
      <el-card shadow="never"><el-table :data="rows" stripe border v-loading="loading"><el-table-column prop="name" label="统计项" min-width="180"/><el-table-column prop="value" label="数量" width="130"/><el-table-column prop="unit" label="单位" width="100"/><el-table-column prop="remark" label="说明" min-width="240"/></el-table><el-empty v-if="!rows.length" description="暂无统计数据"/></el-card>
    </template>

    <el-drawer v-model="detailVisible" class="detail-drawer" title="供水设施详情" direction="rtl" size="560px" append-to-body><el-descriptions :column="1" border><el-descriptions-item v-for="(value, key) in detail" :key="key" :label="key">{{ value ?? '-' }}</el-descriptions-item></el-descriptions></el-drawer>
  </div>
</template>

<script setup>
import { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import { DataAnalysis, Location, MapLocation, Refresh, Setting } from '@element-plus/icons-vue'
import { saveAs } from 'file-saver'
import * as echarts from 'echarts'
import { exportPipeNetworkStatistics, getPipeNetworkDashboard, getWaterFacilityDetail, getWaterFacilityFeatures, getWaterFacilityOverview } from '@/api/pipeNetwork/waterSupply'
import { normalizeMapPoints, unwrapResponse } from '@/utils/waterSupplyModel'

const props = defineProps({ title: { type: String, required: true }, view: { type: String, default: 'stats' } })
const pageIcon = computed(() => props.view === 'gis' ? MapLocation : DataAnalysis)
const metricIcons = [Location, Setting, DataAnalysis, MapLocation]
const route = useRoute()
const facilityTypes = [
  { label: '水源地', value: 'source', color: '#2563eb' },
  { label: '水厂', value: 'plant', color: '#16a34a' },
  { label: '泵站', value: 'pumpStation', color: '#d97706' },
  { label: '管网', value: 'pipe', color: '#64748b' },
  { label: '用水户', value: 'user', color: '#dc2626' }
]
const overview = ref([])
const rows = ref([])
const mapPoints = ref([])
const mapLines = ref([])
const routeTypes = String(route.query.type || '').split(',').map(item => item.trim()).filter(Boolean)
const selectedTypes = ref(routeTypes.length ? facilityTypes.map(item => item.value).filter(item => routeTypes.includes(item)) : facilityTypes.map(item => item.value))
const loading = ref(false)
const detailVisible = ref(false)
const detail = ref({})
const barChartRef = ref()
const pieChartRef = ref()
let barChart
let pieChart

const typeColor = type => facilityTypes.find(item => item.value === type)?.color || '#2563eb'
const flattenMetrics = (section, value) => {
  if (Array.isArray(value)) return value.map(item => ({ ...item, section }))
  if (!value || typeof value !== 'object') return [{ name: section, value, unit: '项' }]
  return Object.entries(value).flatMap(([name, metric]) => {
    if (Array.isArray(metric)) return metric.map(item => ({ ...item, section: `${section}/${name}` }))
    if (metric && typeof metric === 'object') return flattenMetrics(`${section}/${name}`, metric)
    return [{ name: `${section}/${name}`, value: metric, unit: '项' }]
  })
}

const renderCharts = async facilityOverview => {
  await nextTick()
  barChart?.dispose(); pieChart?.dispose()
  if (!barChartRef.value || !pieChartRef.value) return
  const labels = facilityOverview.map(item => item.facilityTypeName || item.name || item.facilityType)
  barChart = echarts.init(barChartRef.value)
  barChart.setOption({ tooltip: { trigger: 'axis' }, legend: { top: 0 }, grid: { left: 45, right: 16, top: 42, bottom: 34 }, xAxis: { type: 'category', data: labels }, yAxis: { type: 'value', minInterval: 1 }, series: [{ name: '正常', type: 'bar', stack: 'status', data: facilityOverview.map(item => Number(item.normalCount || 0)), itemStyle: { color: '#16a34a' } }, { name: '异常', type: 'bar', stack: 'status', data: facilityOverview.map(item => Number(item.abnormalCount || 0)), itemStyle: { color: '#dc2626' } }] })
  pieChart = echarts.init(pieChartRef.value)
  pieChart.setOption({ tooltip: { trigger: 'item' }, legend: { bottom: 0 }, series: [{ type: 'pie', radius: ['42%', '68%'], center: ['50%', '45%'], data: facilityOverview.map(item => ({ name: item.facilityTypeName || item.name || item.facilityType, value: Number(item.totalCount || 0) })), label: { formatter: '{b}\n{d}%' } }] })
}

const buildMap = features => {
  const rawPoints = []
  const rawLines = []
  features.forEach(feature => {
    const coordinates = feature.geometry?.coordinates || []
    const properties = feature.properties || {}
    if (feature.geometry?.type === 'Point') rawPoints.push({ ...properties, id: feature.id, longitude: coordinates[0], latitude: coordinates[1], type: properties.facilityType, typeName: properties.facilityTypeName })
    if (feature.geometry?.type === 'LineString' && coordinates.length > 1) rawLines.push({ id: feature.id, properties, coordinates })
  })
  const coordinatePoints = [...rawPoints, ...rawLines.flatMap(line => line.coordinates.map((coordinate, index) => ({ id: `${line.id}-${index}`, longitude: coordinate[0], latitude: coordinate[1] })))]
  const positions = new Map(normalizeMapPoints(coordinatePoints).map(item => [item.id, item]))
  mapPoints.value = rawPoints.map(point => ({ ...point, ...positions.get(point.id) })).filter(point => Number.isFinite(point.mapX))
  mapLines.value = rawLines.map(line => ({ ...line, points: line.coordinates.map((_, index) => positions.get(`${line.id}-${index}`)).filter(Boolean).map(point => `${point.mapX},${point.mapY}`).join(' ') })).filter(line => line.points)
}

const loadData = async () => {
  loading.value = true
  try {
    if (props.view === 'gis') {
      const [overviewResponse, featureResponse] = await Promise.all([getWaterFacilityOverview(), getWaterFacilityFeatures({ types: selectedTypes.value.join(',') })])
      const summary = unwrapResponse(overviewResponse) || []
      overview.value = summary.filter(item => item.facilityType !== 'total').map(item => ({ label: item.facilityTypeName, value: item.geoCompleteCount ?? 0, unit: '个点位' }))
      buildMap(unwrapResponse(featureResponse)?.features || [])
    } else {
      const data = unwrapResponse(await getPipeNetworkDashboard()) || {}
      const facilityOverview = Array.isArray(data.facilityOverview) ? data.facilityOverview : []
      overview.value = facilityOverview.map(item => ({ label: item.facilityTypeName || item.facilityType, value: item.totalCount ?? 0, unit: '项' }))
      rows.value = Object.entries(data).filter(([section]) => section !== 'facilityOverview').flatMap(([section, value]) => flattenMetrics(section, value)).map(item => ({ name: item.name || item.label || item.section || '统计项', value: item.value ?? item.totalCount ?? 0, unit: item.unit || '项', remark: item.remark || item.section || '' }))
      await renderCharts(facilityOverview)
    }
  } catch (error) { overview.value = []; rows.value = []; mapPoints.value = []; mapLines.value = []; console.warn(`[${props.title}] 数据加载失败`, error) } finally { loading.value = false }
}
const exportData = async () => {
  try {
    const blob = await exportPipeNetworkStatistics()
    saveAs(new Blob([blob]), `管网数据统计分析_${new Date().toISOString().slice(0, 10)}.xlsx`)
  } catch (error) {
    console.warn('管网统计导出失败', error)
  }
}
const pointStyle = point => ({ left: `${point.mapX}%`, top: `${point.mapY}%`, color: typeColor(point.type) })
const openFeature = async point => { try { const response = await getWaterFacilityDetail(point.type, point.id?.split(':').pop()); detail.value = unwrapResponse(response) || point; detailVisible.value = true } catch {} }
const resizeCharts = () => { barChart?.resize(); pieChart?.resize() }
onMounted(() => { loadData(); window.addEventListener('resize', resizeCharts) })
onBeforeUnmount(() => { window.removeEventListener('resize', resizeCharts); barChart?.dispose(); pieChart?.dispose() })
</script>

<style lang="scss">
@use './waterSupplyPageTheme.scss';
</style>

<style scoped>
.water-page{padding:20px;background:#f5f7fa;min-height:calc(100vh - 84px)}.page-heading{display:flex;justify-content:space-between;align-items:center;gap:16px;margin-bottom:16px}.page-heading h2{margin:0 0 5px;font-size:20px}.heading-actions{display:flex;align-items:center;gap:12px}.muted{font-size:13px;color:#909399}.metric-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px;margin-bottom:16px}.metric{background:#fff;padding:16px 18px;border:1px solid #ebeef5}.metric span{display:block;color:#909399;font-size:13px}.metric strong{font-size:24px;line-height:34px}.metric small{margin-left:5px;color:#909399}.chart-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px}.card-title{font-weight:600;margin-bottom:8px}.chart{height:310px}.map-card{min-height:580px}.map-legend{display:flex;gap:18px;margin-bottom:12px;color:#475569;font-size:13px}.map-legend i{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:6px}.facility-map{position:relative;height:500px;overflow:hidden;border:1px solid #dbe6f2;background-color:#f8fbff;background-image:linear-gradient(#eaf0f6 1px,transparent 1px),linear-gradient(90deg,#eaf0f6 1px,transparent 1px);background-size:40px 40px}.pipe-layer{position:absolute;inset:0;width:100%;height:100%;overflow:visible}.facility-point{position:absolute;transform:translate(-50%,-50%);border:0;background:transparent;cursor:pointer;text-align:center;padding:0;color:#2563eb}.facility-point span{display:block;width:15px;height:15px;margin:auto;border-radius:50%;background:currentColor;border:3px solid #fff;box-shadow:0 0 0 3px currentColor}.facility-point b{display:block;margin-top:4px;color:#334155;font-size:11px;white-space:nowrap}.facility-map :deep(.el-empty){position:absolute;inset:0}@media(max-width:1100px){.metric-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.heading-actions{align-items:flex-end;flex-direction:column}}@media(max-width:800px){.page-heading{align-items:flex-start;flex-direction:column}.chart-grid{grid-template-columns:1fr}.metric-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.heading-actions{align-items:flex-start}.heading-actions :deep(.el-checkbox-group){display:flex;flex-wrap:wrap}}
</style>
