<template>
  <el-dialog
    title="产品质量报表预览"
    :visible.sync="visible"
    width="880px"
    append-to-body
    :close-on-click-modal="false"
    @open="onOpen"
    @close="onClose"
  >
    <!-- 工具栏 -->
    <div class="rpt-toolbar">
      <span class="rpt-coil-hint">{{ coilLabel }}</span>
      <div class="rpt-toolbar-right">
        <el-button
          size="small"
          type="primary"
          icon="el-icon-download"
          :loading="exporting"
          @click="exportPdf"
        >导出 PDF</el-button>
        <el-button size="small" @click="visible = false">关闭</el-button>
      </div>
    </div>

    <!-- 加载状态 -->
    <div v-if="dataLoading" class="rpt-loading">
      <i class="el-icon-loading" />  正在加载实绩数据…
    </div>

    <!-- 报告主体 -->
    <div v-show="!dataLoading" ref="reportContent" class="report-body">
      <!-- ─── 页眉 ─── -->
      <div class="rpt-header">
        <div class="rpt-header-left">
          <div class="company-line">中国五矿</div>
          <div class="mcc-line">MCC 中冶赛迪信息</div>
        </div>
        <div class="rpt-header-title">产品质量报表</div>
        <div class="rpt-header-right">
          <div class="brand-name">科伦普</div>
          <div class="brand-sub">KE LUN PU</div>
        </div>
      </div>

      <!-- ─── 钢卷规格 ─── -->
      <div class="rpt-section-bar">钢卷规格</div>
      <table class="rpt-table spec-table">
        <tbody>
          <tr>
            <td class="cell-label">钢卷号</td>
            <td class="cell-val cell-coilid">{{ v('hot_coilid') || v('coilid') }}</td>
            <td class="cell-label">来料厚度[mm]</td>
            <td class="cell-val">{{ v('entry_thick') }}</td>
            <td class="cell-label">来料宽度[mm]</td>
            <td class="cell-val">{{ v('entry_width') }}</td>
            <td class="cell-label">来料重量[t]</td>
            <td class="cell-val">{{ v('entry_weight') }}</td>
          </tr>
          <tr>
            <td class="cell-label">钢种</td>
            <td class="cell-val">{{ v('steel_grade') || v('steelgrade') || v('process_code') }}</td>
            <td class="cell-label">成品厚度[mm]</td>
            <td class="cell-val">{{ v('exit_thick') }}</td>
            <td class="cell-label">成品宽度[mm]</td>
            <td class="cell-val">{{ v('exit_width') }}</td>
            <td class="cell-label">成品重量[t]</td>
            <td class="cell-val">{{ v('exit_weight') || v('entry_weight') }}</td>
          </tr>
          <tr>
            <td class="cell-label">班组</td>
            <td class="cell-val">{{ v('shift') || v('class_no') || '—' }}</td>
            <td class="cell-label">偏差上限[mm]</td>
            <td class="cell-val">{{ v('thick_upper') || v('up_tol') || '—' }}</td>
            <td class="cell-label">压下率[%]</td>
            <td class="cell-val">{{ reductionRate }}</td>
            <td class="cell-label">成品长度[m]</td>
            <td class="cell-val">{{ v('exit_length') }}</td>
          </tr>
          <tr>
            <td class="cell-label">下工序</td>
            <td class="cell-val">{{ v('next_process') || v('next_proc') || '—' }}</td>
            <td class="cell-label">偏差下限[mm]</td>
            <td class="cell-val">{{ v('thick_lower') || v('dn_tol') || '—' }}</td>
            <td class="cell-label">原料卷号</td>
            <td class="cell-val" colspan="3">{{ v('coilid') }}</td>
          </tr>
          <tr>
            <td class="cell-label">生产时间</td>
            <td class="cell-val" colspan="3">{{ v('prod_time') || v('start_time') || v('createtime') || '—' }}</td>
            <td class="cell-label">生产时长</td>
            <td class="cell-val" colspan="3">{{ productionDuration }}</td>
          </tr>
        </tbody>
      </table>

      <!-- ─── 质量判定 ─── -->
      <div class="rpt-section-bar">质量判定</div>
      <table class="rpt-table quality-table">
        <thead>
          <tr>
            <th>轧制总长[m]</th>
            <th>头尾超差[m]</th>
            <th>厚度合格率[%]</th>
            <th>目标板形</th>
            <th>板形合格率[%]</th>
            <th>板形质量</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>{{ rolledLength }}</td>
            <td>{{ v('head_tail_dev') || '—' }}</td>
            <td>{{ thickPassRate }}</td>
            <td>{{ v('target_shape') || '平直' }}</td>
            <td>{{ v('shape_pass_rate') || '—' }}</td>
            <td :class="qualityClass">{{ qualityLabel }}</td>
          </tr>
        </tbody>
      </table>

      <!-- ─── 图表区 ─── -->
      <template v-if="hasSeries">
        <!-- 厚度偏差 -->
        <template v-if="hasField('thick_dev') || hasField('act_thick')">
          <div class="rpt-chart-title">
            成品厚度偏差
            <span class="rpt-chart-subtitle">产出厚度 - {{ v('exit_thick') }} [mm]</span>
          </div>
          <div ref="chartThick" class="rpt-chart" />
        </template>

        <!-- 速度趋势 -->
        <template v-if="hasField('plspeed') || hasField('trimspeed') || hasField('millexitspeed')">
          <div class="rpt-chart-title">速度趋势 [m/min]</div>
          <div ref="chartSpeed" class="rpt-chart" />
        </template>

        <!-- 轧机出口速度 -->
        <template v-if="hasField('millexitspeed') && (hasField('plspeed') || hasField('trimspeed'))">
          <div class="rpt-chart-title">轧机出口速度 [m/min]</div>
          <div ref="chartMillSpeed" class="rpt-chart" />
        </template>

        <!-- 张力趋势 -->
        <template v-if="hasField('pltens') || hasField('enltens') || hasField('cxltens')">
          <div class="rpt-chart-title">张力趋势 [N]</div>
          <div ref="chartTension" class="rpt-chart" />
        </template>

        <!-- 额外字段图表 -->
        <template v-for="grp in extraChartGroups">
          <div :key="grp.title + '_t'" class="rpt-chart-title">{{ grp.title }}</div>
          <div :key="grp.title + '_c'" :ref="'chartExtra_' + grp.refKey" class="rpt-chart" />
        </template>
      </template>
      <div v-else class="rpt-no-data">暂无实绩曲线数据</div>

      <!-- ─── 页脚 ─── -->
      <div class="rpt-footer">生成时间：&nbsp;{{ nowStr }}</div>
    </div>
  </el-dialog>
</template>

<script>
import * as echarts from 'echarts'
import { getPlanWithSeg } from '@/api/l2/timing'

// Series fields consumed by named charts — remaining fields get auto-grouped
const NAMED_KEYS = new Set(['startpos', 'thick_dev', 'act_thick', 'plspeed', 'trimspeed', 'millexitspeed', 'pltens', 'enltens', 'cxltens'])

// Groups of extra series fields to chart together
const EXTRA_GROUPS = [
  { keys: ['bendf1', 'bendf2', 'bendf3', 'bendf4', 'bendf5'], title: '弯辊力 [kN]', unit: 'kN' },
  { keys: ['rollf1', 'rollf2', 'rollf3', 'rollf4', 'rollf5'], title: '轧制力 [kN]', unit: 'kN' },
  { keys: ['fwd_slip1', 'fwd_slip2', 'fwd_slip3', 'fwd_slip4', 'fwd_slip5'], title: '前滑值', unit: '' },
  { keys: ['temp_in', 'temp_out', 'cool_temp'], title: '温度 [°C]', unit: '°C' },
]

function lineOption(title, xData, series, yName) {
  return {
    title: { text: title, textStyle: { fontSize: 12, fontWeight: 'normal', color: '#303133' }, top: 4, left: 8 },
    tooltip: { trigger: 'axis', confine: true },
    legend: { top: 4, right: 8, textStyle: { fontSize: 10 } },
    grid: { top: 40, bottom: 32, left: 10, right: 12, containLabel: true },
    xAxis: {
      type: 'category', data: xData, name: '带钢长度[m]',
      nameTextStyle: { fontSize: 10 }, axisLabel: { fontSize: 9, interval: 'auto' }
    },
    yAxis: { type: 'value', name: yName, nameTextStyle: { fontSize: 10 }, axisLabel: { fontSize: 9 } },
    series: series.map((s, i) => ({
      name: s.name, type: 'line', smooth: false, symbol: 'none',
      lineStyle: { width: 1.5 },
      data: s.data
    }))
  }
}

function dualAxisOption(title, xData, devSeries, thickSeries, exitThick) {
  return {
    title: { text: title, textStyle: { fontSize: 12, fontWeight: 'normal', color: '#303133' }, top: 4, left: 8 },
    tooltip: { trigger: 'axis', confine: true },
    legend: { top: 4, right: 8, textStyle: { fontSize: 10 } },
    grid: { top: 40, bottom: 32, left: 10, right: 12, containLabel: true },
    xAxis: {
      type: 'category', data: xData, name: '带钢长度[m]',
      nameTextStyle: { fontSize: 10 }, axisLabel: { fontSize: 9, interval: 'auto' }
    },
    yAxis: [
      { type: 'value', name: 'μm', nameTextStyle: { fontSize: 10 }, axisLabel: { fontSize: 9 } },
      { type: 'value', name: 'mm', nameTextStyle: { fontSize: 10 }, axisLabel: { fontSize: 9 }, splitLine: { show: false } }
    ],
    series: [
      { name: '厚度偏差', type: 'line', yAxisIndex: 0, smooth: false, symbol: 'none', lineStyle: { width: 1, color: '#5F7BA0' }, data: devSeries },
      thickSeries && { name: '实际厚度', type: 'line', yAxisIndex: 1, smooth: false, symbol: 'none', lineStyle: { width: 1.5, color: '#e6a23c' }, data: thickSeries }
    ].filter(Boolean)
  }
}

export default {
  name: 'QualityReportDialog',
  data() {
    return {
      visible:     false,
      dataLoading: false,
      exporting:   false,
      plan:        null,
      series:      null,
      nowStr:      '',
      chartInsts:  []
    }
  },
  computed: {
    coilLabel() {
      const id = this.plan?.hot_coilid || this.plan?.coilid || ''
      return id ? `钢卷号：${id}` : ''
    },
    hasSeries() {
      return !!this.series && Object.keys(this.series).length > 0
    },
    reductionRate() {
      const e = parseFloat(this.plan?.entry_thick)
      const x = parseFloat(this.plan?.exit_thick)
      if (!e || !x || e <= 0) return '—'
      return ((e - x) / e * 100).toFixed(2)
    },
    rolledLength() {
      if (this.plan?.exit_length) return this.plan.exit_length
      if (this.series?.startpos?.length) {
        const max = Math.max(...this.series.startpos.filter(v => v != null))
        return max > 0 ? max.toFixed(1) : '—'
      }
      return '—'
    },
    thickPassRate() {
      const r = this.plan?.thick_pass_rate || this.plan?.thick_passrate
      return r != null ? r : '—'
    },
    qualityLabel() {
      const r = this.plan?.quality || this.plan?.quality_result
      if (r) return r
      const tp = parseFloat(this.thickPassRate)
      if (!isNaN(tp)) return tp >= 99 ? '合格' : '不合格'
      return '—'
    },
    qualityClass() {
      return this.qualityLabel === '合格' ? 'cell-ok' : this.qualityLabel === '不合格' ? 'cell-ng' : ''
    },
    productionDuration() {
      const d = this.plan?.prod_duration || this.plan?.duration
      if (!d) return '—'
      const sec = parseInt(d)
      if (isNaN(sec)) return d
      const h = Math.floor(sec / 3600)
      const m = Math.floor((sec % 3600) / 60)
      const s = sec % 60
      return `${String(h).padStart(2, '0')}时${String(m).padStart(2, '0')}分${String(s).padStart(2, '0')}秒`
    },
    extraChartGroups() {
      if (!this.series) return []
      const result = []
      // first try the predefined groups
      for (const grp of EXTRA_GROUPS) {
        const presentKeys = grp.keys.filter(k => this.hasField(k))
        if (presentKeys.length) {
          result.push({ title: grp.title, unit: grp.unit, keys: presentKeys, refKey: grp.title.replace(/\s/g, '_') })
        }
      }
      // then collect truly unknown keys
      const knownInExtra = new Set(EXTRA_GROUPS.flatMap(g => g.keys))
      const unknown = Object.keys(this.series).filter(k => !NAMED_KEYS.has(k) && !knownInExtra.has(k) && Array.isArray(this.series[k]) && this.series[k].length)
      if (unknown.length) {
        result.push({ title: '其他工艺参数', unit: '', keys: unknown, refKey: 'other' })
      }
      return result
    }
  },
  methods: {
    v(key) {
      const val = this.plan?.[key]
      return val != null && val !== '' ? val : '—'
    },
    hasField(key) {
      return !!(this.series?.[key]?.length)
    },

    // Public: open with a row object
    open(row) {
      this.plan   = row
      this.series = null
      this.visible = true
    },

    onOpen() {
      this.nowStr = new Date().toLocaleString('zh-CN').replace(/\//g, '-')
      this.$nextTick(() => {
        if (this.series) {
          this.renderAllCharts()
        } else if (this.plan) {
          this.fetchSeries()
        }
      })
    },

    onClose() {
      this.disposeCharts()
    },

    async fetchSeries() {
      const id = this.plan?.encoilid || this.plan?.coilid
      if (!id) return
      this.dataLoading = true
      try {
        const res = await getPlanWithSeg(id)
        const plan   = res?.data?.plan   || res?.data?.firstRow || this.plan
        const series = res?.data?.series || null
        if (plan) this.plan = plan
        this.series = series
        this.$nextTick(() => this.renderAllCharts())
      } finally {
        this.dataLoading = false
      }
    },

    disposeCharts() {
      this.chartInsts.forEach(c => { try { c.dispose() } catch (_) {} })
      this.chartInsts = []
    },

    pick(key) {
      return (this.series?.[key] || []).map(v => v == null ? null : +parseFloat(v).toFixed(3))
    },

    xData() {
      return (this.series?.startpos || []).map(v => v == null ? '' : (+parseFloat(v).toFixed(1)))
    },

    renderAllCharts() {
      this.disposeCharts()
      if (!this.series) return
      const x = this.xData()

      // 厚度偏差
      if (this.$refs.chartThick) {
        const devKey = this.hasField('thick_dev') ? 'thick_dev' : null
        const actKey = this.hasField('act_thick') ? 'act_thick' : null
        if (devKey || actKey) {
          const devData = devKey ? this.pick(devKey).map(v => v == null ? null : v * 1000) : []
          const actData = actKey ? this.pick(actKey) : null
          const c = echarts.init(this.$refs.chartThick, null, { renderer: 'canvas' })
          if (devKey) {
            c.setOption(dualAxisOption('成品厚度偏差', x, devData, actData, this.plan?.exit_thick))
          } else {
            c.setOption(lineOption('实际厚度 [mm]', x, [{ name: '实际厚度', data: actData }], 'mm'))
          }
          this.chartInsts.push(c)
        }
      }

      // 速度趋势
      if (this.$refs.chartSpeed) {
        const series = []
        if (this.hasField('plspeed'))    series.push({ name: '轧制速度 plspeed',  data: this.pick('plspeed') })
        if (this.hasField('trimspeed'))  series.push({ name: '剪切速度 trimspeed', data: this.pick('trimspeed') })
        if (!this.hasField('plspeed') && !this.hasField('trimspeed') && this.hasField('millexitspeed')) {
          series.push({ name: '轧机出口速度', data: this.pick('millexitspeed') })
        }
        if (series.length) {
          const c = echarts.init(this.$refs.chartSpeed, null, { renderer: 'canvas' })
          c.setOption(lineOption('速度趋势', x, series, 'm/min'))
          this.chartInsts.push(c)
        }
      }

      // 轧机出口速度（单独显示）
      if (this.$refs.chartMillSpeed && this.hasField('millexitspeed')) {
        const c = echarts.init(this.$refs.chartMillSpeed, null, { renderer: 'canvas' })
        c.setOption(lineOption('轧机出口速度', x, [{ name: 'millexitspeed', data: this.pick('millexitspeed') }], 'm/min'))
        this.chartInsts.push(c)
      }

      // 张力趋势
      if (this.$refs.chartTension) {
        const series = []
        if (this.hasField('pltens'))  series.push({ name: '出口张力 pltens', data: this.pick('pltens') })
        if (this.hasField('enltens')) series.push({ name: '入口张力 enltens', data: this.pick('enltens') })
        if (this.hasField('cxltens')) series.push({ name: 'cxltens',           data: this.pick('cxltens') })
        if (series.length) {
          const c = echarts.init(this.$refs.chartTension, null, { renderer: 'canvas' })
          c.setOption(lineOption('张力趋势', x, series, 'N'))
          this.chartInsts.push(c)
        }
      }

      // 额外图表组
      for (const grp of this.extraChartGroups) {
        const refKey = 'chartExtra_' + grp.refKey
        const refEl  = this.$refs[refKey]
        const el     = Array.isArray(refEl) ? refEl[0] : refEl
        if (!el) continue
        const series = grp.keys.filter(k => this.hasField(k)).map(k => ({ name: k, data: this.pick(k) }))
        if (series.length) {
          const c = echarts.init(el, null, { renderer: 'canvas' })
          c.setOption(lineOption(grp.title, x, series, grp.unit))
          this.chartInsts.push(c)
        }
      }
    },

    async exportPdf() {
      this.exporting = true
      try {
        const [html2canvas, { jsPDF }] = await Promise.all([
          import('html2canvas').then(m => m.default),
          import('jspdf')
        ])

        const el = this.$refs.reportContent
        const canvas = await html2canvas(el, {
          scale: 2,
          useCORS: true,
          allowTaint: true,
          backgroundColor: '#ffffff',
          logging: false
        })

        const imgData  = canvas.toDataURL('image/jpeg', 0.95)
        const pdf      = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' })
        const pageW    = pdf.internal.pageSize.getWidth()   // 210
        const pageH    = pdf.internal.pageSize.getHeight()  // 297
        const margin   = 8
        const printW   = pageW - margin * 2
        const ratio    = canvas.width / printW
        const imgH     = canvas.height / ratio
        let remaining  = imgH
        let srcY       = 0

        while (remaining > 0) {
          const sliceH  = Math.min(pageH - margin * 2, remaining)
          const slicePx = sliceH * ratio
          const sliceCanvas = document.createElement('canvas')
          sliceCanvas.width  = canvas.width
          sliceCanvas.height = slicePx
          const ctx = sliceCanvas.getContext('2d')
          ctx.drawImage(canvas, 0, srcY, canvas.width, slicePx, 0, 0, canvas.width, slicePx)
          pdf.addImage(sliceCanvas.toDataURL('image/jpeg', 0.95), 'JPEG', margin, margin, printW, sliceH)
          srcY      += slicePx
          remaining -= sliceH
          if (remaining > 0) pdf.addPage()
        }

        const coilId = this.plan?.hot_coilid || this.plan?.coilid || 'report'
        pdf.save(`质量报表_${coilId}.pdf`)
      } catch (e) {
        this.$message.error('PDF导出失败：' + e.message)
        console.error(e)
      } finally {
        this.exporting = false
      }
    }
  }
}
</script>

<style scoped>
/* ── 工具栏 ── */
.rpt-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 0 10px;
  border-bottom: 1px solid #f0f2f5;
  margin-bottom: 10px;
}
.rpt-coil-hint { font-size: 13px; color: #606266; font-weight: 500; }
.rpt-toolbar-right { display: flex; gap: 8px; }

/* ── 加载 ── */
.rpt-loading {
  padding: 40px 0;
  text-align: center;
  font-size: 14px;
  color: #909399;
}

/* ── 报告主体 ── */
.report-body {
  background: #fff;
  padding: 20px 24px;
  font-size: 12px;
  color: #303133;
  min-height: 300px;
}

/* 页眉 */
.rpt-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 2px solid #2c5282;
  padding-bottom: 10px;
  margin-bottom: 14px;
}
.rpt-header-left { font-size: 11px; color: #555; line-height: 1.6; }
.company-line { font-weight: 600; font-size: 13px; }
.mcc-line     { font-size: 10px; color: #888; }
.rpt-header-title { font-size: 22px; font-weight: 700; color: #1a365d; letter-spacing: 2px; }
.rpt-header-right { text-align: right; }
.brand-name { font-size: 16px; font-weight: 700; color: #2c5282; letter-spacing: 1px; }
.brand-sub  { font-size: 9px; color: #888; letter-spacing: 2px; }

/* 节标题 */
.rpt-section-bar {
  background: #2c5282;
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 2px;
  margin: 10px 0 6px;
  letter-spacing: 1px;
}

/* 规格表 & 质量判定表 */
.rpt-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 11.5px;
  margin-bottom: 4px;
}
.rpt-table td, .rpt-table th {
  border: 1px solid #c9d4e0;
  padding: 4px 8px;
  text-align: left;
  white-space: nowrap;
}
.rpt-table th {
  background: #dce8f4;
  color: #1a365d;
  font-weight: 600;
  text-align: center;
  font-size: 11px;
}
.cell-label {
  background: #eef3f9;
  color: #4a6080;
  font-weight: 500;
  width: 110px;
}
.cell-val { color: #1a1a2e; font-weight: 600; }
.cell-coilid { font-size: 13px; color: #1a365d; letter-spacing: 0.5px; }
.cell-ok { color: #2e7d32; font-weight: 700; text-align: center; }
.cell-ng { color: #c62828; font-weight: 700; text-align: center; }
.quality-table td { text-align: center; }

/* 图表 */
.rpt-chart-title {
  font-size: 12px;
  font-weight: 600;
  color: #2c5282;
  margin: 14px 0 4px;
  padding-left: 6px;
  border-left: 3px solid #2c5282;
}
.rpt-chart-subtitle {
  font-size: 11px;
  font-weight: normal;
  color: #888;
  margin-left: 8px;
}
.rpt-chart {
  width: 100%;
  height: 180px;
  border: 1px solid #e8edf2;
  border-radius: 3px;
  background: #fafbfc;
}

/* 无数据 */
.rpt-no-data {
  padding: 28px 0;
  text-align: center;
  font-size: 13px;
  color: #c0c4cc;
}

/* 页脚 */
.rpt-footer {
  margin-top: 20px;
  padding-top: 8px;
  border-top: 1px solid #e2e8f0;
  text-align: center;
  font-size: 10px;
  color: #888;
}

/* 覆盖 dialog padding */
::v-deep .el-dialog__body { padding: 12px 20px 20px; }
::v-deep .el-button--primary {
  background: #2c5282 !important; border-color: #2c5282 !important;
}
::v-deep .el-button--primary:hover { background: #1a365d !important; border-color: #1a365d !important; }
</style>
