<script setup>
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import * as echarts from 'echarts'

const scopeSelect = ref('selected')
const districtSearch = ref('')

const treeRef = ref(null)
const treeData = ref([
  {
    id: '106',
    label: '106壶天镇',
    children: [
      { id: '203', label: '203大坪村', children: [] },
      { id: '206', label: '206石狗村', children: [] },
      { id: '207', label: '207壶天村', children: [] },
      { id: '210', label: '210中石村', children: [] },
      { id: '214', label: '214光辉村', children: [] },
      { id: '218', label: '218直东村', children: [] },
      {
        id: '220',
        label: '220合东村',
        children: [
          { id: '220-01', label: '[01] 第一民主组', children: [] },
          { id: '220-02', label: '[02] 第二民主组', children: [] },
          { id: '220-03', label: '[03] 第三民主组', children: [] },
          { id: '220-04', label: '[04] 第四民主组', children: [] },
          { id: '220-05', label: '[05] 第五民主组', children: [] },
          { id: '220-06', label: '[06] 第六民主组', children: [] },
          { id: '220-07', label: '[07] 第七民主组', children: [] },
          { id: '220-08', label: '[08] 第八民主组', children: [] }
        ]
      },
      { id: '222', label: '222南岳坪村', children: [] },
      { id: '224', label: '224上新桥村', children: [] },
      { id: '229', label: '229潭桥村', children: [] },
      { id: '230', label: '230双坪村', children: [] },
      { id: '235', label: '235山坪村', children: [] },
      { id: '238', label: '238大塘村', children: [] },
      { id: '239', label: '239山竹村', children: [] },
      { id: '242', label: '242渠溪村', children: [] },
      { id: '244', label: '244雄辉村', children: [] },
      { id: '247', label: '247井湾村', children: [] },
      { id: '248', label: '248背冲村', children: [] }
    ]
  },
  { id: '107', label: '107翻江镇', children: [] },
  { id: '110', label: '110月山镇', children: [] }
])

const treeProps = { children: 'children', label: 'label' }

const selectedNodeId = ref('')
const selectedPathLabels = ref([])
const selectedSubtreeIds = ref(null)

function walkSubtreeIds(node, set) {
  if (!node) return
  set.add(node.id)
  const children = Array.isArray(node.children) ? node.children : []
  for (const child of children) {
    walkSubtreeIds(child, set)
  }
}

function findPathLabelsById(list, targetId) {
  const path = []
  function dfs(nodes) {
    if (!Array.isArray(nodes)) return false
    for (const n of nodes) {
      path.push(n.label)
      if (n.id === targetId) return true
      if (dfs(n.children)) return true
      path.pop()
    }
    return false
  }
  dfs(list)
  return path
}

function normalizeTitleLabel(label) {
  const raw = String(label || '').trim()
  const withoutCode = raw.replace(/^\d+/, '').trim()
  return withoutCode.replace(/^\[(\d+)\]\s*/, '').trim()
}

function filterTreeNode(value, data) {
  if (!value) return true
  if (scopeSelect.value === 'selected' && selectedSubtreeIds.value && !selectedSubtreeIds.value.has(data?.id)) {
    return false
  }
  return String(data?.label || '').includes(value)
}

function handleTreeNodeClick(data) {
  selectedNodeId.value = data?.id || ''
  selectedPathLabels.value = findPathLabelsById(treeData.value, selectedNodeId.value)
  const set = new Set()
  walkSubtreeIds(data, set)
  selectedSubtreeIds.value = set
  if (districtSearch.value) {
    treeRef.value?.filter?.(districtSearch.value)
  }
}

const titleText = computed(() => {
  const cleaned = (selectedPathLabels.value || []).map(normalizeTitleLabel).filter(Boolean)
  if (cleaned.length === 0) return '湘乡市延包任务进度'
  return `湘乡市${cleaned.slice(0, 3).join('')}延包任务进度`
})

const metrics = ref([
  { label: '总发包方', value: '8', valueClass: 'text-gray-800' },
  { label: '未开始', value: '7', valueClass: 'text-gray-800' },
  { label: '摸底中', value: '15', valueClass: 'text-gray-800' },
  { label: '公示中', value: '0', valueClass: 'text-gray-800' },
  { label: '签合同', value: '0', valueClass: 'text-gray-800' },
  { label: '总户数', value: '534', valueClass: 'text-gray-800' },
  { label: '已上报', value: '533', valueClass: 'text-gray-800' },
  { label: '已上报合同面积(亩)', value: '1,519.64', valueClass: 'text-gray-800' },
  { label: '未上报', value: '1', valueClass: 'text-red-600' },
  { label: '未上报合同面积(亩)', value: '4.78', valueClass: 'text-gray-800' },
  { label: '待公示', value: '532', valueClass: 'text-red-600' },
  { label: '已公示', value: '0', valueClass: 'text-gray-800' },
  { label: '待审核', value: '0', valueClass: 'text-red-600' },
  { label: '未通过', value: '1', valueClass: 'text-red-600' }
])

const metricColumns = 5
const metricRowCount = computed(() => Math.ceil(metrics.value.length / metricColumns))
function metricCellClass(idx) {
  const col = idx % metricColumns
  const row = Math.floor(idx / metricColumns)
  return [
    'h-18 flex flex-col items-center justify-center gap-1 border-r border-gray-200 border-b border-gray-200',
    col === metricColumns - 1 ? 'border-r-0' : '',
    row === metricRowCount.value - 1 ? 'border-b-0' : ''
  ]
}

const monthValue = ref('2025-12')

const issueList = ref([])
const issueCurrentPage = ref(1)
const issuePageSize = ref(10)
const issueTotal = computed(() => issueList.value.length)
const issuePageData = computed(() => {
  const start = (issueCurrentPage.value - 1) * issuePageSize.value
  return issueList.value.slice(start, start + issuePageSize.value)
})

const reportChartEl = ref(null)
const confirmChartEl = ref(null)
const reportPieEl = ref(null)
const publicPieEl = ref(null)
const chartsWrapEl = ref(null)

let reportChart = null
let confirmChart = null
let reportPie = null
let publicPie = null
let chartResizeObserver = null

function getMonthDays(yyyyMm) {
  const parts = String(yyyyMm || '').split('-')
  const year = Number(parts[0] || 0)
  const month = Number(parts[1] || 0)
  if (!year || !month) return 31
  return new Date(year, month, 0).getDate()
}

const xDays = computed(() => {
  const days = getMonthDays(monthValue.value)
  return Array.from({ length: days }, (_, i) => String(i + 1).padStart(2, '0'))
})

function setLineChart(instance, title) {
  const days = xDays.value
  instance?.setOption?.({
    title: { text: title, left: 10, top: 8, textStyle: { fontSize: 14, fontWeight: 600, color: '#111827' } },
    grid: { left: 46, right: 16, top: 40, bottom: 24 },
    tooltip: { trigger: 'axis' },
    xAxis: { type: 'category', data: days, axisTick: { show: false } },
    yAxis: { type: 'value', min: 0, max: 1, interval: 1 },
    series: [
      {
        type: 'line',
        data: days.map(() => 0),
        symbol: 'circle',
        symbolSize: 6,
        lineStyle: { width: 2, color: '#ef4444' },
        itemStyle: { color: '#ef4444' }
      }
    ]
  })
}

function setReportPieChart(instance) {
  instance?.setOption?.({
    title: { text: '上报情况', left: 'center', top: 8, textStyle: { fontSize: 14, fontWeight: 600, color: '#111827' } },
    tooltip: { trigger: 'item' },
    legend: { left: 10, top: 10, orient: 'vertical' },
    series: [
      {
        type: 'pie',
        radius: ['0%', '55%'],
        center: ['55%', '60%'],
        label: { formatter: '{b}' },
        data: [
          { name: '未上报', value: 1, itemStyle: { color: '#ef4444' } },
          { name: '已上报', value: 533, itemStyle: { color: '#334155' } }
        ]
      }
    ]
  })
}

function setPublicPieChart(instance) {
  instance?.setOption?.({
    title: { text: '发包方公示情况', left: 'center', top: 8, textStyle: { fontSize: 14, fontWeight: 600, color: '#111827' } },
    tooltip: { trigger: 'item' },
    legend: { left: 10, top: 10, orient: 'vertical' },
    series: [
      {
        type: 'pie',
        radius: ['0%', '55%'],
        center: ['58%', '60%'],
        label: { formatter: '{b}' },
        data: [
          { name: '未开始公示', value: 8, itemStyle: { color: '#ef4444' } },
          { name: '公示中', value: 0, itemStyle: { color: '#0ea5e9' } },
          { name: '完成公示', value: 0, itemStyle: { color: '#64748b' } }
        ]
      }
    ]
  })
}

function resizeAll() {
  reportChart?.resize?.()
  confirmChart?.resize?.()
  reportPie?.resize?.()
  publicPie?.resize?.()
}

function initCharts() {
  if (reportChartEl.value && !reportChart) reportChart = echarts.init(reportChartEl.value)
  if (confirmChartEl.value && !confirmChart) confirmChart = echarts.init(confirmChartEl.value)
  if (reportPieEl.value && !reportPie) reportPie = echarts.init(reportPieEl.value)
  if (publicPieEl.value && !publicPie) publicPie = echarts.init(publicPieEl.value)

  if (reportChart) setLineChart(reportChart, '上报数据情况')
  if (confirmChart) setLineChart(confirmChart, '确权数据情况')
  if (reportPie) setReportPieChart(reportPie)
  if (publicPie) setPublicPieChart(publicPie)
}

function onResize() {
  resizeAll()
}

watch(districtSearch, (val) => {
  treeRef.value?.filter?.(val)
})

watch(monthValue, async () => {
  await nextTick()
  if (reportChart) setLineChart(reportChart, '上报数据情况')
  if (confirmChart) setLineChart(confirmChart, '确权数据情况')
  resizeAll()
})

onMounted(async () => {
  await nextTick()
  handleTreeNodeClick(treeData.value?.[0]?.children?.find?.((v) => v.id === '220') || treeData.value?.[0])
  treeRef.value?.setCurrentKey?.('220')
  initCharts()
  if (chartsWrapEl.value && !chartResizeObserver) {
    chartResizeObserver = new ResizeObserver(() => resizeAll())
    chartResizeObserver.observe(chartsWrapEl.value)
  }
  window.addEventListener('resize', onResize)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', onResize)
  chartResizeObserver?.disconnect?.()
  chartResizeObserver = null
  reportChart?.dispose?.()
  confirmChart?.dispose?.()
  reportPie?.dispose?.()
  publicPie?.dispose?.()
  reportChart = null
  confirmChart = null
  reportPie = null
  publicPie = null
})
</script>

<template>
  <div class="h-full w-full flex overflow-hidden">
    <div class="w-72 border-r border-gray-200 bg-white flex flex-col">
      <div class="p-2 border-b border-gray-200">
        <el-select v-model="scopeSelect" size="small" class="w-full" placeholder="选中的节点中搜索">
          <el-option label="选中的节点中搜索" value="selected" />
          <el-option label="全部" value="all" />
        </el-select>
        <el-input v-model="districtSearch" size="small" clearable class="mt-2" placeholder="搜索" />
      </div>
      <el-scrollbar class="flex-1">
        <div class="p-2">
          <el-tree
            ref="treeRef"
            :data="treeData"
            node-key="id"
            :props="treeProps"
            :filter-node-method="filterTreeNode"
            default-expand-all
            highlight-current
            :expand-on-click-node="false"
            @node-click="handleTreeNodeClick"
          />
        </div>
      </el-scrollbar>
    </div>

    <div class="flex-1 bg-white overflow-hidden">
      <div class="h-full p-2">
        <div class="h-full border border-gray-200 flex flex-col">
          <div class="h-10 flex items-center justify-center relative border-b border-gray-200">
            <div class="text-sm font-medium text-gray-800">{{ titleText }}</div>
            <div class="absolute right-2 top-0 h-10 flex items-center gap-2">
              <el-button type="primary" size="small">按乡镇导出</el-button>
              <el-button type="primary" size="small">按村导出</el-button>
              <el-button type="primary" size="small">按组导出</el-button>
            </div>
          </div>

          <div class="grid grid-cols-5 border-b border-gray-200">
            <div
              v-for="(m, idx) in metrics"
              :key="idx"
              :class="metricCellClass(idx)"
            >
              <div class="flex items-center gap-2 text-green-600 text-sm">
                <span class="font-medium">{{ m.label }}</span>
              </div>
              <div class="text-xl font-semibold" :class="m.valueClass">{{ m.value }}</div>
            </div>
          </div>

          <div class="p-2 flex items-center gap-2">
            <div class="text-sm text-gray-700">按月份统计上报进度：</div>
            <el-date-picker v-model="monthValue" type="month" size="small" format="YYYY-MM" value-format="YYYY-MM" class="!w-40" />
          </div>

          <div ref="chartsWrapEl" class="flex-1 flex border-t border-gray-200 overflow-hidden">
            <div class="flex-1 flex flex-col border-r border-gray-200">
              <div class="h-48 border-b border-gray-200">
                <div ref="reportChartEl" class="h-full w-full"></div>
              </div>
              <div class="h-48">
                <div ref="confirmChartEl" class="h-full w-full"></div>
              </div>
              <div class="flex-1 border-t border-gray-200 grid grid-cols-2">
                <div class="border-r border-gray-200">
                  <div ref="reportPieEl" class="h-full w-full"></div>
                </div>
                <div>
                  <div ref="publicPieEl" class="h-full w-full"></div>
                </div>
              </div>
            </div>
            <div class="w-96 flex flex-col">
              <div class="h-10 grid grid-cols-2 border-b border-gray-200 text-sm text-gray-700">
                <div class="flex items-center justify-center">记录时间</div>
                <div class="flex items-center justify-center border-l border-gray-200">问题内容</div>
              </div>
              <el-scrollbar class="flex-1">
                <div v-if="issuePageData.length" class="text-sm text-gray-700">
                  <div
                    v-for="(row, idx) in issuePageData"
                    :key="idx"
                    class="grid grid-cols-2 min-h-10 border-b border-gray-200"
                  >
                    <div class="flex items-center justify-center px-2">{{ row.time }}</div>
                    <div class="flex items-center px-2 border-l border-gray-200">{{ row.content }}</div>
                  </div>
                </div>
                <div v-else class="h-full flex items-center justify-center text-sm text-gray-500">暂无数据</div>
              </el-scrollbar>
              <div class="h-10 px-2 border-t border-gray-200 flex items-center justify-end">
                <el-pagination
                  v-model:current-page="issueCurrentPage"
                  v-model:page-size="issuePageSize"
                  :page-sizes="[10, 20, 50]"
                  :total="issueTotal"
                  layout="prev, pager, next, sizes, total"
                  small
                />
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
:deep(.el-tree-node__content) {
  height: 26px;
}
</style>
