<template>
  <div class="p-2 compare-report-page">
    <el-row :gutter="12">
      <el-col :xs="24" :md="7" :lg="6">
        <el-card shadow="hover" class="side-card">
          <el-form label-position="top">
            <el-form-item label="能源类型">
              <el-select v-model="deviceType" class="w-full" @change="handleDeviceTypeChange">
                <el-option v-for="dict in device_type" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
          </el-form>
          <el-tree
            ref="nodeTreeRef"
            class="node-tree"
            :data="nodeTree"
            node-key="nodeKey"
            show-checkbox
            default-expand-all
            check-strictly
            :props="{ label: 'name', children: 'children', disabled: 'disabled' }"
          />
        </el-card>
      </el-col>

      <el-col :xs="24" :md="17" :lg="18">
        <el-card shadow="hover" class="filter-card">
          <el-form :inline="true">
            <el-form-item label="对比方式">
              <el-checkbox-group v-model="compareTypes">
                <el-checkbox-button label="yoy">同比</el-checkbox-button>
                <el-checkbox-button label="mom">环比</el-checkbox-button>
              </el-checkbox-group>
            </el-form-item>
            <el-form-item label="时间类型">
              <el-select v-model="timeType" class="time-type" @change="handleTimeTypeChange">
                <el-option label="时" value="hour" />
                <el-option label="日" value="day" />
                <el-option label="月" value="month" />
                <el-option label="年" value="year" />
                <el-option label="班组" value="shift" />
              </el-select>
            </el-form-item>
            <el-form-item v-if="timeType === 'hour' || timeType === 'shift'" label="日期">
              <el-date-picker v-model="dateValue" type="date" value-format="YYYY-MM-DD" />
            </el-form-item>
            <el-form-item v-else-if="timeType === 'day'" label="月份">
              <el-date-picker v-model="dateValue" type="month" value-format="YYYY-MM" />
            </el-form-item>
            <el-form-item v-else-if="timeType === 'month'" label="年份">
              <el-date-picker v-model="dateValue" type="year" value-format="YYYY" />
            </el-form-item>
            <el-form-item v-else label="年份区间">
              <el-input-number v-model="startYear" :min="2000" :max="2100" controls-position="right" />
              <span class="range-separator">至</span>
              <el-input-number v-model="endYear" :min="2000" :max="2100" controls-position="right" />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="loadReport">查询</el-button>
            </el-form-item>
          </el-form>
        </el-card>

        <el-card shadow="hover" class="chart-card">
          <div v-loading="loading" class="chart-wrap">
            <div ref="chartRef" class="chart"></div>
            <el-empty v-if="!loading && empty" class="chart-empty" description="暂无对比数据" />
          </div>
        </el-card>

        <div class="summary-grid">
          <el-card v-for="item in summaryCards" :key="item.type" shadow="hover" class="summary-card">
            <div class="summary-left">
              <el-icon class="summary-icon">
                <TrendCharts />
              </el-icon>
              <div class="summary-percent" :class="{ down: item.percent < 0 }">{{ item.percent }}%</div>
            </div>
            <div class="summary-right">
              <div class="summary-title">{{ item.label }}</div>
              <div class="summary-values">
                <div>当前时间：{{ item.currentTotal.toFixed(2) }} {{ unit }}</div>
                <div>对比时间：{{ item.compareTotal.toFixed(2) }} {{ unit }}</div>
              </div>
            </div>
          </el-card>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script setup name="CompareReport" lang="ts">
import * as echarts from 'echarts';
import { TrendCharts } from '@element-plus/icons-vue';
import { getCompareReport } from '@/api/report';
import { listFloorInfo } from '@/api/system/floor';
import { FloorInfoVO } from '@/api/system/floor/types';

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { device_type } = toRefs<any>(proxy?.useDict('device_type'));

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

const deviceType = ref<string | number>('2');
const nodeTree = ref<any[]>([]);
const compareTypes = ref<string[]>(['yoy']);
const timeType = ref<'hour' | 'day' | 'month' | 'year' | 'shift'>('day');
const dateValue = ref('');
const startYear = ref(new Date().getFullYear());
const endYear = ref(new Date().getFullYear());
const loading = ref(false);
const empty = ref(true);
const valueName = ref('用电量');
const unit = ref('kWh');
const summaryCards = ref<Array<{ type: string; label: string; percent: number; currentTotal: number; compareTotal: number }>>([]);

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

function initDateValue() {
  const now = new Date();
  if (timeType.value === 'day') dateValue.value = `${now.getFullYear()}-${pad(now.getMonth() + 1)}`;
  else if (timeType.value === 'month') dateValue.value = String(now.getFullYear());
  else dateValue.value = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;
  startYear.value = now.getFullYear();
  endYear.value = now.getFullYear();
}

function normalizeNodeTree(rows: FloorInfoVO[]): any[] {
  return rows
    .map((row) => {
      const children = normalizeNodeTree(row.children || []);
      if (row.isDevice === '1') {
        if (String(row.deviceType || '') !== String(deviceType.value)) return null;
        return {
          id: row.id,
          nodeKey: String(row.id),
          name: row.name || row.deviceId,
          isDevice: row.isDevice,
          deviceId: row.deviceId,
          deviceType: row.deviceType,
          disabled: false,
          children: []
        };
      }
      if (!children.length) return null;
      return {
        id: row.id,
        nodeKey: `node_${row.id}`,
        name: row.name,
        isDevice: row.isDevice,
        isDeviceGroup: row.isDeviceGroup,
        disabled: row.isDeviceGroup !== '1',
        children
      };
    })
    .filter(Boolean);
}

async function loadTree() {
  const res = await listFloorInfo();
  nodeTree.value = normalizeNodeTree((res as any).rows || []);
}

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

function renderChart(data: any) {
  initChart();
  const series: any[] = [
    {
      name: data.current.periodLabel,
      type: 'bar',
      barMaxWidth: 34,
      data: data.current.values
    }
  ];
  data.comparisons.forEach((item: any) => {
    series.push({
      name: item.periodLabel,
      type: 'line',
      smooth: true,
      symbolSize: 6,
      data: item.values
    });
  });
  empty.value = !series.some((item) => (item.data || []).some((value: number | null) => value !== null && Number(value) !== 0));
  chart?.setOption(
    {
      tooltip: { trigger: 'axis', valueFormatter: (value: unknown) => `${Number(value || 0).toFixed(2)} ${unit.value}` },
      legend: { top: 0 },
      grid: { top: 54, left: 48, right: 24, bottom: 42 },
      xAxis: { type: 'category', data: data.xAxis },
      yAxis: { type: 'value', name: `${valueName.value}(${unit.value})` },
      series
    },
    true
  );
}

async function loadReport() {
  const checkedNodes = (nodeTreeRef.value?.getCheckedNodes?.() || []).filter((node: any) => !node.disabled && node.id);
  const nodeIds = checkedNodes.map((node: any) => node.id);
  if (!nodeIds.length || !compareTypes.value.length) {
    renderChart({ xAxis: [], current: { periodLabel: '', values: [] }, comparisons: [] });
    summaryCards.value = [];
    return;
  }
  loading.value = true;
  try {
    const res = await getCompareReport({
      deviceType: deviceType.value,
      nodeIds: nodeIds.join(','),
      compareTypes: compareTypes.value.join(','),
      timeType: timeType.value,
      date: dateValue.value,
      startYear: startYear.value,
      endYear: endYear.value
    });
    valueName.value = res.data.valueName;
    unit.value = res.data.unit;
    summaryCards.value = res.data.comparisons.map((item) => ({
      type: item.type,
      label: item.label,
      percent: item.percent,
      currentTotal: res.data.current.total,
      compareTotal: item.total
    }));
    renderChart(res.data);
  } finally {
    loading.value = false;
  }
}

async function handleDeviceTypeChange() {
  nodeTreeRef.value?.setCheckedKeys?.([]);
  await loadTree();
}

function handleTimeTypeChange() {
  initDateValue();
}

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

onMounted(async () => {
  initDateValue();
  await loadTree();
  await nextTick();
  initChart();
  window.addEventListener('resize', resizeChart);
});

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

<style scoped>
.side-card,
.filter-card,
.chart-card {
  margin-bottom: 12px;
}

.node-tree {
  max-height: 640px;
  overflow: auto;
}

.time-type {
  width: 100px;
}

.range-separator {
  margin: 0 8px;
}

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

.chart {
  width: 100%;
  height: 460px;
}

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

.summary-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.summary-card {
  min-height: 132px;
}

.summary-card :deep(.el-card__body) {
  display: grid;
  grid-template-columns: 128px minmax(0, 1fr);
  align-items: center;
  gap: 18px;
  height: 100%;
}

.summary-title {
  margin-bottom: 12px;
  font-weight: 600;
}

.summary-left {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 92px;
  border-right: 1px solid var(--el-border-color-lighter);
}

.summary-right {
  min-width: 0;
}

.summary-icon {
  color: var(--el-color-primary);
  font-size: 34px;
}

.summary-percent {
  color: var(--el-color-success);
  font-size: 28px;
  font-weight: 700;
}

.summary-percent.down {
  color: var(--el-color-danger);
}

.summary-values {
  color: var(--el-text-color-regular);
  line-height: 1.8;
  text-align: left;
}

@media (max-width: 900px) {
  .summary-grid {
    grid-template-columns: 1fr;
  }

  .summary-card :deep(.el-card__body) {
    grid-template-columns: 112px minmax(0, 1fr);
  }
}
</style>
