<template>
  <div>
    <div class="sec-title">张力设定模型</div>

    <div class="section-row">
      <!-- ─── 输入面板 ─── -->
      <div class="card" style="flex:0 0 280px;">
        <div class="card-header">参数输入</div>
        <div class="card-body">
          <div class="flex-col">
            <div class="form-field">
              <div class="kv-label">带钢厚度 (mm)</div>
              <input v-model.number="form.thickness" type="number" class="kv-input" step="0.1" min="2.0" max="4.5" />
            </div>
            <div class="form-field">
              <div class="kv-label">带钢宽度 (mm)</div>
              <input v-model.number="form.width" type="number" class="kv-input" step="10" min="800" max="1250" />
            </div>
            <div class="form-field">
              <div class="kv-label">屈服强度 (MPa)</div>
              <input v-model.number="form.yield_strength" type="number" class="kv-input" step="5" min="200" max="600" />
            </div>
            <div class="form-field">
              <div class="kv-label">张力系数</div>
              <input v-model.number="form.tension_coef" type="number" class="kv-input" step="0.01" min="0.1" max="0.5" />
            </div>
            <button class="btn btn-primary fw mt8" :disabled="loading" @click="doCalc">
              {{ loading ? '计算中...' : '计算张力' }}
            </button>
            <button class="btn btn-outline fw" @click="loadPreset">加载默认参数</button>
          </div>
        </div>

        <!-- 结果摘要 -->
        <div v-if="result" class="card-body" style="border-top:1px solid #30363d;">
          <div class="kv-grid">
            <span class="kv-label">T_max</span>
            <span class="kv-value">{{ result.T_max }} <span class="kv-unit">kN</span></span>
            <span class="kv-label">截面积</span>
            <span class="kv-value">{{ result.cross_section_mm2 }} <span class="kv-unit">mm²</span></span>
            <span class="kv-label">焊缝速限</span>
            <span class="kv-value">{{ result.weld_speed_limit }} <span class="kv-unit">m/min</span></span>
            <span class="kv-label">加速附加张力</span>
            <span class="kv-value">{{ result.accel_tension }} <span class="kv-unit">kN</span></span>
          </div>
        </div>
      </div>

      <!-- ─── 张力图示 ─── -->
      <div class="card" style="flex:1;">
        <div class="card-header">张力分布图示</div>
        <div class="card-body">
          <div class="tension-diagram" v-if="result">
            <div
              v-for="(zone, key, idx) in result.zones"
              :key="key"
              class="zone-block"
            >
              <!-- 连接线 -->
              <div
                v-if="idx > 0"
                class="zone-line"
                :style="{ background: lineColor(zone.tension_kN) }"
              ></div>
              <!-- 辊子 -->
              <div class="roller-wrap">
                <div class="roller" :style="{ borderColor: lineColor(zone.tension_kN) }">
                  <span class="roller-label">{{ rollerIcon(key) }}</span>
                </div>
                <div class="zone-name">{{ zone.name_cn }}</div>
                <div class="zone-tension" :style="{ color: lineColor(zone.tension_kN) }">
                  {{ zone.tension_kN }} kN
                </div>
                <div class="zone-ratio">×{{ zone.ratio }}</div>
              </div>
            </div>
          </div>
          <div v-else class="empty-hint">
            输入参数后点击「计算张力」查看张力分布
          </div>
        </div>
      </div>
    </div>

    <!-- ─── 张力明细表 ─── -->
    <div class="card mt8" v-if="result">
      <div class="card-header">各段张力详情</div>
      <div class="table-scroll">
        <table class="data-table">
          <thead>
            <tr>
              <th>工艺段</th>
              <th>名称</th>
              <th>基准系数</th>
              <th>校准系数 K</th>
              <th>设定张力 (kN)</th>
              <th>状态</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(zone, key) in result.zones" :key="key">
              <td class="td-num">{{ key }}</td>
              <td>{{ zone.name_cn }}</td>
              <td class="td-num">{{ zone.ratio }}</td>
              <td class="td-num" :style="{ color: Math.abs(zone.k_cal - 1) > 0.05 ? '#f0a500' : '#8b949e' }">
                {{ zone.k_cal.toFixed(4) }}
                <span v-if="Math.abs(zone.k_cal - 1) > 0.005" style="font-size:10px;">
                  ({{ zone.k_cal > 1 ? '+' : '' }}{{ ((zone.k_cal - 1) * 100).toFixed(1) }}%)
                </span>
              </td>
              <td class="td-num" style="color:#00c8ff;font-weight:600;">{{ zone.tension_kN }}</td>
              <td>
                <span :class="['badge', tensionBadge(zone.tension_kN)]">
                  {{ tensionStatus(zone.tension_kN) }}
                </span>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>

    <!-- ─── 张力模型校准 ─── -->
    <div class="card mt8">
      <div class="card-header">
        张力模型校准（各区段独立）
        <span v-if="calibratedZoneCount > 0" class="ch-badge" style="background:#3a2a00;color:#f0a500;">
          {{ calibratedZoneCount }} 个区段已修正
        </span>
        <button class="btn btn-outline" style="margin-left:auto;padding:2px 10px;font-size:11px;"
          @click="resetCalib">全部重置</button>
      </div>
      <div class="card-body">
        <div class="calib-layout">
          <div class="calib-form">
            <div class="calib-hint">在张力计或张力传感器读数与模型设定值存在系统性偏差时录入修正数据。</div>
            <div class="flex-col" style="gap:8px;margin-top:10px;">
              <div class="form-field">
                <div class="kv-label">测量位置</div>
                <select v-model="calib.zone" class="kv-input">
                  <option value="inlet">入口张力</option>
                  <option value="s1_roller">S1夹送辊</option>
                  <option value="acid_entry">酸洗入口</option>
                  <option value="acid1">1#酸槽</option>
                  <option value="acid2">2#酸槽</option>
                  <option value="acid3">3#酸槽</option>
                  <option value="rinse">漂洗段</option>
                  <option value="leveler">拉矫机</option>
                  <option value="s2_roller">S2夹送辊</option>
                  <option value="outlet">出口张力</option>
                </select>
              </div>
              <div class="form-field">
                <div class="kv-label">实测张力 (kN)</div>
                <input v-model.number="calib.measured_kn" type="number" class="kv-input" step="0.1" min="0" />
              </div>
              <div v-if="result && calib.zone" class="calib-predict-row">
                <span class="kv-label">当前K</span>
                <span class="kv-value" :style="{ color: Math.abs((calib.zone_kcal[calib.zone]||1)-1)>0.05?'#f0a500':'#8b949e' }">
                  {{ (calib.zone_kcal[calib.zone] || 1).toFixed(4) }}
                </span>
                <span class="kv-label" style="margin-left:12px;">预测值</span>
                <span class="kv-value">{{ result.zones[calib.zone] ? result.zones[calib.zone].tension_kN : '—' }} <span class="kv-unit">kN</span></span>
                <span class="kv-label" style="margin-left:12px;">偏差</span>
                <span class="kv-value" v-if="result.zones[calib.zone] && calib.measured_kn"
                  :style="{ color: Math.abs(calib.measured_kn - result.zones[calib.zone].tension_kN) > result.zones[calib.zone].tension_kN * 0.1 ? '#f0a500' : '#28a745' }">
                  {{ (calib.measured_kn - result.zones[calib.zone].tension_kN > 0 ? '+' : '') + (calib.measured_kn - result.zones[calib.zone].tension_kN).toFixed(2) }} kN
                </span>
              </div>
              <div class="form-field">
                <div class="kv-label">备注（可选）</div>
                <input v-model="calib.note" type="text" class="kv-input" />
              </div>
              <button class="btn btn-primary fw" :disabled="calib.loading || !calib.measured_kn" @click="submitCalib">
                {{ calib.loading ? '提交中...' : '提交修正数据' }}
              </button>
            </div>
          </div>
          <div class="calib-history">
            <div class="sec-title" style="margin-bottom:8px;">修正记录</div>
            <table class="data-table">
              <thead>
                <tr><th>时间</th><th>K 前</th><th>K 后</th><th>位置</th><th>实测(kN)</th><th>预测(kN)</th><th>备注</th></tr>
              </thead>
              <tbody>
                <tr v-for="h in tensionHistory" :key="h.ts">
                  <td class="td-muted">{{ h.ts.slice(5,16) }}</td>
                  <td class="td-num">{{ h.k_before }}</td>
                  <td class="td-num" :style="{ color: h.k_after > h.k_before ? '#28a745' : '#f0a500' }">{{ h.k_after }}</td>
                  <td>{{ h.input.zone }}</td>
                  <td class="td-num">{{ h.input.measured_kn }}</td>
                  <td class="td-num">{{ h.input.predicted_kn }}</td>
                  <td class="td-muted">{{ h.note || '—' }}</td>
                </tr>
                <tr v-if="!tensionHistory.length">
                  <td colspan="7" class="td-muted" style="text-align:center;padding:14px;">暂无修正记录</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>

    <!-- ─── 批量张力设定表 ─── -->
    <div class="card mt8">
      <div class="card-header">
        批量张力设定
        <span class="ch-badge">共 {{ batchData.length }} 卷</span>
      </div>
      <div class="table-scroll">
        <table class="data-table">
          <thead>
            <tr>
              <th>卷号</th>
              <th>厚度(mm)</th>
              <th>宽度(mm)</th>
              <th>屈服强度(MPa)</th>
              <th>T_max(kN)</th>
              <th>S1张力(kN)</th>
              <th>酸槽张力(kN)</th>
              <th>S2张力(kN)</th>
              <th>状态</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="row in batchData" :key="row.coil_no">
              <td class="td-num">{{ row.coil_no }}</td>
              <td class="td-num">{{ row.thickness }}</td>
              <td class="td-num">{{ row.width }}</td>
              <td class="td-num">{{ row.yield_strength }}</td>
              <td class="td-num" style="color:#00c8ff;">{{ row.t_max }}</td>
              <td class="td-num">{{ row.s1 }}</td>
              <td class="td-num">{{ row.acid }}</td>
              <td class="td-num">{{ row.s2 }}</td>
              <td>
                <span :class="['badge', row.status === '已确认' ? 'badge-green' : 'badge-yellow']">
                  {{ row.status }}
                </span>
              </td>
            </tr>
            <tr v-if="!batchData.length">
              <td colspan="9" class="td-muted" style="text-align:center;padding:20px;">暂无批量数据</td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template>

<script>
import { predictTension, getCoils, getCalibration, calibrateTension, resetCalibration } from '@/api'

// 钢种屈服强度参考值（MPa）
const YIELD_MAP = { Q195:195, Q215:215, Q235:235, SPHC:280, SPHD:270, SPHE:260, SS400:245, SAPH440:440, QSTE420TM:420 }

export default {
  name: 'TensionModel',
  data() {
    return {
      loading: false,
      form: {
        thickness: 3.0,
        width: 1000,
        yield_strength: 350,
        tension_coef: 0.25,
      },
      result: null,
      batchData: [],
      batchLoading: false,
      calib: {
        zone_kcal: {},
        zone: 's1_roller',
        measured_kn: null,
        note: '',
        loading: false,
      },
      calibHistory: [],
    }
  },
  computed: {
    tensionHistory() {
      return this.calibHistory.filter(h => h.model === 'tension').slice(0, 10)
    },
    calibratedZoneCount() {
      return Object.values(this.calib.zone_kcal).filter(k => Math.abs(k - 1.0) > 0.005).length
    },
  },
  async mounted() {
    await this.doCalc()
    await this.fetchBatch()
    await this.loadCalibration()
  },
  methods: {
    loadPreset() {
      this.form = { thickness: 3.0, width: 1000, yield_strength: 350, tension_coef: 0.25 }
      this.doCalc()
    },
    async fetchBatch() {
      this.batchLoading = true
      try {
        const res = await getCoils({ page_size: 20 })
        const coils = res.data?.items || []
        // 对最近的卷用模型计算张力设定
        this.batchData = coils
          .filter(c => c.thickness && c.width && c.steel_grade)
          .map(c => {
            const ys = YIELD_MAP[c.steel_grade] || 280
            const coef = 0.25
            const tmax = +((coef * ys * c.thickness * c.width) / 1000).toFixed(2)
            return {
              coil_no: c.coil_no,
              thickness: c.thickness,
              width: c.width,
              steel_grade: c.steel_grade,
              yield_strength: ys,
              t_max: tmax,
              s1:   +(tmax * 0.85).toFixed(2),
              acid: +(tmax * 0.72).toFixed(2),
              s2:   +(tmax * 0.88).toFixed(2),
              status: c.status,
            }
          })
      } catch (e) {
        // silent
      } finally {
        this.batchLoading = false
      }
    },
    async doCalc() {
      if (!this.form.thickness || !this.form.width || !this.form.yield_strength) return
      this.loading = true
      try {
        const res = await predictTension(this.form)
        this.result = res.data
      } catch (e) {
        this.$message.error('计算失败：' + (e.response?.data?.detail || e.message))
      } finally {
        this.loading = false
      }
    },
    lineColor(kn) {
      if (!this.result) return '#30363d'
      const ratio = kn / this.result.T_max
      if (ratio >= 0.9) return '#da3633'
      if (ratio >= 0.75) return '#f0a500'
      return '#28a745'
    },
    rollerIcon(key) {
      const icons = {
        inlet: 'IN', s1_roller: 'S1', acid_entry: 'AE',
        acid1: 'A1', acid2: 'A2', acid3: 'A3',
        rinse: 'RI', leveler: 'LV', s2_roller: 'S2', outlet: 'OUT'
      }
      return icons[key] || '—'
    },
    tensionBadge(kn) {
      if (!this.result) return 'badge-gray'
      const r = kn / this.result.T_max
      if (r >= 0.9) return 'badge-red'
      if (r >= 0.75) return 'badge-yellow'
      return 'badge-green'
    },
    tensionStatus(kn) {
      if (!this.result) return '—'
      const r = kn / this.result.T_max
      if (r >= 0.9) return '高张力'
      if (r >= 0.75) return '正常偏高'
      return '正常'
    },
    async loadCalibration() {
      try {
        const res = await getCalibration()
        this.calib.zone_kcal = res.data?.tension_zone_kcal || {}
        this.calibHistory = res.data?.history || []
      } catch (e) { /* silent */ }
    },
    async submitCalib() {
      if (!this.calib.measured_kn) return
      this.calib.loading = true
      try {
        await calibrateTension({
          thickness:      this.form.thickness,
          width:          this.form.width,
          yield_strength: this.form.yield_strength,
          tension_coef:   this.form.tension_coef,
          zone:           this.calib.zone,
          measured_kn:    this.calib.measured_kn,
          note:           this.calib.note,
        })
        this.$message.success('修正数据已提交，张力模型系数已更新')
        this.calib.measured_kn = null
        this.calib.note = ''
        await this.loadCalibration()
        await this.doCalc()
      } catch (e) {
        this.$message.error('提交失败：' + (e.response?.data?.detail || e.message))
      } finally {
        this.calib.loading = false
      }
    },
    async resetCalib() {
      try {
        await this.$confirm('确认将张力模型校准系数重置为 1.0？', '重置确认', { type: 'warning' })
        await resetCalibration('tension')
        this.$message.success('已重置')
        await this.loadCalibration()
        await this.doCalc()
      } catch (e) { /* cancelled */ }
    },
    kCalColor(k) {
      const d = Math.abs(k - 1.0)
      if (d < 0.05) return '#1a3a1f'
      if (d < 0.15) return '#3a2a00'
      return '#3a1a1a'
    },
  }
}
</script>

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

.form-field { display: flex; flex-direction: column; gap: 5px; }
.mt8 { margin-top: 8px; }

.calib-layout {
  display: flex;
  gap: 20px;
  align-items: flex-start;
}
.calib-form {
  flex: 0 0 300px;
}
.calib-history {
  flex: 1;
  overflow-x: auto;
}
.calib-hint {
  font-size: 11px;
  color: $text-muted;
  line-height: 1.6;
  border-left: 2px solid $border;
  padding-left: 8px;
}
.calib-predict-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: rgba(255,255,255,.03);
  border-radius: 4px;
  border: 1px solid $border;
}

.tension-diagram {
  display: flex;
  align-items: center;
  overflow-x: auto;
  padding: 20px 10px;
  gap: 0;
  min-height: 160px;
  &::-webkit-scrollbar { height: 4px; }
  &::-webkit-scrollbar-thumb { background: $border; }
}

.zone-block {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.zone-line {
  width: 32px;
  height: 3px;
  flex-shrink: 0;
  border-radius: 2px;
}

.roller-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.roller {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 2px solid $border;
  background: $bg-panel;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
}

.zone-name {
  font-size: 10px;
  color: $text-secondary;
  text-align: center;
  max-width: 60px;
  white-space: nowrap;
}

.zone-tension {
  font-size: 11px;
  font-family: $font-mono;
  font-weight: 700;
}

.zone-ratio {
  font-size: 10px;
  color: $text-muted;
}

.empty-hint {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 160px;
  color: $text-muted;
  font-size: 13px;
}
</style>
