<template>
  <div class="model-page">
    <el-card shadow="never" class="page-card">
      <div slot="header" class="card-header">
        <span>
          <i class="el-icon-cpu"></i>
          六机架轧制模型 · 当前卷 / 下一卷预测对照
        </span>
        <div class="header-actions">
          <span v-if="updatedAt" class="updated-at">更新于 {{ updatedAt }}</span>
          <el-switch
            v-model="autoRefresh"
            active-text="自动刷新"
            inactive-color="#c0c4cc"
            style="margin: 0 12px;"
          />
          <el-button size="mini" icon="el-icon-refresh" :loading="loading" @click="fetchData">刷新</el-button>
        </div>
      </div>

      <el-alert
        v-if="errorMsg"
        :title="errorMsg"
        type="error"
        show-icon
        :closable="false"
        style="margin-bottom: 16px;"
      />

      <div v-loading="loading && !data" element-loading-text="正在从模型服务拉取数据...">
        <el-empty v-if="!data && !loading && !errorMsg" description="暂无数据，点击右上角「刷新」拉取" />

        <template v-if="data && !data.error">
          <coil-panel title="当前卷" tag-type="success" :coil="data.current" />
          <coil-panel title="下一卷" tag-type="warning" :coil="data.next" style="margin-top: 20px;" />
        </template>

        <el-alert
          v-else-if="data && data.error"
          :title="data.error"
          type="warning"
          show-icon
          :closable="false"
        />
      </div>
    </el-card>
  </div>
</template>

<script>
import { getLatestMillData } from '@/api/l2/mill'

const STATUS_MAP = {
  PRODUCING: { text: '正在轧', type: 'success' },
  READY: { text: 'L2已生成设定值', type: 'primary' },
  ONLINE: { text: '已排队待轧', type: 'warning' },
  PRODUCT: { text: '已轧完', type: 'info' },
}

// 与 klp-ml-mill/predict.py 的 TABLE_COLUMNS 保持一致，跟HMI「模型设定」页面列一致
const COLUMNS = [
  { label: '入口厚度', unit: 'mm', field: 'setup_enthick', fmt: v => fmtNum(v, 3) },
  { label: '压下率', unit: '%', field: 'setup_reduct', fmt: v => fmtNum(v, 0) },
  { label: '轧辊速度', unit: 'm/min', field: 'calc_stand_spd', fmt: v => fmtNum(v, 0) },
  { label: '前滑', unit: '%', field: 'meas_slip', fmt: v => fmtNum(v, 2) },
  { label: '轧制力', unit: 'kN', field: 'calc_force', fmt: v => fmtNum(v, 0) },
  { label: '辊缝', unit: 'mm', field: 'calc_gap_run', fmt: v => fmtNum(v, 2) },
  { label: '工作辊弯辊', unit: 'kN', field: 'mea_wr_bend', fmt: v => fmtNum(v, 0) },
  { label: '中间辊弯辊', unit: 'kN', field: 'mea_ir_bend', fmt: v => fmtNum(v, 0) },
  { label: '张应力', unit: 'MPa', field: 'setup_extension_stress', fmt: v => fmtNum(v, 0) },
  { label: '出口张力', unit: 'kN', field: 'setup_extension_force', fmt: v => fmtNum(v, 0) },
  { label: '负荷', unit: '%', field: 'calc_power_ratio', fmt: v => fmtNum(v, 0) },
]

function fmtNum(v, digits) {
  if (v === null || v === undefined || v === '') return '-'
  const n = Number(v)
  if (Number.isNaN(n)) return '-'
  return n.toFixed(digits)
}

// CoilPanel：一个卷(当前/下一)的展示，L2实测 vs 我们的预测，逐机架对照
const CoilPanel = {
  name: 'CoilPanel',
  props: {
    title: { type: String, required: true },
    tagType: { type: String, default: 'info' },
    coil: { type: Object, default: null },
  },
  computed: {
    statusInfo() {
      const s = this.coil && this.coil.status
      return STATUS_MAP[s] || { text: s || '未知', type: 'info' }
    },
    specText() {
      const s = this.coil && this.coil.spec
      if (!s) return '-'
      return `${s.grade}  ${s.entry_thick} → ${s.exit_thick} mm  宽 ${s.width}`
    },
    // 6机架 x 2行(产线/预测)，空过机架单独一行
    rows() {
      if (!this.coil) return []
      const l2 = this.coil.l2 || {}
      const ours = (this.coil.ours && this.coil.ours.predictions) || {}
      const out = []
      for (let sid = 0; sid < 6; sid++) {
        const oursStand = ours['stand' + sid]
        const l2Stand = l2[String(sid)] || l2[sid]
        const active = oursStand ? oursStand.active !== false : !!l2Stand
        if (!active) {
          out.push({ standLabel: '机架' + (sid + 1), source: '空过', idle: true, rowspan: 1 })
          continue
        }
        out.push({
          standLabel: '机架' + (sid + 1), source: '产线(L2)', rowspan: 2, isFirst: true,
          values: COLUMNS.map(c => (l2Stand ? l2Stand[c.field] : null)),
        })
        out.push({
          standLabel: '机架' + (sid + 1), source: '预测(我们)', rowspan: 0, isFirst: false,
          values: COLUMNS.map(c => {
            const e = oursStand && oursStand[c.field]
            return e && typeof e === 'object' ? e.value : null
          }),
        })
      }
      return out
    },
  },
  methods: {
    objectSpanMethod({ row, columnIndex }) {
      if (columnIndex === 0) {
        if (row.rowspan === 0) return { rowspan: 0, colspan: 0 }
        return { rowspan: row.rowspan, colspan: 1 }
      }
    },
    fmt(row, colIndex) {
      if (row.idle) return '-'
      const raw = row.values[colIndex]
      return COLUMNS[colIndex].fmt(raw)
    },
  },
  render(h) {
    const columns = COLUMNS
    const header = h('div', { class: 'coil-panel-header' }, [
      h('span', { class: 'coil-panel-title' }, [
        h('el-tag', { props: { type: this.tagType, effect: 'dark', size: 'medium' } }, this.title),
      ]),
      this.coil
        ? h('span', { class: 'coil-meta' }, [
            h('b', this.coil.coilid || '-'),
            h('el-tag', { props: { type: this.statusInfo.type, size: 'mini' }, style: 'margin: 0 8px;' }, this.statusInfo.text),
            h('span', { class: 'spec-text' }, this.specText),
          ])
        : null,
    ])

    if (!this.coil) return h('div', { class: 'coil-panel' }, [header, h('el-empty', { props: { description: '暂无数据' } })])

    const notes = []
    if (this.coil.l2_note) notes.push(h('el-alert', {
      props: { title: 'L2实测：' + this.coil.l2_note, type: 'info', showIcon: true, closable: false },
      style: 'margin: 8px 0;',
    }))
    if (this.coil.ours_note) notes.push(h('el-alert', {
      props: { title: '我们的预测：' + this.coil.ours_note, type: 'info', showIcon: true, closable: false },
      style: 'margin: 8px 0;',
    }))

    const tableCols = [
      h('el-table-column', {
        props: { label: '机架', width: '150', align: 'center' },
        scopedSlots: {
          default: ({ row }) => [
            h('div', { class: 'stand-cell' }, [
              h('span', row.standLabel),
              !row.idle ? h('el-tag', {
                props: { size: 'mini', type: row.isFirst ? 'success' : 'primary', effect: row.isFirst ? 'plain' : 'dark' },
                style: 'margin-left: 6px;',
              }, row.source) : h('el-tag', { props: { size: 'mini', type: 'info' } }, '空过'),
            ]),
          ],
        },
      }),
      ...columns.map((c, idx) => h('el-table-column', {
        props: { label: c.label, align: 'right', minWidth: '92' },
        scopedSlots: {
          header: () => [h('div', [h('div', c.label), h('div', { class: 'col-unit' }, c.unit)])],
          default: ({ row }) => [h('span', { class: { 'l2-value': row.isFirst, 'pred-value': row.isFirst === false } }, this.fmt(row, idx))],
        },
      })),
    ]

    return h('div', { class: 'coil-panel' }, [
      header,
      ...notes,
      h('el-table', {
        props: {
          data: this.rows, border: true, size: 'mini', stripe: false,
          spanMethod: this.objectSpanMethod,
          rowClassName: ({ row }) => (row.idle ? 'idle-row' : (row.isFirst ? 'l2-row' : 'pred-row')),
        },
      }, tableCols),
    ])
  },
}

export default {
  name: 'AcidModel',
  components: { CoilPanel },
  data() {
    return {
      loading: false,
      data: null,
      errorMsg: '',
      updatedAt: '',
      autoRefresh: false,
      timer: null,
    }
  },
  watch: {
    autoRefresh(val) {
      if (val) {
        this.timer = setInterval(this.fetchData, 30000)
      } else if (this.timer) {
        clearInterval(this.timer)
        this.timer = null
      }
    },
  },
  created() {
    this.fetchData()
  },
  beforeDestroy() {
    if (this.timer) clearInterval(this.timer)
  },
  methods: {
    async fetchData() {
      this.loading = true
      this.errorMsg = ''
      try {
        this.data = await getLatestMillData()
        this.updatedAt = new Date().toLocaleTimeString('zh-CN', { hour12: false })
      } catch (e) {
        this.errorMsg = (e && e.response && e.response.data && e.response.data.detail) || '获取模型数据失败'
      } finally {
        this.loading = false
      }
    },
  },
}
</script>

<style scoped lang="scss">
.model-page {
  padding: 16px;
  height: calc(100% - 32px);
  overflow-y: auto;
}

.page-card {
  border-radius: 12px;
  border: none;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 600;
  font-size: 15px;
  color: #1f2d3d;

  i {
    color: #409eff;
    margin-right: 6px;
  }
}

.header-actions {
  display: flex;
  align-items: center;

  .updated-at {
    font-size: 12px;
    color: #909399;
    font-weight: normal;
  }
}

::v-deep .coil-panel {
  border: 1px solid #ebeef5;
  border-radius: 10px;
  padding: 16px;
  background: #fafbfc;

  .coil-panel-header {
    display: flex;
    align-items: center;
    margin-bottom: 12px;
    flex-wrap: wrap;
    gap: 10px;
  }

  .coil-meta {
    display: flex;
    align-items: center;
    font-size: 13px;
    color: #606266;

    b {
      color: #1f2d3d;
      margin-right: 4px;
    }

    .spec-text {
      color: #606266;
      background: #fff;
      border: 1px solid #ebeef5;
      border-radius: 4px;
      padding: 2px 8px;
    }
  }

  .stand-cell {
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
  }

  .col-unit {
    font-size: 11px;
    color: #909399;
    font-weight: normal;
  }

  .l2-value {
    color: #1f2d3d;
  }

  .pred-value {
    color: #409eff;
    font-weight: 600;
  }

  .el-table .l2-row {
    background-color: #fff;
  }

  .el-table .pred-row {
    background-color: #ecf5ff;
  }

  .el-table .idle-row {
    background-color: #f4f4f5;
    color: #c0c4cc;
  }
}
</style>
