<template>
  <div class="container">
    <el-card shadow="never" class="main-card">
      <template #header>
        <div class="header-row">
          <div class="left-panel">
            <h2 class="sys-title">📡 光谱数据监控</h2>
            <div class="sys-status">
              <span v-if="isRunning" class="status-running">
                <el-icon class="is-loading"><Loading /></el-icon> 正在执行同步任务...
              </span>
              <span v-else class="status-idle">
                <el-icon><CircleCheck /></el-icon> 系统就绪 (最后更新: {{ lastCheckTime }})
              </span>
            </div>
          </div>
          <div class="header-actions">
            <el-button type="primary" :loading="isRunning" @click="handleManualRefresh(false)" round icon="Refresh" :size="isMobile ? 'small' : 'default'">手动同步</el-button>
          </div>
        </div>
      </template>

      <div class="status-summary">
        <el-tag type="danger" effect="dark" class="res-tag">红色：已离线 / 异常 / 滞后>7天</el-tag>
        <el-tag type="warning" color="#ff8c00" effect="dark" class="res-tag" style="border-color: #ff8c00;">橘色：滞后 2-7 天</el-tag>
        <el-tag type="warning" effect="dark" class="res-tag">黄色：滞后 1-2 天</el-tag>
        <el-tag type="success" effect="dark" class="res-tag">绿色：正常且今日已同步</el-tag>
      </div>

      <div class="toolbar" :class="{ 'mobile-toolbar': isMobile }">
        <div class="filter-section">
          <el-radio-group v-model="filters.site" :size="isMobile ? 'small' : 'default'">
            <el-radio-button value="all">全部</el-radio-button>
            <el-radio-button value="106">106 塔上光谱仪</el-radio-button>
            <el-radio-button value="82">82 高光谱传感器</el-radio-button>
          </el-radio-group>
          <el-input
              v-model="filters.keyword"
              placeholder="搜索设备名称..."
              class="search-input"
              clearable
          />
        </div>
        <div class="action-section">
          <el-checkbox v-model="showHidden" label="显示屏蔽" border style="margin-right: 10px" :size="isMobile ? 'small' : 'default'"/>
          <el-button type="warning" plain :disabled="selectedRows.length === 0" @click="hideSelected" :size="isMobile ? 'small' : 'default'">屏蔽选中</el-button>
        </div>
      </div>

      <el-table
          ref="multipleTableRef"
          :data="sortedData"
          border
          height="600"
          v-loading="isRunning"
          @selection-change="val => selectedRows = val"
          :row-class-name="tableRowClassName"
          style="width: 100%"
      >
        <el-table-column type="selection" width="40" align="center" fixed="left" />

        <el-table-column label="状态" :width="isMobile ? 90 : 120" align="center">
          <template #default="{ row }">
            <el-tag :style="getStatusTagStyle(row)" effect="dark" size="small">{{ getStatusLabel(row) }}</el-tag>
          </template>
        </el-table-column>

        <el-table-column label="名称" min-width="180">
          <template #default="{ row }">
            <div class="name-cell">
              <el-link type="primary" underline="hover" @click="showDetails(row)" style="font-weight: bold; font-size: 14px;">
                {{ formatDisplayName(row.name) }}
              </el-link>
              <el-tag v-if="isHidden(row.name)" type="info" size="small" style="margin-left:5px">隐藏</el-tag>
            </div>
          </template>
        </el-table-column>

        <el-table-column prop="reason" label="反馈" min-width="150" v-if="!isMobile">
          <template #default="{ row }">
            <span :style="{ color: getStatusColor(row), fontWeight: 'bold' }">{{ formatReason(row) }}</span>
          </template>
        </el-table-column>

        <el-table-column prop="offset" label="时效" width="80" align="center" v-if="!isMobile"/>
        <el-table-column prop="latest_time" label="数据时间" width="170" align="center" />

        <el-table-column label="操作" width="70" v-if="showHidden" align="center" fixed="right">
          <template #default="{ row }">
            <el-button v-if="isHidden(row.name)" type="primary" link @click="restoreDevice(row.name)">恢复</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <el-drawer
        v-model="drawerVisible"
        title="设备详情"
        :size="isMobile ? '100%' : '80%'"
        @opened="initCharts"
        direction="rtl"
    >

<!--      <div v-if="activeDevice" class="drawer-content">-->
<!--        <div class="info-banner">-->
<!--          <el-descriptions :column="isMobile ? 1 : 4" border size="small">-->
<!--            <el-descriptions-item label="设备名称">{{ formatDisplayName(activeDevice.name) }}</el-descriptions-item>-->
<!--            <el-descriptions-item label="当前状态">-->
<!--              <el-tag size="small" :style="getStatusTagStyle(activeDevice)">{{ getStatusLabel(activeDevice) }}</el-tag>-->
<!--            </el-descriptions-item>-->
<!--            <el-descriptions-item label="数据时间">{{ activeDevice.latest_time }}</el-descriptions-item>-->
<!--            <el-descriptions-item label="检查时间">{{ activeDevice.check_time }}</el-descriptions-item>-->
<!--          </el-descriptions>-->
<!--        </div>-->
<!--        <div class="visual-section">-->
<!--          <h3 class="section-title">-->
<!--            <el-icon><DataLine /></el-icon>-->
<!--            {{ is106Site ? '光谱能量分布 (完整原始数据)' : '高光谱传感器数据 (Up/Down Spec)' }}-->
<!--          </h3>-->
<!--          <div v-if="currentChartModules.length === 0" class="empty-hint"><el-empty description="暂无有效的图表数据" /></div>-->
<!--          <div v-for="(module, index) in currentChartModules" :key="index" class="chart-container">-->
<!--            <div class="chart-header" v-if="is106Site">-->
<!--              <div class="tag-group">-->
<!--                <span class="module-tag">型号: {{ module.model }}</span>-->
<!--                <span class="sn-tag">SN: {{ module.sn }}</span>-->
<!--              </div>-->
<!--            </div>-->
<!--            <div :id="'chart-' + index" class="echart-box" :class="{ 'no-header': !is106Site }"></div>-->
<!--          </div>-->
<!--        </div>-->
<!--      </div>-->
      <sidevueold></sidevueold>
    </el-drawer>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onBeforeUnmount, nextTick } from 'vue'
import axios from 'axios'
import * as echarts from 'echarts'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Loading, CircleCheck, Refresh, DataLine } from '@element-plus/icons-vue'
import sidevueold from "./sidevueold.vue"
// --- 响应式布局状态 ---
const windowWidth = ref(window.innerWidth)
const isMobile = computed(() => windowWidth.value < 768)

// 窗口大小监听函数
const handleResize = () => {
  windowWidth.value = window.innerWidth
  // 触发图表重绘
  chartInstances.forEach(chart => chart && chart.resize())
}

// --- 状态变量 ---
const rawData = ref([])
const isRunning = ref(false)
const lastCheckTime = ref('N/A')
const selectedRows = ref([])
const showHidden = ref(false)
const drawerVisible = ref(false)
const activeDevice = ref(null)
const filters = reactive({ site: 'all', keyword: '' })
const multipleTableRef = ref()
let chartInstances = [] // 存储图表实例以便resize

// 初始化隐藏列表
const ignoredList = ref(JSON.parse(localStorage.getItem('hide_list') || '[]'))

let autoRefreshTimer = null

// --- 工具函数 ---
const formatSource = (source) => {
  if (!source) return ''
  const s = source.toString()
  if (s.includes('106')) return '106 塔上光谱仪'
  if (s.includes('82')) return '82 高光谱传感器'
  return s
}

const formatDisplayName = (name) => {
  if (!name) return ''
  return name.split('_').map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join('_')
}

const parseFlexibleDate = (dateStr) => {
  if (!dateStr || dateStr === 'N/A') return null
  try {
    let cleanStr = dateStr.toString().split('.')[0].replace(/[_/]/g, '-')
    const d = new Date(cleanStr)
    return isNaN(d.getTime()) ? null : d
  } catch { return null }
}

const getHoursDiff = (dateStr) => {
  if (!dateStr || dateStr === 'N/A') return 999
  const lastDate = parseFlexibleDate(dateStr)
  if (!lastDate) return 999
  return (new Date() - lastDate) / (1000 * 3600)
}

// --- 业务逻辑 (状态与排序) ---
const getLevel = (row) => {
  if (row.status === '已离线' || row.status === '异常') return 4
  if (!row.content || row.content === '{}') return 4

  const last = parseFlexibleDate(row.latest_time)
  if (!last) return 4
  const now = new Date()
  const days = (now - last) / (1000 * 3600 * 24)

  if (days > 7) return 4
  if (days > 2) return 3
  if (now.getDate() !== last.getDate()) return 2
  return 1
}

const getStatusLabel = (row) => {
  if (row.status === '已离线') return '已离线'
  if (row.status === '异常') return '异常'
  const level = getLevel(row)
  if (level === 4) return '缺失'
  if (level === 3) return '>2天'
  if (level === 2) return '昨日'
  return '在线'
}

const getStatusColor = (row) => {
  const level = getLevel(row)
  return ['#909399', '#67C23A', '#E6A23C', '#ff8c00', '#F56C6C'][level]
}

const getStatusTagStyle = (row) => {
  const color = getStatusColor(row)
  return { backgroundColor: color, borderColor: color, color: 'white', border: 'none' }
}

const formatReason = (row) => {
  if (row.reason && row.reason !== '同步成功') return row.reason
  const level = getLevel(row)
  if (level === 2) return '⚠️ 待今日更新'
  return '✅ 同步正常'
}

// --- 隐藏/恢复逻辑 ---
const isHidden = (name) => ignoredList.value.includes(name)

const restoreDevice = (name) => {
  if (!name) return
  ignoredList.value = ignoredList.value.filter(item => item !== name)
  localStorage.setItem('hide_list', JSON.stringify(ignoredList.value))
  ElMessage.success('设备已恢复显示')
}

const hideSelected = () => {
  if (selectedRows.value.length === 0) return
  const namesToHide = selectedRows.value.map(row => row.name)
  let count = 0
  namesToHide.forEach(name => {
    if (!ignoredList.value.includes(name)) {
      ignoredList.value.push(name)
      count++
    }
  })
  if (count > 0) {
    localStorage.setItem('hide_list', JSON.stringify(ignoredList.value))
    ElMessage.warning(`已屏蔽 ${count} 个设备`)
    if (multipleTableRef.value) multipleTableRef.value.clearSelection()
  } else {
    ElMessage.info('选中的设备已在屏蔽列表中')
  }
}

const showDetails = (row) => {
  activeDevice.value = row
  drawerVisible.value = true
}

// --- 过滤与排序 ---
const sortedData = computed(() => {
  return rawData.value.filter(d => {
    const basicMatch = (filters.site === 'all' || d.source.includes(filters.site)) &&
        d.name.toLowerCase().includes(filters.keyword.toLowerCase())
    if (showHidden.value) return basicMatch
    else return basicMatch && !isHidden(d.name)
  }).sort((a, b) => getLevel(b) - getLevel(a))
})

const tableRowClassName = ({ row }) => row.status === '已离线' ? 'offline-row' : ''

// --- 刷新逻辑 ---
const fetchLogs = async () => {
  try {
    const res = await axios.get('/api/logs')
    rawData.value = res.data
    if (res.data.length > 0) {
      const latest = res.data.reduce((prev, curr) => (prev.check_time > curr.check_time) ? prev : curr)
      lastCheckTime.value = latest.check_time
    }
  } catch (e) {
    console.warn("API Error, using mock data for display")
  }
}

const checkStatus = async () => {
  try {
    const res = await axios.get('/api/status')
    isRunning.value = res.data.is_running
    if (isRunning.value) setTimeout(checkStatus, 2000)
    else fetchLogs()
  } catch { isRunning.value = false }
}

const handleManualRefresh = async (force = false) => {
  const hours = getHoursDiff(lastCheckTime.value)
  if (!force && hours < 6) {
    try {
      await ElMessageBox.confirm(
          `数据更新于 ${hours.toFixed(1)} 小时前。后端每日10点自动更新，通常无需手动操作。\n是否强制重新爬取？`,
          '数据尚新', { confirmButtonText: '强制爬取', cancelButtonText: '仅加载最新', type: 'warning' }
      )
    } catch {
      fetchLogs()
      ElMessage.success('已加载最新数据库记录')
      return
    }
  }
  try {
    isRunning.value = true
    await axios.post('/api/run')
    checkStatus()
    ElMessage.success('任务已下发')
  } catch {
    isRunning.value = false
    ElMessage.warning('后台已有任务在运行')
  }
}

// --- 图表逻辑 ---
const is106Site = computed(() => activeDevice.value?.source?.includes('106'))
const currentChartModules = computed(() => {
  if (!activeDevice.value?.content || activeDevice.value.content === '{}') return []
  if (is106Site.value) {
    const modules = []
    const infoRegex = /FS\d_Info,Model,([^,]+),SN,([^,]+).*?Wavelength,([\d\.,\s]+)/gs
    let match
    const contentStr = activeDevice.value.content
    while ((match = infoRegex.exec(contentStr)) !== null) {
      const wavelengths = match[3].split(',').map(Number).filter(n => !isNaN(n))
      const series = []
      for (let p = 1; p <= 4; p++) {
        const dMatch = contentStr.match(new RegExp(`${match[1].trim()}_P${p}[^0-9-]*([\\d\\.,\\s-]+)`, 'i'))
        if (dMatch) {
          const vals = dMatch[1].split(',').map(v => {
            const n = parseFloat(v);
            // 修改点 2：不再判断 n > 65500，直接返回原始值 n
            return n;
          })
          if (vals.some(v => v !== null)) series.push({ name: `P${p}`, data: vals, color: ['#5470c6', '#91cc75', '#fac858', '#ee6666'][p-1] })
        }
      }
      if (series.length) modules.push({ model: match[1], sn: match[2], xAxis: wavelengths, series })
    }
    return modules
  } else {
    try {
      const d = JSON.parse(activeDevice.value.content)
      return d.wavelenth ? [{ title: activeDevice.value.name, xAxis: d.wavelenth, series: [
          { name: 'DownSpec', data: d.downspec, color: '#409EFF' }, { name: 'UpSpec', data: d.upspec, color: '#67C23A' }
        ]}] : []
    } catch { return [] }
  }
})

const initCharts = () => {
  chartInstances = [] // 清空旧实例引用
  nextTick(() => {
    currentChartModules.value.forEach((m, i) => {
      const dom = document.getElementById(`chart-${i}`)
      if (dom) {
        if (echarts.getInstanceByDom(dom)) echarts.getInstanceByDom(dom).dispose()
        const chart = echarts.init(dom)
        chartInstances.push(chart)
        chart.setOption({
          title: { text: is106Site.value ? `SN: ${m.sn}` : m.title, left: 'center', top: 10, textStyle: { fontSize: isMobile.value ? 14 : 18 } },
          tooltip: { trigger: 'axis', confine: true },
          legend: { top: 35, type: 'scroll' },
          grid: { top: 70, bottom: 30, right: isMobile.value ? 10 : 30, left: isMobile.value ? 40 : 50 },
          xAxis: { type: 'category', data: m.xAxis, boundaryGap: false },
          yAxis: { type: 'value', min: 'dataMin', max: 'dataMax' },
          series: m.series.map(s => ({
            name: s.name,
            type: 'line',
            data: s.data,
            connectNulls: false,
            smooth: true,
            showSymbol: false,
            lineStyle: { width: 2, color: s.color },
            areaStyle: { opacity: 0.1, color: s.color }
          }))
        })
      }
    })
  })
}

// --- 生命周期 ---
onMounted(() => {
  document.title = "光谱数据监控"
  fetchLogs()
  window.addEventListener('resize', handleResize)
  autoRefreshTimer = setInterval(() => {
    if (!isRunning.value) fetchLogs()
  }, 300000)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)
  if (autoRefreshTimer) clearInterval(autoRefreshTimer)
  chartInstances.forEach(c => c && c.dispose())
})
</script>

<style scoped>
/* 基础 PC 端样式 */
.container { padding: 20px; max-width: 1400px; margin: 0 auto; background-color: #f5f7fa; min-height: 100vh; transition: all 0.3s; }
.header-row { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px; }
.sys-title { margin: 0; font-size: 22px; color: #303133; font-weight: 600; }
.sys-status { font-size: 13px; color: #909399; margin-top: 5px; }
.status-running { color: #409EFF; font-weight: bold; display: flex; align-items: center; gap: 5px; }
.status-idle { display: flex; align-items: center; gap: 5px; }
.status-summary { margin: 15px 0; display: flex; gap: 10px; flex-wrap: wrap; }
.toolbar { background: #fff; padding: 15px 20px; border-radius: 8px; display: flex; justify-content: space-between; margin-bottom: 20px; border: 1px solid #ebeef5; align-items: center; transition: all 0.3s; }
.filter-section { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.name-cell { display: flex; align-items: center; flex-wrap: wrap; gap: 5px;}
:deep(.offline-row) { background-color: #fef0f0 !important; }
.drawer-content { padding: 0 20px 20px; }
.info-banner { margin-bottom: 20px; }
.chart-container { margin-bottom: 30px; border: 1px solid #e4e7ed; border-radius: 8px; overflow: hidden; background: #fff; }
.chart-header { background: #fafafa; padding: 10px 20px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #e4e7ed; }
.echart-box { width: 100%; height: 380px; }
.echart-box.no-header { margin-top: 15px; }

/* 移动端适配 (Screen < 768px) */
@media screen and (max-width: 768px) {
  .container { padding: 10px; }

  /* 头部调整 */
  .header-row { flex-direction: column; align-items: flex-start; }
  .left-panel { width: 100%; margin-bottom: 10px; }
  .header-actions { width: 100%; display: flex; justify-content: flex-end; }
  .sys-title { font-size: 18px; }

  /* 状态标签调整 */
  .status-summary { gap: 5px; }
  .res-tag { font-size: 11px; height: 24px; padding: 0 5px; }

  /* 工具栏调整 */
  .mobile-toolbar { flex-direction: column; align-items: stretch; padding: 15px 10px; }
  .filter-section { flex-direction: column; align-items: stretch; width: 100%; }
  .search-input { width: 100% !important; margin-left: 0 !important; margin-top: 5px; }

  .action-section {
    display: flex;
    justify-content: space-between;
    margin-top: 15px;
    padding-top: 10px;
    border-top: 1px dashed #ebeef5;
  }

  /* Drawer 内部调整 */
  .drawer-content { padding: 0 10px 20px; }
  .chart-header { flex-direction: column; align-items: flex-start; gap: 5px; }
  .echart-box { height: 300px; }
}
</style>
