<script setup>
import * as echarts from 'echarts'
import { ArrowLeft, VideoPlay, VideoPause, Download } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import {
  onMounted,
  onBeforeUnmount,
  ref,
  computed,
  nextTick,
  watch,
} from 'vue'
import { useRouter, useRoute } from 'vue-router'
import {
  getExperiment,
  startExperiment,
  stopExperiment,
  getDataPoints,
} from '@/api/realtimeMonitor'

const router = useRouter()
const route = useRoute()
const expId = Number(route.params.id)

// ── 试验状态 ───────────────────────────────────────────────────────────────────
const experiment = ref(null)
const loadingExp = ref(false)

const loadExperiment = async () => {
  loadingExp.value = true
  try {
    experiment.value = await getExperiment(expId)
  } finally {
    loadingExp.value = false
  }
}

const isRunning = computed(() => experiment.value?.status === 'running')
const isStopped = computed(() => experiment.value?.status === 'stopped')

// ── 实时数据 ───────────────────────────────────────────────────────────────────
const dataPoints = ref([])      // 全部数据点
let nextFromStep = 0            // 下次轮询起始步
let pollTimer = null

const fetchNewPoints = async () => {
  try {
    const newPts = await getDataPoints(expId, nextFromStep)
    if (newPts.length) {
      dataPoints.value = [...dataPoints.value, ...newPts]
      nextFromStep = dataPoints.value[dataPoints.value.length - 1].step_idx + 1
      updateCharts()
    }
    // 更新试验状态
    const latest = await getExperiment(expId)
    experiment.value = latest
    if (latest.status !== 'running') {
      stopPolling()
    }
  } catch {
    // 静默处理轮询错误
  }
}

const startPolling = () => {
  if (pollTimer) return
  pollTimer = setInterval(fetchNewPoints, 2000)
}

const stopPolling = () => {
  if (pollTimer) {
    clearInterval(pollTimer)
    pollTimer = null
  }
}

// ── 控制操作 ───────────────────────────────────────────────────────────────────
const controlling = ref(false)

const handleStart = async () => {
  controlling.value = true
  try {
    await startExperiment(expId)
    experiment.value = await getExperiment(expId)
    ElMessage.success('MPC 控制已启动')
    startPolling()
  } finally {
    controlling.value = false
  }
}

const handleStop = async () => {
  controlling.value = true
  try {
    await stopExperiment(expId)
    stopPolling()
    experiment.value = await getExperiment(expId)
    // 加载全部数据点
    const all = await getDataPoints(expId, 0)
    dataPoints.value = all
    updateCharts()
    ElMessage.success('控制已停止')
  } finally {
    controlling.value = false
  }
}

// ── 图表 ───────────────────────────────────────────────────────────────────────
const chartRef = ref(null)
let chart = null

const MAX_CHART_POINTS = 300   // 超过时抽样显示

const buildDisplayData = () => {
  const pts = dataPoints.value
  if (!pts.length) return []
  const step = pts.length > MAX_CHART_POINTS ? Math.ceil(pts.length / MAX_CHART_POINTS) : 1
  return pts.filter((_, i) => i % step === 0)
}

const initCharts = () => {
  if (chartRef.value && !chart) {
    chart = echarts.init(chartRef.value)
  }
  updateCharts()
}

const updateCharts = () => {
  const display = buildDisplayData()
  const xData = display.map((d) => `步${d.step_idx}`)
  const actuals = display.map((d) => d.actual_temp)
  const currents = display.map((d) => d.current_output)
  const targetLine = display.map(() => experiment.value?.target_temp ?? null)

  if (chart) {
    chart.setOption(
      {
        animation: false,
        color: ['#409EFF', '#F56C6C', '#E6A23C'],
        tooltip: {
          trigger: 'axis',
          backgroundColor: 'rgba(255,255,255,0.96)',
          borderColor: '#e2e8f0',
          borderWidth: 1,
          formatter(params) {
            if (!params?.length) return ''
            const lines = [`<div style="margin-bottom:4px;font-weight:600">${params[0].axisValue}</div>`]
            params.forEach((p) => {
              const unit = p.seriesName === '电流输出' ? ' A' : ' °C'
              const v = p.data != null ? Number(p.data).toFixed(3) + unit : '--'
              lines.push(
                `<div style="display:flex;justify-content:space-between;gap:16px">
                  <span>${p.marker}${p.seriesName}</span><strong>${v}</strong>
                </div>`,
              )
            })
            return lines.join('')
          },
        },
        legend: {
          bottom: 4,
          itemWidth: 18,
          itemHeight: 8,
          textStyle: { color: '#475569', fontSize: 12 },
        },
        grid: { top: 16, left: 16, right: 60, bottom: 52, containLabel: true },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: xData,
          axisLabel: { color: '#64748b', fontSize: 11, interval: Math.max(0, Math.floor(xData.length / 10) - 1) },
          axisLine: { lineStyle: { color: '#cbd5e1' } },
        },
        yAxis: [
          {
            type: 'value',
            name: '温度 (°C)',
            position: 'left',
            nameTextStyle: { color: '#64748b', fontSize: 11 },
            axisLabel: { color: '#64748b', fontSize: 11 },
            splitLine: { lineStyle: { color: '#e2e8f0' } },
          },
          {
            type: 'value',
            name: '电流 (A)',
            position: 'right',
            nameTextStyle: { color: '#E6A23C', fontSize: 11 },
            axisLabel: { color: '#E6A23C', fontSize: 11 },
            splitLine: { show: false },
            min: 0,
          },
        ],
        series: [
          {
            name: '实际温度',
            type: 'line',
            yAxisIndex: 0,
            data: actuals,
            smooth: true,
            symbol: 'none',
            lineStyle: { width: 2 },
          },
          {
            name: '目标温度',
            type: 'line',
            yAxisIndex: 0,
            data: targetLine,
            symbol: 'none',
            lineStyle: { width: 1.5, type: 'dotted', color: '#F56C6C' },
          },
          {
            name: '电流输出',
            type: 'line',
            yAxisIndex: 1,
            data: currents,
            smooth: false,
            symbol: 'none',
            lineStyle: { width: 2, color: '#E6A23C' },
            areaStyle: { color: '#E6A23C', opacity: 0.06 },
          },
        ],
      },
      true,
    )
  }
}

// ── 窗口 resize ────────────────────────────────────────────────────────────────
const onResize = () => {
  chart?.resize()
}

// ── 生命周期 ───────────────────────────────────────────────────────────────────
onMounted(async () => {
  await loadExperiment()
  // 加载已有数据点
  const pts = await getDataPoints(expId, 0)
  dataPoints.value = pts
  if (pts.length) nextFromStep = pts[pts.length - 1].step_idx + 1

  await nextTick()
  initCharts()

  if (experiment.value?.status === 'running') {
    startPolling()
  }

  window.addEventListener('resize', onResize)
})

onBeforeUnmount(() => {
  stopPolling()
  window.removeEventListener('resize', onResize)
  chart?.dispose()
})

// ── 状态辅助 ───────────────────────────────────────────────────────────────────
const statusType = (s) => ({ idle: 'info', running: 'success', stopped: '' }[s] ?? 'info')
const statusLabel = (s) => ({ idle: '未开始', running: '运行中', stopped: '已停止' }[s] ?? s)

const latestPoint = computed(() => {
  const pts = dataPoints.value
  return pts.length ? pts[pts.length - 1] : null
})

// ── 曲线 / 表格 切换 ────────────────────────────────────────────────────────────
const viewMode = ref('chart')

watch(viewMode, async (val) => {
  if (val === 'chart') {
    await nextTick()
    chart?.dispose()
    chart = null
    initCharts()
  }
})

const downloadCSV = () => {
  const target = experiment.value?.target_temp ?? ''
  const header = ['步骤', '实际温度(°C)', '目标温度(°C)', '电流输出(A)']
  const rows = dataPoints.value.map((pt) => [
    pt.step_idx,
    pt.actual_temp,
    target,
    pt.current_output,
  ])
  const csv = [header, ...rows].map((r) => r.join(',')).join('\n')
  const blob = new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8;' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `${experiment.value?.name ?? 'data'}_数据.csv`
  a.click()
  URL.revokeObjectURL(url)
}
</script>

<template>
  <div class="detail-page" v-loading="loadingExp">
    <!-- 顶部导航 -->
    <div class="page-header">
      <el-button :icon="ArrowLeft" link @click="router.back()">返回列表</el-button>
      <span class="header-title">{{ experiment?.name ?? '试验详情' }}</span>
      <el-tag v-if="experiment" :type="statusType(experiment.status)" size="small">
        {{ statusLabel(experiment.status) }}
      </el-tag>
    </div>

    <template v-if="experiment">
      <!-- 信息卡 + 控制面板 -->
      <el-row :gutter="16" class="info-row">
        <!-- 试验信息 -->
        <el-col :span="16">
          <el-card shadow="hover" class="info-card">
            <div class="info-grid">
              <div class="info-item">
                <span class="label">预测模型</span>
                <span class="value">{{ experiment.model_name }}</span>
              </div>
              <div class="info-item">
                <span class="label">目标温度</span>
                <span class="value highlight">{{ experiment.target_temp?.toFixed(1) }} °C</span>
              </div>
              <div class="info-item">
                <span class="label">已采集步数</span>
                <span class="value">{{ experiment.total_steps }}</span>
              </div>
              <div class="info-item">
                <span class="label">采样周期</span>
                <span class="value">{{ experiment.sampling_interval ?? 1.0 }} s</span>
              </div>
              <div class="info-item" style="grid-column: span 2">
                <span class="label">输入CSV路径</span>
                <span class="value" style="font-size:12px;word-break:break-all">{{ experiment.input_csv_path ?? '--' }}</span>
              </div>
              <div class="info-item" style="grid-column: span 2">
                <span class="label">输出CSV路径</span>
                <span class="value" style="font-size:12px;word-break:break-all">{{ experiment.output_csv_path ?? '--' }}</span>
              </div>
              <div class="info-item">
                <span class="label">开始时间</span>
                <span class="value">{{ experiment.start_time ?? '--' }}</span>
              </div>
              <div class="info-item">
                <span class="label">停止时间</span>
                <span class="value">{{ experiment.stop_time ?? '--' }}</span>
              </div>
            </div>
            <div v-if="experiment.error_msg" class="error-msg">
              ⚠ {{ experiment.error_msg }}
            </div>
          </el-card>
        </el-col>

        <!-- 实时读数 + 操作 -->
        <el-col :span="8">
          <el-card shadow="hover" class="control-card">
            <div class="realtime-stats">
              <div class="stat-item">
                <div class="stat-label">当前温度</div>
                <div class="stat-value temp">
                  {{ latestPoint ? latestPoint.actual_temp.toFixed(3) : '--' }} °C
                </div>
              </div>
              <div class="stat-item">
                <div class="stat-label">目标温度</div>
                <div class="stat-value target">
                  {{ experiment.target_temp?.toFixed(1) }} °C
                </div>
              </div>
              <div class="stat-item">
                <div class="stat-label">当前电流</div>
                <div class="stat-value curr">
                  {{ latestPoint ? latestPoint.current_output.toFixed(3) : '--' }} A
                </div>
              </div>
            </div>

            <div class="control-btns">
              <el-button
                v-if="!isRunning"
                type="success"
                :icon="VideoPlay"
                :loading="controlling"
                :disabled="isStopped && experiment.total_steps >= 600"
                style="width:100%;margin-bottom:10px"
                @click="handleStart"
              >
                开始 MPC 控制
              </el-button>
              <el-button
                v-else
                type="danger"
                :icon="VideoPause"
                :loading="controlling"
                style="width:100%;margin-bottom:10px"
                @click="handleStop"
              >
                停止控制
              </el-button>

            </div>
          </el-card>
        </el-col>
      </el-row>

      <!-- MPC 参数展示 -->
      <el-card shadow="hover" class="params-card">
        <template #header>
          <span class="card-title">MPC 控制参数</span>
        </template>
        <div class="params-row" v-if="experiment.mpc_params">
          <span v-for="(v, k) in experiment.mpc_params" :key="k" class="param-chip">
            <span class="param-key">{{ k }}</span>
            <span class="param-val">{{ v }}</span>
          </span>
        </div>
      </el-card>

      <!-- 温度与电流曲线 -->
      <el-card shadow="hover" class="chart-card">
        <template #header>
          <div class="chart-header">
            <span class="card-title">温度与电流曲线</span>
            <span v-if="isRunning" class="live-badge">● 实时更新中</span>
            <div class="chart-toolbar">
              <el-radio-group v-model="viewMode" size="small">
                <el-radio-button value="chart">曲线</el-radio-button>
                <el-radio-button value="table">表格</el-radio-button>
              </el-radio-group>
              <el-button
                v-if="viewMode === 'table' && dataPoints.length"
                size="small"
                :icon="Download"
                @click="downloadCSV"
              >下载 CSV</el-button>
            </div>
          </div>
        </template>
        <div v-if="!dataPoints.length" class="empty-chart">
          <el-empty description="暂无数据，请启动 MPC 控制" :image-size="80" />
        </div>
        <template v-else>
          <div v-if="viewMode === 'chart'" ref="chartRef" class="chart-body" />
          <div v-else class="table-body">
            <el-table :data="dataPoints" size="small" height="320" border stripe>
              <el-table-column prop="step_idx" label="步骤" width="80" align="center" />
              <el-table-column label="实际温度 (°C)" align="right">
                <template #default="{ row }">{{ row.actual_temp.toFixed(3) }}</template>
              </el-table-column>
              <el-table-column label="目标温度 (°C)" align="right">
                <template #default>{{ experiment.target_temp?.toFixed(3) }}</template>
              </el-table-column>
              <el-table-column label="电流输出 (A)" align="right">
                <template #default="{ row }">{{ row.current_output.toFixed(3) }}</template>
              </el-table-column>
            </el-table>
          </div>
        </template>
      </el-card>
    </template>

  </div>
</template>

<style lang="scss" scoped>
.detail-page {
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.page-header {
  display: flex;
  align-items: center;
  gap: 12px;

  .header-title {
    font-size: 16px;
    font-weight: 600;
    color: var(--text-primary);
    flex: 1;
  }
}

.info-row {
  margin: 0 !important;
}

.info-card {
  height: 100%;

  .info-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px 24px;
  }

  .info-item {
    display: flex;
    flex-direction: column;
    gap: 2px;
  }

  .label {
    font-size: 12px;
    color: var(--text-tertiary);
  }

  .value {
    font-size: 14px;
    color: var(--text-primary);
    font-weight: 500;

    &.highlight {
      color: #165dff;
      font-size: 18px;
      font-weight: 700;
    }
  }

  .error-msg {
    margin-top: 12px;
    color: #f56c6c;
    font-size: 13px;
    background: #fff0f0;
    padding: 8px 12px;
    border-radius: 4px;
  }
}

.control-card {
  .realtime-stats {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-bottom: 16px;
  }

  .stat-item {
    text-align: center;
    padding: 10px 8px;
    border-radius: 6px;
    background: var(--bg-page);
  }

  .stat-label {
    font-size: 11px;
    color: var(--text-tertiary);
    margin-bottom: 4px;
  }

  .stat-value {
    font-size: 16px;
    font-weight: 700;

    &.temp { color: #409eff; }
    &.ref  { color: #67c23a; }
    &.curr { color: #e6a23c; }
    &.target { color: #f56c6c; }
  }
}

.params-card {
  .params-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }

  .param-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 10px;
    border-radius: 12px;
    background: var(--primary-light);
    font-size: 12px;

    .param-key {
      color: var(--text-secondary);
    }

    .param-val {
      color: var(--primary);
      font-weight: 600;
    }
  }
}

.chart-card {
  .chart-header {
    display: flex;
    align-items: center;
    gap: 12px;

    .chart-toolbar {
      margin-left: auto;
      display: flex;
      align-items: center;
      gap: 8px;
    }
  }

  .live-badge {
    font-size: 12px;
    color: #67c23a;
    animation: blink 1.2s ease-in-out infinite;
  }

  .empty-chart {
    height: 240px;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .chart-body {
    height: 280px;
    width: 100%;
  }

  .table-body {
    width: 100%;
  }
}

.card-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
}

.report-desc {
  :deep(.el-descriptions__label) {
    width: 140px;
  }
}

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}
</style>
