<template>
  <div class="p-2 water-report-page">
    <el-card shadow="hover">
      <el-form :inline="true" class="query-form">
        <el-form-item label="时间范围">
          <el-date-picker
            v-model="timeRange"
            type="datetimerange"
            value-format="YYYY-MM-DD HH:mm:ss"
            range-separator="至"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            :default-time="defaultTime"
            @change="handleQuery"
          />
        </el-form-item>
        <el-form-item label="时间周期">
          <el-select v-model="selectedInterval" clearable placeholder="全部显示" class="interval-select" @change="handleQuery">
            <el-option v-for="item in intervalOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="能源指标">
          <el-select v-model="selectedMetricId" filterable placeholder="请选择能源指标" class="metric-select" @change="handleQuery">
            <el-option v-for="metric in metricOptions" :key="metric.id" :label="formatMetricLabel(metric)" :value="metric.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="设备">
          <el-select
            v-model="selectedDevices"
            multiple
            collapse-tags
            collapse-tags-tooltip
            filterable
            clearable
            placeholder="请选择设备"
            class="device-select"
            @change="handleQuery"
          >
            <el-option v-for="device in deviceOptions" :key="device.value" :label="device.label" :value="device.value" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>

      <div v-loading="loading" class="chart-wrap">
        <div ref="chartRef" class="line-chart"></div>
        <el-empty v-if="!loading && empty" class="chart-empty" description="暂无用水数据" />
      </div>

      <el-table v-loading="loading" border :data="tableData" class="detail-table" height="360">
        <el-table-column prop="deviceId" label="计量设备编号" min-width="150" />
        <el-table-column prop="deviceName" label="计量设备名称" min-width="150" />
        <el-table-column prop="deviceLocation" label="计量设备位置" min-width="220" show-overflow-tooltip />
        <el-table-column prop="reportTime" label="采集时间" align="center" min-width="160" />
        <el-table-column :label="currentMetricName" align="right" min-width="150">
          <template #default="scope">
            {{ formatMetricValue(scope.row.value) }}
          </template>
        </el-table-column>
      </el-table>
    </el-card>
  </div>
</template>

<script setup name="WaterReport" lang="ts">
import * as echarts from 'echarts';
import { getWaterReport, listWaterDevices } from '@/api/report';
import { WaterDeviceOption, WaterReportSeries } from '@/api/report/types';
import { listEnergyMetric } from '@/api/ems/energyMetric';
import { EnergyMetricVO } from '@/api/ems/energyMetric/types';

const chartRef = ref<HTMLDivElement>();
let chartInstance: echarts.ECharts | undefined;

const loading = ref(false);
const empty = ref(true);
const deviceOptions = ref<WaterDeviceOption[]>([]);
const metricOptions = ref<EnergyMetricVO[]>([]);
const selectedMetricId = ref<string | number>();
const selectedDevices = ref<string[]>([]);
const tableData = ref<any[]>([]);
const timeRange = ref<string[]>([]);
const selectedInterval = ref<number>();
const currentMetricName = ref('水表读数');
const currentMetricUnit = ref('m³');
const defaultTime: [Date, Date] = [new Date(2000, 0, 1, 0, 0, 0), new Date(2000, 0, 1, 23, 59, 59)];
const intervalOptions = [
  { label: '5秒', value: 5 },
  { label: '10秒', value: 10 },
  { label: '15秒', value: 15 },
  { label: '30秒', value: 30 },
  { label: '1分钟', value: 60 },
  { label: '5分钟', value: 300 },
  { label: '10分钟', value: 600 },
  { label: '30分钟', value: 1800 },
  { label: '1小时', value: 3600 },
  { label: '1天', value: 86400 }
];

function pad(value: number) {
  return String(value).padStart(2, '0');
}

function formatDateTime(date: Date) {
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
}

function initDefaultRange() {
  const end = new Date();
  const start = new Date(end.getTime() - 24 * 60 * 60 * 1000);
  timeRange.value = [formatDateTime(start), formatDateTime(end)];
}

function initChart() {
  if (!chartRef.value) {
    return;
  }
  chartInstance = echarts.init(chartRef.value, 'macarons');
}

function renderChart(xAxis: string[], series: WaterReportSeries[]) {
  if (!chartInstance) {
    initChart();
  }
  empty.value = !xAxis.length || !series.some((item) => item.data.some((value) => value !== null && value !== undefined));

  chartInstance?.setOption(
    {
      tooltip: {
        trigger: 'axis',
        valueFormatter: (value: unknown) => (value === null || value === undefined ? '-' : `${Number(value).toFixed(2)} ${currentMetricUnit.value}`)
      },
      legend: {
        type: 'scroll',
        top: 0
      },
      grid: {
        top: 48,
        right: 28,
        bottom: 48,
        left: 58,
        containLabel: true
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: xAxis,
        axisLabel: {
          hideOverlap: true
        }
      },
      yAxis: {
        type: 'value',
        name: `${currentMetricName.value}${currentMetricUnit.value ? `(${currentMetricUnit.value})` : ''}`,
        scale: true
      },
      dataZoom: [
        {
          type: 'inside'
        },
        {
          type: 'slider',
          height: 24,
          bottom: 8
        }
      ],
      series: series.map((item) => ({
        ...item,
        connectNulls: true,
        showSymbol: false,
        emphasis: {
          focus: 'series'
        }
      }))
    },
    true
  );
}

function formatMetricValue(value: unknown) {
  if (value === null || value === undefined || value === '') {
    return '-';
  }
  const numberValue = Number(value);
  return Number.isFinite(numberValue) ? `${numberValue.toFixed(2)}${currentMetricUnit.value ? ` ${currentMetricUnit.value}` : ''}` : value;
}

function formatMetricLabel(metric: EnergyMetricVO) {
  return `${metric.metricName || ''}${metric.unit ? `(${metric.unit})` : ''}`;
}

async function loadMetrics() {
  const res = await listEnergyMetric({ type: '1', pageNum: 1, pageSize: 100 });
  metricOptions.value = (res as any).rows || [];
  selectedMetricId.value = metricOptions.value[0]?.id;
  currentMetricName.value = metricOptions.value[0]?.metricName || currentMetricName.value;
  currentMetricUnit.value = metricOptions.value[0]?.unit || currentMetricUnit.value;
}

async function loadDevices() {
  const res = await listWaterDevices();
  deviceOptions.value = res.data || [];
  selectedDevices.value = deviceOptions.value.slice(0, 5).map((item) => item.value);
}

async function handleQuery() {
  if (!timeRange.value?.length || !selectedMetricId.value || !selectedDevices.value.length) {
    tableData.value = [];
    renderChart([], []);
    return;
  }

  loading.value = true;
  try {
    const res = await getWaterReport({
      beginTime: timeRange.value[0],
      endTime: timeRange.value[1],
      deviceIds: selectedDevices.value.join(','),
      metricId: selectedMetricId.value,
      interval: selectedInterval.value
    });
    currentMetricName.value = res.data.metric?.name || currentMetricName.value;
    currentMetricUnit.value = res.data.metric?.unit || '';
    tableData.value = res.data.records || [];
    renderChart(res.data.xAxis || [], res.data.series || []);
  } finally {
    loading.value = false;
  }
}

async function resetQuery() {
  initDefaultRange();
  selectedInterval.value = undefined;
  selectedMetricId.value = metricOptions.value[0]?.id;
  selectedDevices.value = deviceOptions.value.slice(0, 5).map((item) => item.value);
  await handleQuery();
}

function resizeChart() {
  chartInstance?.resize();
}

onMounted(async () => {
  initDefaultRange();
  await nextTick();
  initChart();
  await loadMetrics();
  await loadDevices();
  await handleQuery();
  window.addEventListener('resize', resizeChart);
});

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeChart);
  chartInstance?.dispose();
  chartInstance = undefined;
});
</script>

<style scoped>
.query-form {
  margin-bottom: 10px;
}

.device-select {
  width: 320px;
}

.metric-select {
  width: 220px;
}

.interval-select {
  width: 140px;
}

.chart-wrap {
  position: relative;
  min-height: 520px;
}

.line-chart {
  width: 100%;
  height: 520px;
}

.chart-empty {
  position: absolute;
  inset: 80px 0 0;
  pointer-events: none;
}

.detail-table {
  margin-top: 12px;
}

@media (max-width: 900px) {
  .device-select,
  .metric-select,
  .interval-select {
    width: 100%;
  }

  .line-chart {
    height: 420px;
  }
}
</style>
