<template>
  <div class="app-container material-doc-hub">
    <div class="search-panel">
      <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="76px">
        <el-form-item label="生产令号" prop="sclh">
          <el-input
            v-model="queryParams.sclh"
            placeholder="留空查全部，可输入令号筛选"
            clearable
            style="width: 280px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" size="mini" :loading="loading" @click="handleQuery">查询</el-button>
          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </div>

    <el-card v-if="total > 0 || loaded" class="summary-card" shadow="never">
      <div class="summary-row">
        <span v-if="queryParams.sclh">令号：<b>{{ queryParams.sclh }}</b></span>
        <span v-else>范围：<b>全部工单</b></span>
        <el-tag size="mini">共 {{ total }} 条</el-tag>
        <el-tag size="mini" type="info">当前页 {{ projectList.length }} 条</el-tag>
      </div>
    </el-card>

    <el-table
      v-loading="loading"
      class="project-table"
      :data="projectList"
      row-key="projectId"
      ref="projectTable"
      border
      size="small"
      :empty-text="emptyTableText"
    >
      <el-table-column type="expand">
        <template slot-scope="projectScope">
          <div class="kanban-wrap">
            <div v-if="!projectScope.row._loaded && !projectScope.row._loading" class="kanban-load-bar">
              <span class="kanban-load-hint">共 {{ projectScope.row.processCount || 0 }} 道工序，点击下方按钮加载</span>
              <el-button type="primary" plain size="mini" @click="loadProjectDetail(projectScope.row)">加载工序计划</el-button>
            </div>
            <div v-else v-loading="projectScope.row._loading" class="kanban-body">
              <div v-if="!projectScope.row._loading && !(projectScope.row.processes || []).length" class="kanban-empty">
                暂无工序计划
              </div>
              <div v-else class="kanban-scroll">
              <div
                v-for="stage in projectScope.row.processes"
                :key="stage.stageKey"
                class="kanban-col"
              >
                <div class="kanban-col__head">
                  <div class="kanban-col__head-main">
                    <div class="kanban-col__title">
                      <span class="kanban-col__oper">工序 {{ stage.operNo }}</span>
                      {{ stage.processName || '-' }}
                    </div>
                    <div class="kanban-col__wc">{{ stage.workCenter || '工作中心未知' }}</div>
                  </div>
                  <el-button type="text" size="mini" class="kanban-col__action" @click.stop="openProcessDetail(projectScope.row, stage)">详情</el-button>
                </div>
                <div class="kanban-card" @click="openProcessDetail(projectScope.row, stage)">
                  <div class="kanban-card__top">
                    <div class="kanban-progress">
                      <el-progress
                        :percentage="stage.progressPct"
                        type="circle"
                        :width="52"
                        :stroke-width="6"
                        :color="stage.progressColor"
                        :show-text="false"
                      />
                      <span class="kanban-progress__text">{{ stage.progressPct }}%</span>
                    </div>
                    <div class="kanban-card__meta">
                      <div class="kanban-kv"><span class="kanban-k">计划</span><span class="kanban-v">{{ displayVal(stage.planQty) }}</span></div>
                      <div class="kanban-kv"><span class="kanban-k">转入</span><span class="kanban-v">{{ displayVal(stage.inQty) }}</span></div>
                      <div class="kanban-kv"><span class="kanban-k">转出</span><span class="kanban-v">{{ displayVal(stage.transOutQty) }}</span></div>
                      <div class="kanban-kv"><span class="kanban-k">汇报</span><span class="kanban-v">{{ displayVal(stage.reportQty) }}</span></div>
                      <div class="kanban-kv">
                        <span class="kanban-k">状态</span>
                        <el-tag size="mini" effect="plain" :type="processStatusType(stage.materialStatus)">{{ stage.materialStatus || '-' }}</el-tag>
                      </div>
                    </div>
                  </div>
                  <div class="kanban-card__bottom">
                    <span class="kanban-time">{{ stage.operPlanStartTime || '-' }} ~ {{ stage.operPlanFinishTime || '-' }}</span>
                    <span v-if="stage.delayDays" class="kanban-delay">逾期 {{ stage.delayDays }} 天</span>
                  </div>
                </div>
              </div>
            </div>
            </div>
          </div>
        </template>
      </el-table-column>

      <el-table-column type="index" label="#" width="50" align="center" :index="indexMethod" />
      <el-table-column label="生产令号" prop="moOrderNo" min-width="130" show-overflow-tooltip />
      <el-table-column label="产品 / 工单" min-width="260" show-overflow-tooltip>
        <template slot-scope="scope">
          <div class="proj-main">
            <div class="proj-title">
              <span class="proj-name">{{ scope.row.productName || '-' }}</span>
              <span class="proj-code">{{ scope.row.productCode || '-' }}</span>
            </div>
            <div class="proj-sub">
              <el-tag size="mini" type="info" effect="plain">MO {{ scope.row.moBillNo || '-' }}</el-tag>
              <el-tag size="mini" effect="plain">{{ scope.row.processCount || 0 }} 道工序</el-tag>
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="数量" prop="qty" width="80" align="center" />
      <el-table-column label="工序" min-width="120" align="center">
        <template slot-scope="scope">
          <span v-if="scope.row.processCount" class="cell-link">{{ scope.row.processCount }} 道 · 展开查看</span>
          <span v-else class="cell-sub">-</span>
        </template>
      </el-table-column>
      <el-table-column label="当前阶段" min-width="100" show-overflow-tooltip>
        <template slot-scope="scope">{{ currentStageLabel(scope.row) }}</template>
      </el-table-column>
      <el-table-column label="操作" width="80" fixed="right" align="center">
        <template slot-scope="scope">
          <el-button type="text" size="mini" @click="toggleRowExpand(scope.row)">展开</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      :page-sizes="[10, 20, 50, 100]"
      @pagination="getList"
    />

    <el-drawer class="hub-drawer" :visible.sync="drawerOpen" direction="btt" size="62%" append-to-body>
      <template slot="title">
        <div class="hub-drawer__title-line">
          <span class="hub-drawer__title-main">工序汇报</span>
          <span class="hub-drawer__title-kv">{{ processContext.moOrderNo }}</span>
          <span class="hub-drawer__title-kv">MO {{ processContext.moBillNo }}</span>
          <span class="hub-drawer__title-kv">工序 {{ processContext.operNo }} · {{ processContext.processName }}</span>
          <span class="hub-drawer__title-kv hub-drawer__title-product">{{ processContext.productName }}</span>
        </div>
      </template>

      <div class="hub-drawer__summary">
        <span>工序号 {{ processContext.operNo }}</span>
        <span>工作中心 {{ processContext.workCenter || '-' }}</span>
        <span>计划 {{ displayVal(processContext.planQty) }}</span>
        <span>汇报 {{ displayVal(processContext.reportQty) }}</span>
      </div>

      <div class="hub-drawer__actions">
        <el-button size="mini" type="primary" plain :loading="reportsLoading" @click="loadReports">加载工序汇报</el-button>
        <el-button size="mini" type="warning" plain :loading="instockLoading" @click="loadInstockQc">加载入库/质检</el-button>
        <el-button size="mini" type="success" plain :loading="subcontractLoading" @click="loadSubcontract">加载委外 C/G</el-button>
      </div>

      <el-tabs v-model="drawerTab" type="card">
        <el-tab-pane label="工序数量" name="qty">
          <el-descriptions :column="3" border size="small">
            <el-descriptions-item label="转入数量">{{ displayVal(processContext.inQty) }}</el-descriptions-item>
            <el-descriptions-item label="转出数量">{{ displayVal(processContext.transOutQty) }}</el-descriptions-item>
            <el-descriptions-item label="汇报数量">{{ displayVal(processContext.reportQty) }}</el-descriptions-item>
            <el-descriptions-item label="工废数量">{{ displayVal(processContext.scrapQty) }}</el-descriptions-item>
            <el-descriptions-item label="工序状态">{{ processContext.operStatus || '-' }}</el-descriptions-item>
            <el-descriptions-item label="物料状态">{{ processContext.materialStatus || '-' }}</el-descriptions-item>
            <el-descriptions-item label="计划开始">{{ processContext.operPlanStartTime || '-' }}</el-descriptions-item>
            <el-descriptions-item label="计划完成">{{ processContext.operPlanFinishTime || '-' }}</el-descriptions-item>
            <el-descriptions-item label="逾期天数">{{ processContext.delayDays || '-' }}</el-descriptions-item>
          </el-descriptions>
        </el-tab-pane>
        <el-tab-pane :label="'工序汇报 (' + reportList.length + ')'" name="reports">
          <el-table :data="reportList" size="mini" border height="calc(62vh - 220px)" empty-text="点击上方「加载工序汇报」查询">
            <el-table-column label="汇报单号" prop="FBillNo" min-width="130" show-overflow-tooltip />
            <el-table-column label="工序号" prop="FOperNumber" width="72" align="center" />
            <el-table-column label="工序说明" prop="FOperDescription" min-width="120" show-overflow-tooltip />
            <el-table-column label="完工" prop="FFinishQty" width="72" align="center" />
            <el-table-column label="合格" prop="FQuaQty" width="72" align="center" />
            <el-table-column label="工废" prop="FProcessFailQty" width="72" align="center" />
            <el-table-column label="料废" prop="FMaterialFailQty" width="72" align="center" />
            <el-table-column label="单据日期" prop="FDate" width="100" show-overflow-tooltip />
          </el-table>
        </el-tab-pane>
        <el-tab-pane :label="'入库/质检 (' + instockList.length + ')'" name="instock">
          <el-table :data="instockList" size="mini" border height="calc(62vh - 220px)" empty-text="点击上方「加载入库/质检」查询（仅入库点工序）">
            <el-table-column label="汇报单号" prop="FBillNo" min-width="130" show-overflow-tooltip />
            <el-table-column label="合格" prop="FQuaQty" width="72" align="center" />
            <el-table-column label="质检状态" width="100" align="center">
              <template slot-scope="scope">
                <el-tag size="mini" :type="isNotInspected(scope.row) ? 'danger' : 'success'">
                  {{ isNotInspected(scope.row) ? '未质检' : '已质检' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="生产入库单" prop="instockBillNo" min-width="140" show-overflow-tooltip />
            <el-table-column label="入库状态" prop="instockDocumentStatus" min-width="120" show-overflow-tooltip />
            <el-table-column label="提示" prop="instockAlertReason" min-width="160" show-overflow-tooltip />
          </el-table>
        </el-tab-pane>
        <el-tab-pane :label="'委外 C/G (' + transferList.length + ')'" name="transfer">
          <el-table :data="transferList" size="mini" border height="calc(62vh - 220px)" empty-text="点击上方「加载委外 C/G」查询">
            <el-table-column label="转移单号" prop="transferBillNo" min-width="130" show-overflow-tooltip />
            <el-table-column label="类型" width="80" align="center">
              <template slot-scope="scope">
                <el-tag size="mini" :type="scope.row.transferType === 'C' ? 'warning' : 'success'">
                  {{ scope.row.transferType === 'C' ? '发出' : scope.row.transferType === 'G' ? '接收' : scope.row.transferType }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="转移数量" prop="operTransferQty" width="88" align="center" />
            <el-table-column label="合格数量" prop="operQualifiedQty" width="88" align="center" />
            <el-table-column label="工废" prop="operProFailQty" width="72" align="center" />
            <el-table-column label="料废" prop="operMatFailQty" width="72" align="center" />
            <el-table-column label="单据日期" width="110">
              <template slot-scope="scope">{{ formatDate(scope.row.billDate) }}</template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>
    </el-drawer>
  </div>
</template>

<script>
import {
  queryMaterialDocHubBoardPage,
  queryMaterialDocHubBoardDetail,
  queryMaterialDocHubReports,
  queryMaterialDocHubInstockQc,
  queryMaterialDocHubSubcontract
} from '@/api/system/materialDocHub'

export default {
  name: 'MaterialDocHub',
  data() {
    return {
      loading: false,
      loaded: false,
      total: 0,
      projectList: [],
      queryParams: {
        sclh: undefined,
        pageNum: 1,
        pageSize: 20
      },
      drawerOpen: false,
      drawerTab: 'qty',
      processContext: {},
      reportList: [],
      instockList: [],
      transferList: [],
      reportsLoading: false,
      instockLoading: false,
      subcontractLoading: false
    }
  },
  computed: {
    emptyTableText() {
      return this.loaded ? '暂无工序计划数据' : '请点击查询加载数据'
    }
  },
  created() {
    this.initFromRoute()
  },
  methods: {
    initFromRoute() {
      const q = (this.$route && this.$route.query) || {}
      const sclh = q.sclh || q.hbytSclh || q.productionOrderNo
      if (sclh) {
        this.queryParams.sclh = sclh
      }
      this.getList()
    },
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    resetQuery() {
      this.queryParams.sclh = undefined
      this.queryParams.pageNum = 1
      this.getList()
    },
    getList() {
      this.loading = true
      const params = {
        pageNum: this.queryParams.pageNum,
        pageSize: this.queryParams.pageSize
      }
      const sclh = (this.queryParams.sclh || '').trim()
      if (sclh) {
        params.sclh = sclh
      }
      queryMaterialDocHubBoardPage(params)
        .then(res => {
          const data = res || {}
          const rows = data.rows || []
          this.total = data.total || 0
          this.projectList = rows.map(r => this.mapProjectRow(r))
          this.loaded = true
        })
        .catch(() => {
          this.projectList = []
          this.total = 0
        })
        .finally(() => {
          this.loading = false
        })
    },
    mapProjectRow(r) {
      return {
        projectId: r.projectId || (r.moBillNo + '@@' + r.materialNumber),
        moBillNo: r.moBillNo,
        moOrderNo: r.moOrderNo,
        productCode: r.materialNumber,
        productName: r.materialName,
        qty: r.operQty,
        processCount: r.processCount,
        processes: [],
        _loaded: false,
        _loading: false
      }
    },
    loadProjectDetail(row) {
      if (!row || row._loading || row._loaded) return
      row._loading = true
      queryMaterialDocHubBoardDetail(row.moBillNo, row.productCode)
        .then(res => {
          const data = (res && res.data !== undefined) ? res.data : res
          row.processes = this.buildProcesses(data.processes || [])
          row._loaded = true
          row.currentStage = this.resolveCurrentStage(row.processes)
        })
        .catch(() => {
          row.processes = []
        })
        .finally(() => {
          row._loading = false
        })
    },
    buildProcesses(rows) {
      const list = (rows || []).map(r => {
        const planQty = Number(r.operQty || 0)
        const transOut = Number(r.transOutQty || 0)
        const pct = planQty > 0 ? Math.round((transOut / planQty) * 100) : 0
        return {
          stageKey: `${r.operNumber}@@${r.processName}`,
          operNo: Number(r.operNumber),
          processName: r.processName,
          workCenter: r.workCenterName,
          planQty: r.operQty,
          inQty: r.transInQty,
          transOutQty: r.transOutQty,
          reportQty: r.reportQty,
          scrapQty: r.scrapQty,
          operStatus: r.operStatus,
          materialStatus: r.materialStatus,
          operPlanStartTime: r.operPlanStartTime2 || r.operPlanStartTime,
          operPlanFinishTime: r.operPlanFinishTime2 || r.operPlanFinishTime,
          delayDays: r.delayDays,
          progressPct: Math.max(0, Math.min(100, pct)),
          progressColor: pct >= 100 ? '#67c23a' : (pct > 0 ? '#7c3aed' : '#c0c4cc')
        }
      })
      return list.sort((a, b) => (a.operNo || 0) - (b.operNo || 0))
    },
    openProcessDetail(project, stage) {
      if (!stage) return
      this.processContext = {
        moOrderNo: project.moOrderNo,
        moBillNo: project.moBillNo,
        materialNumber: project.productCode,
        productName: project.productName,
        operNo: stage.operNo,
        processName: stage.processName,
        workCenter: stage.workCenter,
        planQty: stage.planQty,
        inQty: stage.inQty,
        transOutQty: stage.transOutQty,
        reportQty: stage.reportQty,
        scrapQty: stage.scrapQty,
        operStatus: stage.operStatus,
        materialStatus: stage.materialStatus,
        operPlanStartTime: stage.operPlanStartTime,
        operPlanFinishTime: stage.operPlanFinishTime,
        delayDays: stage.delayDays
      }
      this.reportList = []
      this.instockList = []
      this.transferList = []
      this.drawerTab = 'qty'
      this.drawerOpen = true
    },
    loadReports() {
      const ctx = this.processContext
      if (!ctx.moBillNo) return
      this.reportsLoading = true
      queryMaterialDocHubReports(ctx.moBillNo, ctx.materialNumber, String(ctx.operNo))
        .then(res => {
          this.reportList = (res && res.data !== undefined) ? res.data : (res || [])
        })
        .finally(() => { this.reportsLoading = false })
    },
    loadInstockQc() {
      const ctx = this.processContext
      if (!ctx.moBillNo) return
      this.instockLoading = true
      queryMaterialDocHubInstockQc(ctx.moBillNo, ctx.materialNumber, String(ctx.operNo))
        .then(res => {
          this.instockList = (res && res.data !== undefined) ? res.data : (res || [])
        })
        .finally(() => { this.instockLoading = false })
    },
    loadSubcontract() {
      const ctx = this.processContext
      if (!ctx.moBillNo) return
      this.subcontractLoading = true
      queryMaterialDocHubSubcontract(ctx.moBillNo)
        .then(res => {
          this.transferList = (res && res.data !== undefined) ? res.data : (res || [])
        })
        .finally(() => { this.subcontractLoading = false })
    },
    isNotInspected(row) {
      return this.isZero(row.FQuaQty) && this.isZero(row.FProcessFailQty)
        && this.isZero(row.FMaterialFailQty) && this.isZero(row.FReworkQty)
    },
    isZero(v) {
      if (v == null || v === '') return true
      const n = Number(v)
      return !Number.isFinite(n) || n === 0
    },
    currentStageLabel(project) {
      if (project.currentStage) return project.currentStage
      if (project.processCount) return project.processCount + ' 道工序'
      return '-'
    },
    resolveCurrentStage(processes) {
      const stages = processes || []
      if (!stages.length) return '-'
      const cur = stages.find(s => this.processPhase(s.materialStatus) !== 'done') || stages[stages.length - 1]
      return cur && cur.processName ? cur.processName : '-'
    },
    indexMethod(index) {
      return (this.queryParams.pageNum - 1) * this.queryParams.pageSize + index + 1
    },
    toggleRowExpand(row) {
      if (this.$refs && this.$refs.projectTable) {
        this.$refs.projectTable.toggleRowExpansion(row)
      }
    },
    processPhase(status) {
      const s = (status || '').toString()
      if (s.includes('已转出')) return 'done'
      if (s.includes('未转出')) return 'active'
      return 'idle'
    },
    processStatusType(status) {
      const phase = this.processPhase(status)
      if (phase === 'done') return 'success'
      if (phase === 'active') return 'warning'
      return 'info'
    },
    displayVal(v) {
      return v == null || v === '' ? '-' : v
    },
    formatDate(d) {
      if (!d) return '-'
      if (typeof d === 'string') return d.substring(0, 10)
      try {
        return new Date(d).toISOString().substring(0, 10)
      } catch (e) {
        return '-'
      }
    }
  }
}
</script>

<style scoped>
.search-panel {
  margin-bottom: 12px;
  padding: 12px 14px;
  background: #fafafa;
  border: 1px solid #ebeef5;
  border-radius: 8px;
}
.summary-card { margin-bottom: 12px; }
.summary-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  font-size: 13px;
}
.project-table ::v-deep .el-table__expanded-cell {
  padding: 12px 16px;
  background: #fafbfc;
}
.proj-main { display: flex; flex-direction: column; gap: 4px; }
.proj-title { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.proj-name { font-weight: 600; color: #303133; }
.proj-code { font-size: 12px; color: #909399; }
.proj-sub { display: flex; flex-wrap: wrap; gap: 6px; }
.kanban-wrap { width: 100%; min-height: 40px; }
.kanban-load-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 16px 0;
}
.kanban-load-hint { font-size: 12px; color: #909399; }
.kanban-body { min-height: 40px; }
.kanban-empty { padding: 10px 0; font-size: 12px; color: #c0c4cc; }
.kanban-scroll { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 6px; }
.kanban-col { flex: 0 0 220px; background: #fff; border: 1px solid #ebeef5; border-radius: 6px; overflow: hidden; }
.kanban-col__head { display: flex; align-items: flex-start; justify-content: space-between; padding: 8px 10px; background: #7c3aed; color: #fff; gap: 6px; }
.kanban-col__head-main { flex: 1; min-width: 0; }
.kanban-col__title { font-size: 13px; font-weight: 600; line-height: 1.3; }
.kanban-col__oper {
  display: inline-block;
  margin-right: 4px;
  padding: 0 4px;
  border-radius: 3px;
  background: rgba(255,255,255,0.2);
  font-size: 11px;
}
.kanban-col__wc { margin-top: 2px; font-size: 11px; opacity: 0.9; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kanban-col__action { color: rgba(255,255,255,0.9); padding: 0; flex-shrink: 0; }
.kanban-card { padding: 10px; cursor: pointer; }
.kanban-card__top { display: flex; gap: 10px; align-items: center; }
.kanban-progress {
  position: relative;
  flex-shrink: 0;
  width: 52px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.kanban-progress ::v-deep .el-progress { line-height: 1; }
.kanban-progress ::v-deep .el-progress-circle {
  width: 52px !important;
  height: 52px !important;
}
.kanban-progress__text {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: 11px;
  font-weight: 600;
  color: #606266;
  line-height: 1;
  pointer-events: none;
}
.kanban-card__meta {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  justify-content: center;
}
.kanban-kv {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 12px;
  line-height: 1.4;
}
.kanban-k { color: #909399; flex-shrink: 0; }
.kanban-v {
  color: #303133;
  font-variant-numeric: tabular-nums;
  text-align: right;
  min-width: 44px;
}
.kanban-card__bottom {
  margin-top: 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  font-size: 11px;
  color: #909399;
}
.kanban-delay { color: #f56c6c; }
.cell-sub { font-size: 12px; color: #c0c4cc; }
.cell-link { font-size: 12px; color: #409eff; }
.hub-drawer ::v-deep .el-drawer__header { margin-bottom: 0; padding: 14px 16px; border-bottom: 1px solid #ebeef5; }
.hub-drawer ::v-deep .el-drawer__body { padding: 12px 16px; }
.hub-drawer__title-line { display: flex; align-items: center; gap: 12px; overflow: hidden; white-space: nowrap; }
.hub-drawer__title-main { font-size: 16px; font-weight: 500; }
.hub-drawer__title-kv { font-size: 13px; color: #909399; }
.hub-drawer__title-product { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.hub-drawer__summary { display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 10px; font-size: 13px; color: #606266; }
.hub-drawer__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
</style>
