<template>
  <div>
    <!-- ═══════════════════════════════════════ 异常管理 Tab ═══════════════════════════════════════ -->
    <template v-if="activeTab === 'abnormal'">
      <div class="abn-layout">
        <!-- 左侧：钢卷列表 -->
        <div class="abn-sidebar">
          <div class="sidebar-header">
            钢卷列表
            <span class="add-btn" title="刷新" @click="fetchCoils">⟳</span>
          </div>
          <div class="sidebar-search">
            <input v-model="coilQuery.coil_no" class="kv-input" placeholder="搜索卷号..." style="width:100%;" @keyup.enter="fetchCoils" />
          </div>
          <div class="cl-list">
            <div
              v-for="c in coils"
              :key="c.id"
              :class="['cl-item', { active: selectedCoil && selectedCoil.id === c.id }]"
              @click="selectCoil(c)"
            >
              <div class="cl-name">{{ c.sub_coil_no || c.coil_no }}</div>
              <div class="cl-meta">
                <span class="td-muted" style="font-size:10px;">{{ c.steel_grade || '—' }}</span>
                <span class="td-muted" style="font-size:10px;">{{ c.outlet_thickness ? fmtNum(c.outlet_thickness, 2) + '×' + fmtNum(c.outlet_width, 0) : '' }}</span>
              </div>
            </div>
            <div v-if="!coils.length" class="cl-empty">暂无钢卷</div>
          </div>
        </div>

        <!-- 右侧：异常管理面板 -->
        <div class="abn-main">
          <div v-if="!selectedCoil" class="empty-tip">请选择钢卷</div>

          <template v-else>
            <!-- 钢卷信息 -->
            <div class="card">
              <div class="card-header" style="display:flex;align-items:center;justify-content:space-between;">
                <span>钢卷信息</span>
                <button class="btn btn-outline" style="padding:2px 10px;font-size:11px;" @click="reloadCoil">⟳ 刷新</button>
              </div>
              <div class="card-body">
                <div class="kv-grid">
                  <div class="kv-cell"><span class="kv-label">子卷号</span><span class="kv-value">{{ selectedCoil.sub_coil_no || selectedCoil.coil_no || '—' }}</span></div>
                  <div class="kv-cell"><span class="kv-label">热卷号</span><span class="kv-value">{{ selectedCoil.hot_coil_no || '—' }}</span></div>
                  <div class="kv-cell"><span class="kv-label">钢种</span><span class="kv-value">{{ selectedCoil.steel_grade || '—' }}</span></div>
                  <div class="kv-cell"><span class="kv-label">班/组</span><span class="kv-value">{{ (selectedCoil.shift || '—') + ' / ' + (selectedCoil.team != null ? selectedCoil.team : '—') }}</span></div>
                  <div class="kv-cell"><span class="kv-label">规格[mm]</span><span class="kv-value">{{ specStr }}</span></div>
                  <div class="kv-cell"><span class="kv-label">来料厚度[mm]</span><span class="kv-value">{{ fmtNum(selectedCoil.incoming_thickness, 2) }}</span></div>
                  <div class="kv-cell"><span class="kv-label">出口厚度[mm]</span><span class="kv-value">{{ fmtNum(selectedCoil.outlet_thickness, 2) }}</span></div>
                  <div class="kv-cell"><span class="kv-label">来料宽度[mm]</span><span class="kv-value">{{ fmtNum(selectedCoil.incoming_width, 0) }}</span></div>
                  <div class="kv-cell"><span class="kv-label">出口宽度[mm]</span><span class="kv-value">{{ fmtNum(selectedCoil.outlet_width, 0) }}</span></div>
                  <div class="kv-cell"><span class="kv-label">来料重量[t]</span><span class="kv-value">{{ fmtNum(selectedCoil.incoming_weight, 3) }}</span></div>
                  <div class="kv-cell"><span class="kv-label">称重重量[t]</span><span class="kv-value">{{ fmtNum(selectedCoil.weighed_weight, 3) }}</span></div>
                  <div class="kv-cell"><span class="kv-label">成品长度[m]</span><span class="kv-value">{{ fmtNum(selectedCoil.product_length, 0) }}</span></div>
                  <div class="kv-cell"><span class="kv-label">吨钢长度</span><span class="kv-value">{{ fmtNum(selectedCoil.length_per_ton, 2) }}</span></div>
                  <div class="kv-cell"><span class="kv-label">下线时间</span><span class="kv-value">{{ fmtTime(selectedCoil.offline_time) }}</span></div>
                  <div class="kv-cell"><span class="kv-label">状态</span><span class="kv-value">{{ statusLabel(selectedCoil.status) }}</span></div>
                  <div class="kv-cell"><span class="kv-label">备注</span><span class="kv-value">{{ selectedCoil.remark || '—' }}</span></div>
                </div>
              </div>
            </div>

            <!-- 异常记录 -->
            <div class="card">
              <div class="card-header" style="display:flex;align-items:center;justify-content:space-between;">
                <span>异常记录 <span class="ch-badge">{{ defects.length }} 行</span></span>
                <div class="flex-row" style="gap:8px;">
                  <button class="btn btn-primary" style="padding:2px 14px;font-size:11px;" :disabled="saving" @click="saveDefects">{{ saving ? '保存中...' : '保存' }}</button>
                  <button class="btn btn-outline" style="padding:2px 12px;font-size:11px;" @click="openInherit">继承</button>
                  <button class="btn btn-outline" style="padding:2px 10px;font-size:11px;" @click="addDefectRow">＋ 新增行</button>
                  <button class="btn btn-outline" style="padding:2px 10px;font-size:11px;" @click="loadDefects">⟳ 刷新</button>
                </div>
              </div>
              <div class="table-scroll">
                <table class="data-table abn-table">
                  <thead>
                    <tr>
                      <th style="width:48px;">序号</th>
                      <th style="min-width:140px;">缺陷描述</th>
                      <th style="width:90px;">开始位置</th>
                      <th style="width:90px;">结束位置</th>
                      <th style="width:70px;">长度</th>
                      <th style="width:140px;">上下版面</th>
                      <th style="width:180px;">断面位置</th>
                      <th style="width:160px;">缺陷代码</th>
                      <th style="width:110px;">程度</th>
                      <th style="width:90px;">继承来源</th>
                      <th style="width:60px;">主缺陷</th>
                      <th style="min-width:120px;">缺陷图片</th>
                      <th style="width:60px;">操作</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr v-for="(d, idx) in defects" :key="idx">
                      <td class="td-num">{{ idx + 1 }}</td>
                      <td><input v-model="d.defect_desc" class="kv-input" style="width:100%;" placeholder="请输入缺陷描述" /></td>
                      <td><input v-model.number="d.start_position" type="number" class="kv-input" style="width:100%;" /></td>
                      <td><input v-model.number="d.end_position" type="number" class="kv-input" style="width:100%;" /></td>
                      <td class="td-num">{{ computeLen(d) }}</td>
                      <td>
                        <label class="ck"><input type="checkbox" v-model="d.upper_surface" />上板面</label>
                        <label class="ck"><input type="checkbox" v-model="d.lower_surface" />下板面</label>
                        <a class="all-link" @click="setAll(d, ['upper_surface','lower_surface'])">全选</a>
                      </td>
                      <td>
                        <label class="ck"><input type="checkbox" v-model="d.side_op" />操作侧</label>
                        <label class="ck"><input type="checkbox" v-model="d.side_middle" />中间</label>
                        <label class="ck"><input type="checkbox" v-model="d.side_drive" />驱动侧</label>
                        <a class="all-link" @click="setAll(d, ['side_op','side_middle','side_drive'])">全选</a>
                      </td>
                      <td>
                        <label v-for="opt in defectCodeOptions" :key="opt.value" class="rd">
                          <input type="radio" :value="opt.value" v-model="d.defect_code" />{{ opt.label }}
                        </label>
                      </td>
                      <td>
                        <label v-for="opt in degreeOptions" :key="opt.value" class="rd">
                          <input type="radio" :value="opt.value" v-model="d.degree" />{{ opt.label }}
                        </label>
                      </td>
                      <td class="td-muted" style="text-align:center;">{{ d.inherit_source || '—' }}</td>
                      <td style="text-align:center;"><input type="checkbox" v-model="d.is_main" /></td>
                      <td>
                        <div v-if="d.image_url" class="img-thumb">
                          <img :src="d.image_url" @click="imgPreview = d.image_url" />
                          <span class="img-del" @click="d.image_url = ''">✕</span>
                        </div>
                        <label v-else class="img-up">
                          <input type="file" accept="image/*" style="display:none;" @change="onPickImage(d, $event)" />
                          ＋ 上传
                        </label>
                      </td>
                      <td>
                        <span class="action-link" @click="clearRow(d)">清空</span>
                        <span class="action-link" style="color:#da3633;" @click="removeRow(idx)">删除</span>
                      </td>
                    </tr>
                    <tr v-if="!defects.length">
                      <td colspan="13" class="td-muted" style="text-align:center;padding:18px;">暂无数据</td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
          </template>
        </div>
      </div>
    </template>

    <!-- ─── 图片预览 ─── -->
    <div v-if="imgPreview" class="img-mask" @click="imgPreview = ''">
      <img :src="imgPreview" class="img-full" />
    </div>

    <!-- ─── 继承来源选择弹窗 ─── -->
    <div v-if="inheritDialog.visible" class="modal-mask" @click.self="inheritDialog.visible=false">
      <div class="modal-box" style="width:420px;">
        <div class="modal-header">继承缺陷 — 选择来源钢卷<span class="modal-close" @click="inheritDialog.visible=false">✕</span></div>
        <div class="modal-body">
          <div class="form-field">
            <div class="kv-label">来源钢卷</div>
            <select v-model="inheritDialog.source" class="kv-input">
              <option value="">请选择</option>
              <option v-for="c in coils" :key="c.id" :value="coilKey(c)" v-show="coilKey(c) !== selectedCoilNo">{{ coilKey(c) }} · {{ c.steel_grade || '—' }}</option>
            </select>
          </div>
        </div>
        <div class="modal-footer">
          <button class="btn btn-outline" @click="inheritDialog.visible=false">取消</button>
          <button class="btn btn-primary" @click="doInherit">确定继承</button>
        </div>
      </div>
    </div>

  </div>
</template>

<script>
import {
  getProductionRecords,
  getQcDefectsByCoil, bulkSaveQcDefects,
} from '@/api'

const DEFECT_CODES = [
  { value: 'S', label: '表面缺陷（S）' },
  { value: 'E', label: '边部问题（E）' },
  { value: 'M', label: '尺寸问题（M）' },
  { value: 'G', label: '收卷问题（G）' },
  { value: 'F', label: '版型问题（F）' },
]

const DEGREES = [
  { value: 'light',   label: '轻微' },
  { value: 'medium',  label: '中度' },
  { value: 'serious', label: '严重' },
]

function blankDefect() {
  return {
    defect_desc: '',
    start_position: 0,
    end_position: 0,
    upper_surface: false,
    lower_surface: false,
    side_op: false,
    side_middle: false,
    side_drive: false,
    defect_code: '',
    degree: '',
    is_main: false,
    inherit_source: '',
    image_url: '',
  }
}

export default {
  name: 'Quality',
  data() {
    return {
      activeTab: 'abnormal',
      saving: false,
      selectedCoilNo: '',
      inheritDialog: { visible: false, source: '' },
      imgPreview: '',

      coils: [],
      coilQuery: { coil_no: '', page: 1, page_size: 100 },
      selectedCoil: null,
      defects: [],

      defectCodeOptions: DEFECT_CODES,
      degreeOptions: DEGREES,
    }
  },
  computed: {
    specStr() {
      const c = this.selectedCoil || {}
      if (c.outlet_thickness && c.outlet_width) return `${Number(c.outlet_thickness).toFixed(2)}*${Number(c.outlet_width).toFixed(0)}`
      return '—'
    },
  },
  created() { this.fetchCoils() },
  methods: {
    // ── 异常管理 ──────────────────────────────────
    async fetchCoils() {
      try {
        const params = { page: 1, page_size: 100 }
        if (this.coilQuery.coil_no) params.coil_no = this.coilQuery.coil_no
        const res = await getProductionRecords(params)
        this.coils = res.data.items || []
      } catch (e) { this.coils = [] }
    },
    coilKey(c) { return c ? (c.sub_coil_no || c.coil_no) : '' },
    async selectCoil(c) {
      this.selectedCoil = c
      this.selectedCoilNo = this.coilKey(c)
      await this.loadDefects()
    },
    openInherit() {
      if (!this.selectedCoil) return
      this.inheritDialog = { visible: true, source: '' }
    },
    async doInherit() {
      const src = this.inheritDialog.source
      if (!src) { this.$message.error('请选择继承来源钢卷'); return }
      try {
        const res = await getQcDefectsByCoil(src)
        const rows = (res.data || []).map(d => ({
          defect_desc: d.defect_desc || '',
          start_position: d.start_position || 0,
          end_position: d.end_position || 0,
          upper_surface: !!d.upper_surface, lower_surface: !!d.lower_surface,
          side_op: !!d.side_op, side_middle: !!d.side_middle, side_drive: !!d.side_drive,
          defect_code: d.defect_code || '', degree: d.degree || '',
          is_main: !!d.is_main, inherit_source: src, image_url: d.image_url || '',
        }))
        if (!rows.length) { this.$message.warning('来源钢卷无缺陷记录'); return }
        this.defects = rows
        this.inheritDialog.visible = false
        this.$message.success(`已继承 ${rows.length} 条缺陷`)
      } catch (e) { this.$message.error('继承失败') }
    },
    async reloadCoil() {
      await this.fetchCoils()
      if (this.selectedCoil) {
        const fresh = this.coils.find(c => c.id === this.selectedCoil.id)
        if (fresh) this.selectedCoil = fresh
      }
    },
    async loadDefects() {
      if (!this.selectedCoil) return
      try {
        const res = await getQcDefectsByCoil(this.coilKey(this.selectedCoil))
        this.defects = (res.data || []).map(d => ({
          defect_desc: d.defect_desc || '',
          start_position: d.start_position || 0,
          end_position: d.end_position || 0,
          upper_surface: !!d.upper_surface,
          lower_surface: !!d.lower_surface,
          side_op: !!d.side_op,
          side_middle: !!d.side_middle,
          side_drive: !!d.side_drive,
          defect_code: d.defect_code || '',
          degree: d.degree || '',
          is_main: !!d.is_main,
          inherit_source: d.inherit_source || '',
          image_url: d.image_url || '',
        }))
      } catch (e) { this.defects = [] }
    },
    addDefectRow() { this.defects.push(blankDefect()) },
    removeRow(i) { this.defects.splice(i, 1) },
    clearRow(d) { Object.assign(d, blankDefect()) },
    setAll(d, keys) {
      const allOn = keys.every(k => d[k])
      keys.forEach(k => { d[k] = !allOn })
    },
    computeLen(d) {
      const s = parseFloat(d.start_position); const e = parseFloat(d.end_position)
      if (isNaN(s) || isNaN(e)) return 0
      const v = +(e - s).toFixed(3)
      return v
    },
    async saveDefects() {
      if (!this.selectedCoil) return
      this.saving = true
      try {
        const list = this.defects.map((d, i) => ({
          seq_no: i + 1,
          defect_desc: d.defect_desc || null,
          start_position: d.start_position != null ? Number(d.start_position) : null,
          end_position: d.end_position != null ? Number(d.end_position) : null,
          length_val: this.computeLen(d),
          upper_surface: !!d.upper_surface,
          lower_surface: !!d.lower_surface,
          side_op: !!d.side_op,
          side_middle: !!d.side_middle,
          side_drive: !!d.side_drive,
          defect_code: d.defect_code || null,
          degree: d.degree || null,
          is_main: !!d.is_main,
          inherit_source: d.inherit_source || null,
          image_url: d.image_url || null,
        })).filter(d => d.defect_desc || d.defect_code || d.start_position || d.end_position)
        await bulkSaveQcDefects({ coil_no: this.coilKey(this.selectedCoil), defects: list })
        this.$message.success('保存成功')
        await this.loadDefects()
      } catch (e) {
        this.$message.error('保存失败')
      } finally { this.saving = false }
    },

    onPickImage(d, e) {
      const file = e.target.files && e.target.files[0]
      e.target.value = ''
      if (!file) return
      const reader = new FileReader()
      reader.onload = () => {
        const img = new Image()
        img.onload = () => {
          const max = 640
          let { width, height } = img
          if (width > max || height > max) {
            const r = Math.min(max / width, max / height)
            width = Math.round(width * r); height = Math.round(height * r)
          }
          const canvas = document.createElement('canvas')
          canvas.width = width; canvas.height = height
          canvas.getContext('2d').drawImage(img, 0, 0, width, height)
          d.image_url = canvas.toDataURL('image/jpeg', 0.8)
        }
        img.src = reader.result
      }
      reader.readAsDataURL(file)
    },
    // ── 工具 ─────────────────────────────────────
    fmtTime(t) { return t ? t.slice(0, 16).replace('T', ' ') : '—' },
    fmtNum(v, n = 2) { return v != null && v !== '' ? Number(v).toFixed(n) : '—' },
    statusLabel(s) { return ({ UNWEIGH: '未称重', PRODUCT: '已产出' })[s] || s || '—' },
  },
}
</script>

<style lang="scss" scoped>
@import '@/assets/styles/variables';

.tab-bar {
  display: flex;
  margin-bottom: 14px;
  border-bottom: 2px solid $border;
}
.tab-item {
  padding: 8px 20px;
  font-size: 13px;
  cursor: pointer;
  color: $text-muted;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
  transition: all .15s;
  &:hover { color: $text-primary; }
  &.active { color: $sms-highlight; border-bottom-color: $sms-highlight; font-weight: 600; }
}

/* ─── 异常管理布局 ─── */
.abn-layout { display: flex; gap: 14px; align-items: flex-start; }
.abn-sidebar {
  width: 220px; flex-shrink: 0;
  background: $bg-card; border: 1px solid $border; border-radius: 6px;
  display: flex; flex-direction: column; height: calc(100vh - 120px);
}
.sidebar-header {
  padding: 10px 12px; font-size: 12px; font-weight: 600; color: $sms-highlight;
  border-bottom: 1px solid $border; background: $bg-panel;
  display: flex; align-items: center; justify-content: space-between;
}
.sidebar-search { padding: 8px 10px; border-bottom: 1px solid $border; }
.add-btn { cursor: pointer; color: $sms-highlight; font-size: 14px; &:hover { opacity: .7; } }
.cl-list { flex: 1; overflow-y: auto; }
.cl-item { padding: 8px 12px; cursor: pointer; border-bottom: 1px solid rgba($border, .5);
  &:hover { background: rgba($sms-teal, .05); }
  &.active { background: rgba($sms-teal, .08); border-left: 3px solid $sms-teal; }
}
.cl-name { font-size: 12px; color: $text-primary; margin-bottom: 3px; }
.cl-meta { display: flex; gap: 6px; }
.cl-empty { padding: 20px; text-align: center; font-size: 12px; color: $text-muted; }

.abn-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 14px; }
.empty-tip { padding: 60px; text-align: center; color: $text-muted; font-size: 13px;
  background: $bg-card; border: 1px solid $border; border-radius: 6px; }

/* 钢卷信息网格：5列 */
.kv-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 8px 14px;
}
.kv-cell { display: flex; align-items: center; gap: 6px; font-size: 12px; min-width: 0; }
.kv-cell .kv-label { color: $text-muted; flex-shrink: 0; }
.kv-cell .kv-value { color: $text-primary; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 异常表格 */
.abn-table { table-layout: auto; font-size: 12px; }
.abn-table th, .abn-table td { padding: 6px 6px; vertical-align: middle; }
.abn-table .kv-input { font-size: 12px; padding: 3px 6px; }
.abn-table .ck { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; margin-right: 6px; cursor: pointer; }
.abn-table .rd { display: flex; align-items: center; gap: 4px; font-size: 11px; line-height: 1.7; cursor: pointer; }
.abn-table .all-link { display: block; font-size: 10px; color: $sms-highlight; cursor: pointer; margin-top: 2px;
  &:hover { text-decoration: underline; } }
.abn-table input[type="checkbox"], .abn-table input[type="radio"] {
  accent-color: $sms-teal; width: 14px; height: 14px; margin: 0; cursor: pointer; flex-shrink: 0;
}

/* 缺陷图片：上传/预览 */
.img-up {
  display: inline-block; padding: 4px 10px; font-size: 11px; cursor: pointer;
  border: 1px dashed $border-light; border-radius: 4px; color: $text-secondary; background: $bg-input;
  &:hover { border-color: $sms-teal; color: $sms-teal; }
}
.img-thumb { position: relative; display: inline-block;
  img { width: 56px; height: 42px; object-fit: cover; border: 1px solid $border; border-radius: 4px; cursor: zoom-in; display: block; }
  .img-del { position: absolute; top: -7px; right: -7px; width: 16px; height: 16px; line-height: 15px; text-align: center;
    background: $accent-red; color: #fff; border-radius: 50%; font-size: 10px; cursor: pointer; }
}
.img-mask { position: fixed; inset: 0; background: rgba(0,0,0,.8); display: flex; align-items: center; justify-content: center; z-index: 10000; cursor: zoom-out; }
.img-full { max-width: 88vw; max-height: 88vh; border-radius: 4px; box-shadow: 0 8px 40px rgba(0,0,0,.5); }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; }
.form-field { display: flex; flex-direction: column; gap: 5px; }
.action-link { color: $sms-highlight; cursor: pointer; font-size: 11px; margin-right: 8px; &:hover { text-decoration: underline; } }
.modal-mask { position: fixed; inset: 0; background: rgba(0,0,0,.6); display: flex; align-items: center; justify-content: center; z-index: 9999; }
.modal-box { background: $bg-card; border: 1px solid $border; border-radius: 6px; max-width: 96vw; max-height: 92vh; display: flex; flex-direction: column; }
.modal-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; background: $bg-panel; border-bottom: 1px solid $border; font-size: 13px; font-weight: 600; color: $sms-highlight; .modal-close { cursor: pointer; color: $text-muted; &:hover { color: $text-primary; } } }
.modal-body { padding: 16px; overflow-y: auto; }
.modal-footer { padding: 10px 16px; background: $bg-panel; border-top: 1px solid $border; display: flex; justify-content: flex-end; gap: 10px; }
</style>
