<template>
  <div class="app-container">
    <el-card shadow="never" class="mb-2">
      <el-form :model="queryParams" inline label-width="90px">
        <el-form-item label="开始日期">
          <el-date-picker v-model="queryParams.beginDate" type="date" value-format="YYYY-MM-DD" placeholder="选择开始日期" :disabled-date="disableBeginDate" />
        </el-form-item>
        <el-form-item label="结束日期">
          <el-date-picker v-model="queryParams.endDate" type="date" value-format="YYYY-MM-DD" placeholder="选择结束日期" :disabled-date="disableEndDate" />
        </el-form-item>
        <el-form-item label="工序">
          <el-select v-model="queryParams.processId" filterable placeholder="请选择工序" style="width:220px">
            <el-option v-for="p in processList" :key="p.processId" :label="p.processName" :value="p.processId" />
          </el-select>
        </el-form-item>
        <el-form-item label="机台">
          <el-select v-model="queryParams.machineId" filterable placeholder="请选择机台" style="width:220px" clearable>
            <el-option v-for="m in machineList" :key="m.machineId" :label="m.machineName" :value="m.machineId" />
          </el-select>
        </el-form-item>
        <el-form-item label="班次">
          <el-select v-model="queryParams.shiftId" filterable placeholder="请选择班次" style="width:220px" clearable>
            <el-option v-for="s in shiftList" :key="s.shiftId" :label="s.shiftName" :value="s.shiftId" />
          </el-select>
        </el-form-item>
        <el-form-item label="班组">
          <el-select v-model="queryParams.classTeamId" filterable placeholder="请选择班组" style="width:220px" clearable>
            <el-option v-for="t in teamList" :key="t.classTeamId" :label="t.teamName" :value="t.classTeamId" />
          </el-select>
        </el-form-item>
        <el-form-item label="物料">
          <el-input v-model="queryParams.materialName" placeholder="输入物料名称模糊查询" style="width:220px" clearable />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
          <el-button @click="resetQuery">重置</el-button>
          <el-button type="success" @click="handleExportExcel">导出Excel</el-button>
          <el-button @click="handleExportCsv">导出CSV</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-row :gutter="12" class="mb-2">
      <el-col :span="24">
        <el-card shadow="hover" class="h-100">
          <template #header>
            <div class="card-header">小时产量趋势图（按完成时间小时分布）</div>
          </template>
          <div ref="trendChartRef" style="height: 360px"></div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="12">
      <el-col :span="24">
        <el-card shadow="hover">
          <template #header>
            <div class="card-header">小时产量统计分析表（按完成时间小时分布）</div>
          </template>
          <el-table :data="pivotTableData" border height="520" :cell-style="cellStyle">
            <el-table-column type="index" label="序号" width="70" align="center" />
            <el-table-column prop="item" label="项目" width="150" />
            <el-table-column prop="timeRange" label="时间段" width="220" />
            <el-table-column prop="avg" label="平均" width="100">
              <template #default="scope">{{ formatNumber(scope.row.avg) }}</template>
            </el-table-column>
            <el-table-column v-for="d in dateCols" :key="d" :label="formatDateLabel(d)" :prop="d" min-width="90">
              <template #default="scope">{{ formatNumber(scope.row[d]) }}</template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, getCurrentInstance, watch } from 'vue';
import * as echarts from 'echarts';
import dayjs from 'dayjs';
import { hourlyOutputByHour } from '@/api/mes/prodReport';
import { getProcessInfoList } from '@/api/mes/baseProcessInfo';
import { getProdBaseMachineInfoList } from '@/api/mes/prodBaseMachineInfo';
import { getBaseShiftInfoList } from '@/api/mes/baseShiftInfo';
import { getBaseClassTeamInfoList } from '@/api/mes/baseClassTeamInfo';

const { proxy } = getCurrentInstance() as any;

const queryParams = reactive({
  beginDate: '',
  endDate: '',
  processId: undefined as number | undefined,
  machineId: undefined as number | undefined,
  shiftId: undefined as number | undefined,
  classTeamId: undefined as number | undefined,
  materialName: ''
});

const processList = ref<any[]>([]);
const machineList = ref<any[]>([]);
const shiftList = ref<any[]>([]);
const teamList = ref<any[]>([]);

// 仅按实际完成时间(create_time)的小时进行统计展示
function pad2(n: number | string): string { return String(n).padStart(2, '0'); }
const hours = Array.from({ length: 24 }, (_, i) => pad2(i)); // ["00",...,"23"]
function hourRangeLabel(hh: string): string {
  const next = pad2((Number(hh) + 1) % 24);
  return `${hh}:00:00 ~ ${next}:00:00`;
}

const trendChartRef = ref<HTMLDivElement | null>(null);
let trendChart: echarts.ECharts | null = null;

// 透视数据
const dateCols = ref<string[]>([]);
const pivotTableData = ref<any[]>([]);
let rawList: any[] = [];

function normalizeHour(h: string): string {
  if (!h) return '';
  const hh = h.includes(':') ? h.split(':')[0] : h;
  return hh.padStart(2, '0');
}

function buildDateRange(begin: string, end: string) {
  const res: string[] = [];
  let cur = dayjs(begin).startOf('day');
  const endD = dayjs(end).startOf('day');
  while (cur.isBefore(endD) || cur.isSame(endD)) {
    res.push(cur.format('YYYY-MM-DD'));
    cur = cur.add(1, 'day');
  }
  return res;
}

function buildPivot(list: any[]) {
  const dates = buildDateRange(queryParams.beginDate, queryParams.endDate);
  dateCols.value = dates;
  const rows = hours.map((hh, idx) => ({
    _seq: idx + 1,
    item: `${hh}:00`,
    timeRange: hourRangeLabel(hh),
    key: hh,
    avg: 0,
    ...Object.fromEntries(dates.map(d => [d, 0]))
  }));
  const mapByDateHour = new Map<string, number>();
  list.forEach((it) => {
    const d = it.productionDate; // YYYY-MM-DD
    const hh = normalizeHour(it.hourSlot);
    const qty = Number(it.productionQuantity || 0);
    mapByDateHour.set(`${d}_${hh}`, (mapByDateHour.get(`${d}_${hh}`) || 0) + qty);
  });
  rows.forEach(row => {
    dates.forEach(d => {
      const qty = mapByDateHour.get(`${d}_${row.key}`) || 0;
      row[d] = qty;
    });
    const values = dates.map(d => Number(row[d] || 0));
    const sum = values.reduce((a, b) => a + b, 0);
    row.avg = values.length ? sum / values.length : 0;
  });
  const totalRow: any = { item: '合计', timeRange: '', avg: 0 };
  const averageRow: any = { item: '平均', timeRange: '', avg: 0 };
  dates.forEach(d => {
    const sum = rows.reduce((acc, r) => acc + Number(r[d] || 0), 0);
    const avg = rows.length ? sum / rows.length : 0;
    totalRow[d] = sum;
    averageRow[d] = avg;
  });
  const sumOfRowAvg = rows.reduce((acc, r) => acc + Number(r.avg || 0), 0);
  totalRow.avg = sumOfRowAvg;
  averageRow.avg = dates.length ? (dates.reduce((a, d) => a + Number(totalRow[d] || 0), 0) / dates.length) : 0;
  pivotTableData.value = [...rows, totalRow, averageRow];
}

function updateTrendChart() {
  const dates = dateCols.value;
  if (!trendChart && trendChartRef.value) trendChart = echarts.init(trendChartRef.value);
  const series = hours.map(hh => ({
    name: `${hh}:00`,
    type: 'line',
    smooth: true,
    data: dates.map(d => {
      const row = pivotTableData.value.find((r: any) => r.key === hh);
      return row ? Number(row[d] || 0) : 0;
    })
  }));
  trendChart?.setOption({
    tooltip: { trigger: 'axis' },
    legend: { type: 'scroll', top: 10 },
    grid: { left: 40, right: 40, bottom: 30, containLabel: true },
    xAxis: { type: 'category', data: dates.map(d => formatDateLabel(d)) },
    yAxis: { type: 'value', name: '产量' },
    series
  });
}

function handleQuery() {
  if (!queryParams.processId || !queryParams.beginDate || !queryParams.endDate) {
    proxy.$modal.msgWarning('请选择工序并设置时间范围');
    return;
  }
  // 限制查询时间范围最多31天且结束日期不得早于开始日期
  const begin = dayjs(queryParams.beginDate);
  const end = dayjs(queryParams.endDate);
  if (end.isBefore(begin)) {
    proxy.$modal.msgWarning('结束日期不能早于开始日期');
    return;
  }
  if (end.diff(begin, 'day') > 31) {
    proxy.$modal.msgWarning('时间范围最多为31天，请调整开始/结束日期');
    return;
  }
  // 班次等筛选为可选过滤项，严禁强制选择
  hourlyOutputByHour(queryParams).then((res: any) => {
    rawList = (res?.data) || [];
    buildPivot(rawList);
    updateTrendChart();
  });
}

function resetQuery() {
  Object.assign(queryParams, { beginDate: '', endDate: '', processId: undefined, machineId: undefined, shiftId: undefined, classTeamId: undefined, materialName: '' });
  pivotTableData.value = [];
  dateCols.value = [];
  updateTrendChart();
}

function formatDateLabel(d: string) {
  return dayjs(d).format('YYYY-MM-DD');
}

function formatNumber(v: any) {
  const n = Number(v || 0);
  return n % 1 === 0 ? n : n.toFixed(1);
}

// 限制日期选择：开始日期不能晚于结束日期且最多相差31天；结束日期不能早于开始日期且最多相差31天
function disableBeginDate(date: Date) {
  if (!queryParams.endDate) return false;
  const end = dayjs(queryParams.endDate);
  const d = dayjs(date);
  return d.isAfter(end) || end.diff(d, 'day') > 31;
}
function disableEndDate(date: Date) {
  if (!queryParams.beginDate) return false;
  const begin = dayjs(queryParams.beginDate);
  const d = dayjs(date);
  return d.isBefore(begin) || d.diff(begin, 'day') > 31;
}

async function loadDicts() {
  try {
    const [pRes, sRes, tRes] = await Promise.all([
      getProcessInfoList({}),
      getBaseShiftInfoList({}),
      getBaseClassTeamInfoList({})
    ]);
    processList.value = pRes?.data || [];
    shiftList.value = sRes?.data || [];
    teamList.value = tRes?.data || [];
    await loadMachinesByProcess();
  } catch (e) {
    console.error('加载筛选项失败', e);
  }
}

async function loadMachinesByProcess() {
  try {
    const params: any = {};
    if (queryParams.processId) params.processId = queryParams.processId;
    const mRes = await getProdBaseMachineInfoList(params);
    machineList.value = mRes?.data || [];
  } catch (e) {
    console.error('加载机台失败', e);
    machineList.value = [];
  }
}

watch(() => queryParams.processId, async () => {
  queryParams.machineId = undefined;
  await loadMachinesByProcess();
});

// 移除与“关键时段/班次判定”相关的任何自动刷新逻辑

function handleExportExcel() {
  proxy?.download('/mes/prodReport/hourlyOutputByHour/export', { ...queryParams }, `小时产量报表_${Date.now()}.xlsx`);
}

function handleExportCsv() {
  const headers = ['序号','项目','时间段','平均', ...dateCols.value.map(d => formatDateLabel(d))];
  const bodyRows = pivotTableData.value.map((row: any, idx: number) => {
    const isSummary = row.item === '合计' || row.item === '平均';
    const seq = isSummary ? '' : String(idx + 1);
    const vals = dateCols.value.map(d => formatNumber(row[d]));
    return [seq, row.item, row.timeRange || '', formatNumber(row.avg), ...vals];
  });
  const csvContent = [headers.join(','), ...bodyRows.map(r => r.join(','))].join('\n');
  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `小时产量统计_${Date.now()}.csv`;
  a.click();
  window.URL.revokeObjectURL(url);
}

function onResize() {
  trendChart?.resize();
}

function cellStyle({ row }: any) {
  if (row.item === '合计' || row.item === '平均') {
    return { fontWeight: 600 };
  }
  return {};
}

onMounted(() => {
  queryParams.endDate = dayjs().format('YYYY-MM-DD');
  queryParams.beginDate = dayjs(queryParams.endDate).subtract(14, 'day').format('YYYY-MM-DD');
  loadDicts();
  window.addEventListener('resize', onResize);
});

onUnmounted(() => {
  window.removeEventListener('resize', onResize);
  trendChart?.dispose();
  trendChart = null;
});
</script>

<style scoped>
.app-container { padding: 12px; }
.mb-2 { margin-bottom: 12px; }
.h-100 { height: 100%; }
.card-header { font-weight: 600; }
</style>