<template>
  <div class="remind-page" :class="{ embedded: embedded }">
    <header v-if="!embedded" class="remind-header">
      <div class="brand">
        <div class="brand-mark"><i class="el-icon-bell" /></div>
        <div>
          <h1>委外延期 · 生产提醒</h1>
          <p>机加 / 装配 / 铆焊委外延期 · 发出 / 接收记录</p>
        </div>
      </div>
      <div class="header-actions">
        <span class="sync-time" v-if="lastSyncTime"><i class="el-icon-time" /> {{ lastSyncTime }}</span>
        <el-button type="primary" size="mini" icon="el-icon-refresh" :loading="loading" @click="loadData">
          刷新
        </el-button>
      </div>
    </header>

    <main class="transfer-panel">
      <div class="panel-head">
        <div class="head-left">
          <h2>委外发出 / 接收汇总（按订单合并）</h2>
        </div>
        <div class="toolbar">
          <el-select
            v-model="supplierFilter"
            size="mini"
            clearable
            filterable
            placeholder="转出供应商"
            class="supplier-select"
          >
            <el-option
              v-for="name in supplierOptions"
              :key="name"
              :label="name"
              :value="name"
            />
            <el-option label="（无供应商）" value="__EMPTY__" />
          </el-select>
          <el-select v-model="gapFilter" size="mini" clearable placeholder="差额筛选" class="type-select">
            <el-option label="本批未发完" value="qtyDiff" />
            <el-option label="发出未回完" value="returnDiff" />
          </el-select>
          <el-input
            v-model="keyword"
            size="mini"
            clearable
            placeholder="令号 / 订单 / 产品 / 供应商"
            prefix-icon="el-icon-search"
            class="search-input"
          />
        </div>
      </div>

      <div class="table-wrap" ref="tableWrap">
        <el-table
          ref="remindTable"
          v-loading="loading"
          :data="pagedTransfers"
          border
          stripe
          size="mini"
          :height="tableHeight"
          class="remind-table"
          :header-cell-style="headerCellStyle"
          empty-text="暂无委外发出 / 接收汇总数据"
        >
          <el-table-column type="index" label="#" width="44" align="center" fixed :index="transferIndex" />
          <el-table-column prop="moOrderNo" label="生产令号" min-width="120" show-overflow-tooltip fixed>
            <template slot-scope="{ row }">{{ row.moOrderNo || '—' }}</template>
          </el-table-column>
          <el-table-column prop="moBillNo" label="生产订单号" min-width="112" show-overflow-tooltip fixed />
          <el-table-column prop="outSupplierName" label="转出供应商" min-width="150" show-overflow-tooltip>
            <template slot-scope="{ row }">{{ row.outSupplierName || '—' }}</template>
          </el-table-column>
          <el-table-column prop="inSupplierName" label="接收供应商" min-width="150" show-overflow-tooltip>
            <template slot-scope="{ row }">{{ row.inSupplierName || '—' }}</template>
          </el-table-column>
          <el-table-column prop="materialNumber" label="产品编码" min-width="110" show-overflow-tooltip />
          <el-table-column prop="materialName" label="产品名称" min-width="120" show-overflow-tooltip />
          <el-table-column prop="operQty" label="本批数量" width="88" align="right">
            <template slot-scope="{ row }">{{ row.operQty == null || row.operQty === '' ? '—' : formatQtyVal(row.operQty) }}</template>
          </el-table-column>
          <el-table-column prop="operTransferQty" label="发出数量" width="88" align="right">
            <template slot-scope="{ row }">{{ formatQtyVal(row.operTransferQty) }}</template>
          </el-table-column>
          <el-table-column prop="receiveTransferQty" label="接收数量" width="88" align="right">
            <template slot-scope="{ row }">{{ formatQtyVal(row.receiveTransferQty) }}</template>
          </el-table-column>
          <el-table-column prop="qtyDiff" label="本批−发出" width="96" align="right">
            <template slot-scope="{ row }">
              <span :class="diffClass(row.qtyDiff)">{{ formatQtyVal(row.qtyDiff) }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="returnDiff" label="发出−接收" width="96" align="right">
            <template slot-scope="{ row }">
              <span :class="diffClass(row.returnDiff)">{{ formatQtyVal(row.returnDiff) }}</span>
            </template>
          </el-table-column>
          <el-table-column label="最新日期" width="108">
            <template slot-scope="{ row }">{{ formatDate(row.billDate) }}</template>
          </el-table-column>
          <el-table-column prop="inOperNumber" label="委外工序" width="80" align="center">
            <template slot-scope="{ row }">{{ formatOperNo(row.inOperNumber) }}</template>
          </el-table-column>
          <el-table-column prop="processName" label="工序" min-width="110" show-overflow-tooltip />
        </el-table>
      </div>

      <div class="panel-footer">
        <span class="hint">
          共 <b>{{ filteredTransfers.length }}</b> 条
          <template v-if="supplierFilter && supplierFilter !== '__EMPTY__'">
            · 供应商「{{ supplierFilter }}」
          </template>
        </span>
        <el-pagination
          background
          small
          layout="sizes, prev, pager, next"
          :current-page.sync="transferPage"
          :page-size.sync="transferPageSize"
          :page-sizes="[20, 50, 100]"
          :total="filteredTransfers.length"
        />
      </div>
    </main>
  </div>
</template>

<script>
import { getJjSubcontractDelayRemind } from '@/api/system/workCenterData'

export default {
  name: 'ProductionRemind',
  props: {
    /** 嵌入生产提醒（workCenterAlert）时隐藏独立顶栏 */
    embedded: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      loading: false,
      lastSyncTime: '',
      transferRows: [],
      delayMoCount: 0,
      delayRowCount: 0,
      keyword: '',
      gapFilter: '',
      supplierFilter: '',
      transferPage: 1,
      transferPageSize: 50,
      tableHeight: 420,
      headerCellStyle: {
        background: '#1a2332',
        color: '#e8e4dc',
        fontSize: '12px',
        fontWeight: '600',
        borderColor: '#243044'
      }
    }
  },
  computed: {
    supplierOptions() {
      const set = new Set()
      ;(this.transferRows || []).forEach(r => {
        this.splitSuppliers(r && r.outSupplierName).forEach(name => set.add(name))
      })
      return Array.from(set).sort((a, b) => a.localeCompare(b, 'zh-CN'))
    },
    filteredTransfers() {
      let list = this.transferRows || []
      if (this.supplierFilter === '__EMPTY__') {
        list = list.filter(r => this.splitSuppliers(r && r.outSupplierName).length === 0)
      } else if (this.supplierFilter) {
        const selected = this.supplierFilter
        list = list.filter(r => this.splitSuppliers(r && r.outSupplierName).includes(selected))
      }
      if (this.gapFilter === 'qtyDiff') {
        list = list.filter(r => Number(r && r.qtyDiff) > 0)
      } else if (this.gapFilter === 'returnDiff') {
        list = list.filter(r => Number(r && r.returnDiff) > 0)
      }
      const kw = (this.keyword || '').trim().toLowerCase()
      if (kw) {
        list = list.filter(r => {
          const blob = [
            r.moOrderNo, r.moBillNo, r.outSupplierName, r.inSupplierName,
            r.materialNumber, r.materialName, r.processName
          ].map(v => (v == null ? '' : String(v).toLowerCase())).join('|')
          return blob.includes(kw)
        })
      }
      return list
    },
    pagedTransfers() {
      const start = (this.transferPage - 1) * this.transferPageSize
      return this.filteredTransfers.slice(start, start + this.transferPageSize)
    }
  },
  watch: {
    keyword() { this.transferPage = 1 },
    gapFilter() { this.transferPage = 1 },
    supplierFilter() { this.transferPage = 1 },
    filteredTransfers() {
      this.$nextTick(() => this.scheduleTableLayout())
    },
    pagedTransfers() {
      this.$nextTick(() => this.scheduleTableLayout())
    }
  },
  created() {
    if (!this.embedded) {
      this.loadData()
    }
  },
  mounted() {
    this.updateTableHeight()
    window.addEventListener('resize', this.updateTableHeight)
  },
  activated() {
    this.updateTableHeight()
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.updateTableHeight)
    if (this._tableLayoutTimer) {
      clearTimeout(this._tableLayoutTimer)
    }
  },
  methods: {
    scheduleTableLayout() {
      if (this._tableLayoutTimer) {
        clearTimeout(this._tableLayoutTimer)
      }
      this._tableLayoutTimer = setTimeout(() => {
        this.updateTableHeight()
      }, 50)
    },
    updateTableHeight() {
      this.$nextTick(() => {
        const wrap = this.$refs.tableWrap
        if (!wrap) return
        const next = Math.max(wrap.clientHeight || 0, 240)
        if (Math.abs(next - this.tableHeight) > 2) {
          this.tableHeight = next
        }
        const table = this.$refs.remindTable
        if (table && typeof table.doLayout === 'function') {
          table.doLayout()
        }
      })
    },
    normSupplier(val) {
      if (val == null || val === '') return ''
      return String(val).replace(/\u00a0/g, ' ').trim()
    },
    splitSuppliers(val) {
      const raw = this.normSupplier(val)
      if (!raw) return []
      return raw.split(/[、,，;/|]+/).map(s => s.trim()).filter(Boolean)
    },
    normType(val) {
      if (val == null || val === '') return ''
      return String(val).trim().toUpperCase()
    },
    loadData() {
      this.loading = true
      return getJjSubcontractDelayRemind()
        .then(res => {
          const data = (res && res.data) || {}
          this.transferRows = (data.transferRows || []).map(row => ({
            ...row,
            transferType: this.normType(row.transferType) || 'SUM',
            outSupplierName: this.normSupplier(row.outSupplierName) || null,
            inSupplierName: this.normSupplier(row.inSupplierName) || null,
            moBillNo: row.moBillNo != null ? String(row.moBillNo).trim() : row.moBillNo
          }))
          this.delayMoCount = data.delayMoCount || 0
          this.delayRowCount = data.delayRowCount || 0
          this.transferPage = 1
          this.supplierFilter = ''
          this.gapFilter = ''
          this.touchSyncTime()
          this.$emit('loaded', {
            delayRowCount: this.delayRowCount,
            delayMoCount: this.delayMoCount,
            transferCount: this.transferRows.length
          })
        })
        .catch(() => {
          this.transferRows = []
          this.delayMoCount = 0
          this.delayRowCount = 0
          this.$emit('loaded', { delayRowCount: 0, delayMoCount: 0, transferCount: 0 })
        })
        .finally(() => {
          this.loading = false
          this.$nextTick(() => this.updateTableHeight())
        })
    },
    transferIndex(index) {
      return (this.transferPage - 1) * this.transferPageSize + index + 1
    },
    formatQtyVal(val) {
      if (val == null || val === '') return '0'
      const n = Number(val)
      if (!Number.isFinite(n)) return '0'
      return parseFloat(n.toFixed(2))
    },
    diffClass(val) {
      const n = Number(val)
      if (!Number.isFinite(n) || n === 0) return 'diff-zero'
      return n > 0 ? 'diff-pos' : 'diff-neg'
    },
    formatOperNo(val) {
      if (val == null || val === '') return '—'
      const s = String(val)
      return s.endsWith('.0') ? s.slice(0, -2) : s
    },
    formatDate(val) {
      if (val == null || val === '') return '—'
      const s = String(val)
      if (s.includes('T')) return s.substring(0, 10)
      return s.length >= 10 ? s.substring(0, 10) : s
    },
    touchSyncTime() {
      const d = new Date()
      const pad = n => String(n).padStart(2, '0')
      this.lastSyncTime = `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())} 已同步`
    }
  }
}
</script>

<style scoped>
@import url('https://fonts.googleapis.com/css2?family=Barlow:wght@400;500;600;700&family=Barlow+Condensed:wght@600;700&display=swap');

.remind-page {
  --bg: #eceae4;
  --panel: #faf9f6;
  --dark: #1a2332;
  --muted: #5c6573;
  --amber: #d4820a;
  --teal: #1a7a6d;
  --red: #c0392b;
  --border: #c8c4ba;
  height: calc(100vh - 84px);
  display: flex;
  flex-direction: column;
  padding: 0 4px 8px;
  box-sizing: border-box;
  overflow: hidden;
  font-family: 'Barlow', 'Microsoft YaHei', sans-serif;
  color: var(--dark);
  background:
    linear-gradient(135deg, rgba(26, 35, 50, 0.03) 25%, transparent 25%) -20px 0 / 40px 40px,
    var(--bg);
}

.remind-page.embedded {
  flex: 1;
  height: 100%;
  min-height: 0;
  padding: 0;
  background: transparent;
}

.remind-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
  padding: 8px 14px;
  margin-bottom: 8px;
  background: var(--dark);
  border-radius: 4px;
  color: #f0ebe3;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.brand-mark {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: var(--amber);
  color: var(--dark);
  border-radius: 3px;
  font-size: 15px;
}

.brand h1 {
  margin: 0;
  font-family: 'Barlow Condensed', sans-serif;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.03em;
  line-height: 1.2;
}

.brand p {
  margin: 1px 0 0;
  font-size: 11px;
  color: rgba(240, 235, 227, 0.5);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.sync-time {
  font-size: 11px;
  color: rgba(240, 235, 227, 0.5);
}

.transfer-panel {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 8px 10px;
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-shrink: 0;
  margin-bottom: 8px;
}

.head-left {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.panel-head h2 {
  margin: 0;
  font-size: 14px;
  font-family: 'Barlow Condensed', sans-serif;
  letter-spacing: 0.04em;
}

.head-hint {
  font-size: 11px;
  color: var(--muted);
}

.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: flex-end;
}

.search-input { width: 200px; }
.type-select { width: 100px; }
.supplier-select { width: 200px; }

.table-wrap {
  flex: 1;
  min-height: 0;
  height: 0; /* 配合 flex:1，让子表拿到真实高度以冻结表头 */
  overflow: hidden;
}

.remind-table {
  width: 100%;
}

.remind-table >>> .el-table__fixed,
.remind-table >>> .el-table__fixed-right {
  box-shadow: 6px 0 10px rgba(26, 35, 50, 0.08);
}

.remind-table >>> .el-table__header th {
  padding: 6px 0 !important;
}

.remind-table >>> .el-table__header th .cell {
  color: #e8e4dc !important;
  line-height: 1.3;
  padding: 0 8px;
}

.remind-table >>> .el-table__body td {
  padding: 6px 0 !important;
  vertical-align: middle;
}

.remind-table >>> .el-table__body td .cell {
  line-height: 1.35;
  padding: 0 8px;
}

.remind-table >>> .el-table__body tr:hover > td {
  background: rgba(212, 130, 10, 0.06) !important;
}

.mono {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}

.diff-pos {
  color: var(--red);
  font-weight: 700;
}

.diff-neg {
  color: var(--teal);
  font-weight: 600;
}

.diff-zero {
  color: var(--muted);
}

.panel-footer {
  flex-shrink: 0;
  margin-top: 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.hint {
  font-size: 12px;
  color: var(--muted);
}

.hint b {
  color: var(--dark);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: 15px;
}

@media (max-width: 1200px) {
  .panel-head {
    flex-direction: column;
    align-items: stretch;
  }
  .toolbar { justify-content: flex-start; }
}
</style>
