<template>
  <div class="wh-panel" v-loading="whLoading">
    <div v-if="warehouseList.length === 0 && !whLoading" class="wh-empty">暂无绑定库区</div>

    <div v-if="warehouseList.length > 0" class="doc-tabs">
      <div class="doc-tabs-header">
        <div v-for="(wh, idx) in warehouseList" :key="wh.relId" class="doc-tab-item"
          :class="{ active: activeIdx === idx }" @click="switchWh(idx)">
          <span class="doc-tab-label">{{ wh.warehouseName || wh.actualWarehouseName || '库区' + (idx + 1) }}</span>
          <span class="doc-tab-badge">{{ wh.systemCoilCount || 0 }}卷</span>
        </div>
      </div>
      <div class="doc-tabs-content">
        <div v-for="(wh, idx) in warehouseList" :key="wh.relId" v-show="activeIdx === idx">

          <!-- ====== 盘库执行中 (2)：操作台 ====== -->
          <template v-if="planStatus === 2">
            <div class="console-section">
              <div class="console-steps">
                <div class="console-step" :class="{ done: wh.snapshotCoilLogic }">
                  <span class="step-icon"><i class="el-icon-camera"></i></span>
                  <span class="step-info">
                    <span class="step-title">生成快照</span>
                    <span class="step-desc">{{ wh.snapshotCoilLogic ? '已生成' : '未生成' }}
                      <el-button v-if="wh.snapshotCoilLogic" type="text" size="mini" icon="el-icon-view" @click.stop="showPreview(wh.snapshotCoilLogic)">预览</el-button>
                    </span>
                    <span v-if="wh.snapshotCoilLogic && wh.systemCoilCount != null" class="step-stats">系统：<b>{{ wh.systemCoilCount }}</b> 卷 | 总重：<b>{{ wh.systemTotalWeight }}</b> kg</span>
                  </span>
                  <el-button size="mini" type="primary" plain :loading="genLoading" @click="doGenSnapshot(wh)">生成</el-button>
                </div>
                <div class="console-step" :class="{ done: wh.snapshotCoilStats }">
                  <span class="step-icon"><i class="el-icon-upload2"></i></span>
                  <span class="step-info">
                    <span class="step-title">上传实盘</span>
                    <span class="step-desc">{{ wh.snapshotCoilStats ? '已上传' : '未上传' }}
                      <el-button v-if="wh.snapshotCoilStats" type="text" size="mini" icon="el-icon-view" @click.stop="showPreview(wh.snapshotCoilStats)">预览</el-button>
                    </span>
                    <span v-if="wh.snapshotCoilStats && wh.actualCoilCount != null" class="step-stats">实盘：<b>{{ wh.actualCoilCount }}</b> 卷 | 总重：<b>{{ wh.actualTotalWeight }}</b> kg</span>
                  </span>
                  <el-button size="mini" type="primary" plain @click="openImport(wh)">上传</el-button>
                </div>
                <div class="console-step" :class="{ done: diffDoneMap[wh.relId] }">
                  <span class="step-icon"><i class="el-icon-s-data"></i></span>
                  <span class="step-info">
                    <span class="step-title">执行对比</span>
                    <span class="step-desc">{{ diffDoneMap[wh.relId] ? '已完成' : '未对比' }}
                      <span style="color:#909399;font-size:10px;">阈值</span>
                      <el-input-number v-model="diffThreshold" size="mini" style="width:90px;" :controls="false" />
                      <span style="color:#909399;font-size:10px;">T</span>
                    </span>
                  </span>
                  <el-button size="mini" type="primary" plain :loading="diffLoading" @click="doCompare(wh)">对比</el-button>
                </div>
                <div class="console-step">
                  <span class="step-icon"><i class="el-icon-document-checked"></i></span>
                  <span class="step-info">
                    <span class="step-title">查看结果</span>
                    <span class="step-desc">对比后可查看并保存</span>
                  </span>
                  <el-button size="mini" type="success" plain :disabled="!diffDoneMap[wh.relId]" @click="openDiffDialog(wh)">查看结果</el-button>
                </div>
              </div>
            </div>
            <!-- 对比结果摘要 -->
            <div v-if="diffDoneMap[wh.relId]" class="wh-diff-summary">
              <div class="result-header">对比结果摘要</div>
              <div class="result-grid">
                <div class="result-item miss">盘亏：{{ diffResult.missing.length }}卷</div>
                <div class="result-item extra">盘盈：{{ diffResult.extra.length }}卷</div>
                <div class="result-item diff">不一致：{{ diffResult.mismatch.length }}卷</div>
                <div class="result-item weight-similar">重量不同：{{ diffResult.weightSimilar.length }}卷</div>
              </div>
            </div>

            <div style="text-align:right;margin-bottom:8px;">
              <el-button type="primary" size="small" icon="el-icon-s-promotion" @click="$emit('submit-disc-approval')">提交差异审批</el-button>
            </div>
          </template>

          <!-- ====== 草稿 (0) / 计划待审批 (1)：库区清单 ====== -->
          <template v-if="planStatus === 0 || planStatus === 1">
            <div class="wh-detail-list">
              <div class="wh-detail-row">
                <span class="wh-detail-label">逻辑库区</span>
                <span class="wh-detail-value">{{ wh.warehouseName || '-' }}</span>
              </div>
              <div class="wh-detail-row">
                <span class="wh-detail-label">实际库区</span>
                <span class="wh-detail-value">{{ wh.actualWarehouseName || '-' }}</span>
              </div>
              <div class="wh-detail-row">
                <span class="wh-detail-label">出入库查询起始</span>
                <span class="wh-detail-value">{{ wh.ioStartTime ? formatTime(wh.ioStartTime) : '-' }}</span>
              </div>
              <div class="wh-detail-row">
                <span class="wh-detail-label">出入库查询截止</span>
                <span class="wh-detail-value">{{ wh.ioEndTime ? formatTime(wh.ioEndTime) : '-' }}</span>
              </div>
            </div>
          </template>

          <!-- ====== 概览卡片（状态 2/3/4/5） ====== -->
          <div v-if="planStatus >= 2" class="wh-overview">
            <div class="wh-box">
              <div class="wh-box-title">盘点范围</div>
              <div class="wh-box-body">
                <div v-if="wh.warehouseName">逻辑库区：{{ wh.warehouseName }}</div>
                <div v-if="wh.actualWarehouseName">实际库区：{{ wh.actualWarehouseName }}</div>
                <div v-if="wh.ioStartTime">{{ formatTime(wh.ioStartTime) }} ~ {{ formatTime(wh.ioEndTime) || '' }}</div>
                <div v-if="!wh.warehouseName && !wh.actualWarehouseName && !wh.ioStartTime" style="color:#909399;">无</div>
              </div>
            </div>
            <div class="wh-box">
              <div class="wh-box-title">系统快照
                <el-button v-if="wh.snapshotCoilLogic" type="text" size="mini" icon="el-icon-view" @click="showPreview(wh.snapshotCoilLogic)">预览</el-button>
              </div>
              <div class="wh-box-body">
                <div v-if="wh.snapshotCoilLogic">系统：<b>{{ wh.systemCoilCount || 0 }}</b> 卷 | 总重：<b>{{ wh.systemTotalWeight || 0 }}</b> kg</div>
                <div v-else style="color:#909399;">未生成</div>
              </div>
            </div>
            <div class="wh-box">
              <div class="wh-box-title">实盘数据
                <el-button v-if="wh.snapshotCoilStats" type="text" size="mini" icon="el-icon-view" @click="showPreview(wh.snapshotCoilStats)">预览</el-button>
              </div>
              <div class="wh-box-body">
                <div v-if="wh.snapshotCoilStats">实盘：<b>{{ wh.actualCoilCount || 0 }}</b> 卷 | 总重：<b>{{ wh.actualTotalWeight || 0 }}</b> kg</div>
                <div v-else style="color:#909399;">未上传</div>
              </div>
            </div>
          </div>

          <!-- ===== 计划待审批 (1) 操作 ===== -->
          <div v-if="planStatus === 1" style="text-align:right;margin-bottom:8px;">
            <el-button size="small" type="danger" icon="el-icon-close" @click="$emit('reject')">驳回</el-button>
            <el-button size="small" type="primary" icon="el-icon-check" @click="$emit('approve')">审批通过</el-button>
          </div>
          
          <!-- ===== 差异审批中 (3) 操作 ===== -->
          <div v-if="planStatus === 3" style="text-align:right;margin-bottom:8px;">
            <el-button size="small" type="danger" icon="el-icon-close" @click="$emit('reject')">驳回</el-button>
            <el-button size="small" type="primary" icon="el-icon-check" @click="$emit('diff-approve')">审批通过</el-button>
          </div>

          <!-- ===== 差异处理中 (4) 操作 ===== -->
          <div v-if="planStatus === 4" style="text-align:right;margin-bottom:8px;">
            <el-button size="small" type="success" icon="el-icon-circle-check" @click="$emit('archive')">归档封存</el-button>
          </div>

          <!-- ====== 差异明细表格（状态 2+） ====== -->
          <template v-if="planStatus >= 2">
          <div class="section-title">差异明细</div>

          <template v-if="planStatus === 2">
            <div style="display:flex;justify-content:flex-end;margin-bottom:4px;">
              <el-button size="mini" type="danger" plain icon="el-icon-delete" :disabled="discSelected.length === 0" @click="batchDelDisc(wh)">批量删除</el-button>
            </div>
            <el-table v-loading="discLoadingMap[wh.relId]" :data="discMap[wh.relId] || []" border size="small" style="width:100%" height="300"
              @selection-change="function(s) { discSelected = s; }">
              <el-table-column type="selection" width="36" />
              <el-table-column label="类型" align="center" width="80">
                <template slot-scope="ds">
                  <el-tag v-if="ds.row.discrepancyType === 1" type="success" size="mini">盘盈</el-tag>
                  <el-tag v-else-if="ds.row.discrepancyType === 2" type="danger" size="mini">盘亏</el-tag>
                  <el-tag v-else-if="ds.row.discrepancyType === 3" type="warning" size="mini">不符</el-tag>
                  <el-tag v-else size="mini">偏差</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="钢卷号" align="center" prop="enterCoilNo" width="140" />
              <el-table-column label="差异详情" align="center" prop="discrepancyDetail" min-width="140" show-overflow-tooltip />
              <el-table-column label="原因分析" align="center" min-width="140">
                <template slot-scope="ds"><el-input v-model="ds.row.reasonAnalysis" size="mini" placeholder="原因分析" @blur="saveDiscRow(ds.row)" /></template>
              </el-table-column>
              <el-table-column label="处理建议" align="center" min-width="140">
                <template slot-scope="ds"><el-input v-model="ds.row.processSuggestion" size="mini" placeholder="处理建议" @blur="saveDiscRow(ds.row)" /></template>
              </el-table-column>
              <el-table-column label="" align="center" width="50">
                <template slot-scope="ds"><el-button size="mini" type="text" icon="el-icon-delete" style="color:#f56c6c;" @click="delOneDisc(ds.row, wh.relId)" /></template>
              </el-table-column>
            </el-table>
          </template>

          <template v-else-if="planStatus === 1">
            <el-table v-loading="discLoadingMap[wh.relId]" :data="discMap[wh.relId] || []" border size="small" style="width:100%" height="300">
              <el-table-column label="类型" align="center" width="80">
                <template slot-scope="ds">
                  <el-tag v-if="ds.row.discrepancyType === 1" type="success" size="mini">盘盈</el-tag>
                  <el-tag v-else-if="ds.row.discrepancyType === 2" type="danger" size="mini">盘亏</el-tag>
                  <el-tag v-else-if="ds.row.discrepancyType === 3" type="warning" size="mini">不符</el-tag>
                  <el-tag v-else size="mini">偏差</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="钢卷号" align="center" prop="enterCoilNo" width="140" />
              <el-table-column label="差异详情" align="center" prop="discrepancyDetail" min-width="120" show-overflow-tooltip />
              <el-table-column label="原因分析" align="center" min-width="100">
                <template slot-scope="ds">{{ ds.row.reasonAnalysis || '-' }}</template>
              </el-table-column>
              <el-table-column label="处理建议" align="center" min-width="100">
                <template slot-scope="ds">{{ ds.row.processSuggestion || '-' }}</template>
              </el-table-column>
            </el-table>
          </template>

          <template v-else-if="planStatus === 3">
            <el-table v-loading="discLoadingMap[wh.relId]" :data="discMap[wh.relId] || []" border size="small" style="width:100%" height="300">
              <el-table-column label="类型" align="center" width="80">
                <template slot-scope="ds">
                  <el-tag v-if="ds.row.discrepancyType === 1" type="success" size="mini">盘盈</el-tag>
                  <el-tag v-else-if="ds.row.discrepancyType === 2" type="danger" size="mini">盘亏</el-tag>
                  <el-tag v-else-if="ds.row.discrepancyType === 3" type="warning" size="mini">不符</el-tag>
                  <el-tag v-else size="mini">偏差</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="钢卷号" align="center" prop="enterCoilNo" width="140" />
              <el-table-column label="差异详情" align="center" prop="discrepancyDetail" min-width="120" show-overflow-tooltip />
              <el-table-column label="原因分析" align="center" min-width="100">
                <template slot-scope="ds">{{ ds.row.reasonAnalysis || '-' }}</template>
              </el-table-column>
              <el-table-column label="处理建议" align="center" min-width="100">
                <template slot-scope="ds">{{ ds.row.processSuggestion || '-' }}</template>
              </el-table-column>
            </el-table>
          </template>

          <template v-else-if="planStatus === 4">
            <el-table v-loading="discLoadingMap[wh.relId]" :data="discMap[wh.relId] || []" border size="small" style="width:100%" height="300">
              <el-table-column label="类型" align="center" width="80">
                <template slot-scope="ds">
                  <el-tag v-if="ds.row.discrepancyType === 1" type="success" size="mini">盘盈</el-tag>
                  <el-tag v-else-if="ds.row.discrepancyType === 2" type="danger" size="mini">盘亏</el-tag>
                  <el-tag v-else-if="ds.row.discrepancyType === 3" type="warning" size="mini">不符</el-tag>
                  <el-tag v-else size="mini">偏差</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="钢卷号" align="center" prop="enterCoilNo" width="140" />
              <el-table-column label="差异详情" align="center" prop="discrepancyDetail" min-width="120" show-overflow-tooltip />
              <el-table-column label="原因分析" align="center" min-width="100">
                <template slot-scope="ds">{{ ds.row.reasonAnalysis || '-' }}</template>
              </el-table-column>
              <el-table-column label="处理建议" align="center" min-width="100">
                <template slot-scope="ds">{{ ds.row.processSuggestion || '-' }}</template>
              </el-table-column>
              <el-table-column label="处理结果" align="center" min-width="150">
                <template slot-scope="ds">
                  <el-input v-model="ds.row._processResult" size="mini" placeholder="选填" :disabled="ds.row.processStatus === 2" />
                </template>
              </el-table-column>
              <el-table-column label="状态" align="center" width="90">
                <template slot-scope="ds">
                  <el-tag v-if="ds.row.processStatus === 2" type="success" size="mini">已处理</el-tag>
                  <el-tag v-else type="info" size="mini">待处理</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="操作" align="center" width="90">
                <template slot-scope="ds">
                  <el-button v-if="ds.row.processStatus !== 2" size="mini" type="primary" @click="$emit('process-disc', { row: ds.row, relId: wh.relId })">处理</el-button>
                  <span v-else style="color:#67c23a;font-size:12px;">已完成</span>
                </template>
              </el-table-column>
            </el-table>
          </template>

          <template v-else-if="planStatus === 5">
            <el-table v-loading="discLoadingMap[wh.relId]" :data="discMap[wh.relId] || []" border size="small" style="width:100%" height="300">
              <el-table-column label="类型" align="center" width="80">
                <template slot-scope="ds">
                  <el-tag v-if="ds.row.discrepancyType === 1" type="success" size="mini">盘盈</el-tag>
                  <el-tag v-else-if="ds.row.discrepancyType === 2" type="danger" size="mini">盘亏</el-tag>
                  <el-tag v-else-if="ds.row.discrepancyType === 3" type="warning" size="mini">不符</el-tag>
                  <el-tag v-else size="mini">偏差</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="钢卷号" align="center" prop="enterCoilNo" width="140" />
              <el-table-column label="差异详情" align="center" prop="discrepancyDetail" min-width="120" show-overflow-tooltip />
              <el-table-column label="原因分析" align="center" min-width="100">
                <template slot-scope="ds">{{ ds.row.reasonAnalysis || '-' }}</template>
              </el-table-column>
              <el-table-column label="处理建议" align="center" min-width="100">
                <template slot-scope="ds">{{ ds.row.processSuggestion || '-' }}</template>
              </el-table-column>
              <el-table-column label="处理结果" align="center" min-width="120">
                <template slot-scope="ds">{{ ds.row.processResult || '-' }}</template>
              </el-table-column>
              <el-table-column label="处理状态" align="center" width="90">
                <template slot-scope="ds">
                  <el-tag v-if="ds.row.processStatus === 2" type="success" size="mini">已处理</el-tag>
                  <el-tag v-else type="info" size="mini">未处理</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="处理人" align="center" prop="processUserName" width="90" />
              <el-table-column label="处理时间" align="center" width="150">
                <template slot-scope="ds">{{ ds.row.processTime || '-' }}</template>
              </el-table-column>
            </el-table>
          </template>

          <div v-if="!(discMap[wh.relId] && discMap[wh.relId].length > 0) && !discLoadingMap[wh.relId]" class="wh-empty-tip">暂无差异记录</div>
          <div v-else style="text-align:right;padding:4px 0;">
            <el-pagination background layout="prev, pager, next, total" :total="discTotalMap[wh.relId] || 0" :page-size="discPageSize" :current-page="discPageMap[wh.relId] || 1" @current-change="function(p) { loadDisc(wh.relId, p); }" small />
          </div>
          </template>
        </div>
      </div>
    </div>

    <!-- 导入实盘Excel对话框 -->
    <el-dialog title="导入实盘Excel" :visible.sync="importOpen" width="1000px" append-to-body @close="resetImport">
      <div>
        <div style="display:flex;align-items:center;gap:10px;margin-bottom:14px;">
          <el-upload ref="impUpload" action="" :auto-upload="false" :show-file-list="false" :on-change="onImpFile" accept=".xlsx,.xls"><el-button type="primary" icon="el-icon-upload2">选择Excel</el-button></el-upload>
          <span v-if="impFile" style="color:#67c23a;font-size:13px;"><i class="el-icon-success"></i> {{ impFile.name }}</span>
          <el-button type="warning" icon="el-icon-upload" :disabled="!impFile || impErrors.length > 0 || importing" :loading="importing" @click="doImport">上传</el-button>
          <el-button type="default" icon="el-icon-refresh" :disabled="importing" @click="resetImport">重置</el-button>
        </div>
        <div style="margin-bottom:10px;"><el-link type="primary" icon="el-icon-download" @click="downloadTpl">下载模板</el-link></div>
        <div v-if="impErrors.length > 0" style="margin-top:10px;"><el-alert title="校验失败" type="error" :description="'共' + impErrors.length + '条错误'" show-icon /></div>
        <div v-if="impPreview.length > 0 && impErrors.length === 0" style="margin-top:10px;">
          <el-alert title="校验通过" type="success" :description="'共 ' + impPreview.length + ' 条数据' " show-icon :closable="false" />
          <el-table :data="impPreview" border size="small" max-height="300" stripe style="margin-top:8px;">
            <el-table-column prop="enterCoilNo" label="入场钢卷号" width="140" />
            <el-table-column prop="currentCoilNo" label="当前钢卷号" width="140" />
            <el-table-column prop="netWeight" label="重量(kg)" width="100" />
            <el-table-column prop="specification" label="规格" width="120" />
            <el-table-column prop="material" label="材质" width="100" />
            <el-table-column prop="manufacturer" label="生产厂家" width="120" />
            <el-table-column prop="qualityStatus" label="品质" width="100" />
            <el-table-column prop="actualWarehouseName" label="实际库区" width="100" />
            <el-table-column prop="length" label="长度" width="80" />
          </el-table>
        </div>
      </div>
    </el-dialog>

    <!-- 预览弹窗 -->
    <el-dialog title="文件预览" :visible.sync="previewOpen" width="80%" top="5vh" append-to-body :before-close="function(){previewOpen=false;previewUrl='';}">
      <div style="height:75vh;"><vue-office-excel v-if="previewUrl" :src="previewUrl" @render-error="function(){ $message.error('预览失败'); }" /><span v-else>加载中...</span></div>
    </el-dialog>

    <!-- 对比结果详情弹窗 -->
    <el-dialog title="对比结果详情" :visible.sync="diffDialogOpen" width="90%" top="3vh" append-to-body>
      <div v-if="diffDialogWh">
        <div style="display:flex;justify-content:flex-end;gap:8px;margin-bottom:10px;">
          <el-button type="primary" size="small" icon="el-icon-check" :loading="saving" @click="doSaveResult(diffDialogWh)">保存结果</el-button>
        </div>
        <div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;">
          <div class="diff-block">
            <div class="diff-block-title" style="color:#f56c6c;">盘亏（{{ diffResult.missing.length }}）</div>
            <el-table :data="diffResult.missing" border size="small" height="220">
              <el-table-column prop="enterCoilNo" label="入场钢卷号" width="130" />
              <el-table-column prop="currentCoilNo" label="当前钢卷号" width="130" />
              <el-table-column prop="netWeight" label="重量(kg)" width="100" />
              <el-table-column prop="specification" label="规格" width="120" />
              <el-table-column prop="material" label="材质" width="100" />
            </el-table>
          </div>
          <div class="diff-block">
            <div class="diff-block-title" style="color:#67c23a;">盘盈（{{ diffResult.extra.length }}）</div>
            <el-table :data="diffResult.extra" border size="small" height="220">
              <el-table-column prop="enterCoilNo" label="入场钢卷号" width="130" />
              <el-table-column prop="currentCoilNo" label="当前钢卷号" width="130" />
              <el-table-column prop="netWeight" label="重量(kg)" width="100" />
              <el-table-column prop="specification" label="规格" width="120" />
              <el-table-column prop="material" label="材质" width="100" />
            </el-table>
          </div>
          <div class="diff-block">
            <div class="diff-block-title" style="color:#e6a23c;">字段不一致（{{ diffResult.mismatch.length }}）</div>
            <el-table :data="diffResult.mismatch" border size="small" height="220">
              <el-table-column prop="enterCoilNo" label="入场钢卷号" width="130" />
              <el-table-column prop="currentCoilNo" label="当前钢卷号" width="130" />
              <el-table-column label="差异" min-width="200">
                <template slot-scope="ds"><span v-for="(d, i) in ds.row.diffs" :key="i">{{ d.label }}：快照[{{ d.snapshotValue }}] 实盘[{{ d.physicalValue }}]<br /></span></template>
              </el-table-column>
            </el-table>
          </div>
          <div class="diff-block">
            <div class="diff-block-title" style="color:#409eff;">重量不同（阈值内，{{ diffResult.weightSimilar.length }}）</div>
            <el-table :data="diffResult.weightSimilar" border size="small" height="220">
              <el-table-column prop="enterCoilNo" label="入场钢卷号" width="130" />
              <el-table-column prop="currentCoilNo" label="当前钢卷号" width="130" />
              <el-table-column label="差异" min-width="200">
                <template slot-scope="ds"><span v-for="(d, i) in ds.row.diffs" :key="i">{{ d.label }}：快照[{{ d.snapshotValue }}] 实盘[{{ d.physicalValue }}]<br /></span></template>
              </el-table-column>
            </el-table>
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listCountPlanWarehouse } from "@/api/flow/countPlanWarehouse";
import { listCountDiscrepancy, updateCountDiscrepancy, batchAddCountDiscrepancy, delCountDiscrepancy } from "@/api/flow/countDiscrepancy";
import { exportCoilWithAll } from "@/api/wms/coil";
import { uploadFile, listByIds } from "@/api/system/oss";
import { updateCountPlanWarehouse } from "@/api/flow/countPlanWarehouse";
import { parseTime } from '@/utils/klp';
import * as XLSX from 'xlsx';
import { downloadAndParseExcel, SNAPSHOT_COL_MAP, PHYSICAL_HEADER_MAP, compareCoils } from '../utils/compare.js';
import VueOfficeExcel from '@vue-office/excel';
import '@vue-office/excel/lib/index.css';

const IMP_TEMPLATE = ['入场钢卷号', '当前钢卷号', '重量(kg)', '规格', '材质', '生产厂家', '品质', '实际库区', '长度', '备注'];

export default {
  name: 'WarehouseDetailPanel',
  components: { VueOfficeExcel },
  props: {
    planId: { type: [Number, String], required: true },
    planStatus: { type: Number, default: 0 }
  },
  data() {
    return {
      whLoading: false, warehouseList: [], activeIdx: 0,
      discMap: {}, discLoadingMap: {}, discPageMap: {}, discTotalMap: {},
      discPageSize: 20,
      genLoading: false,
      importOpen: false, importWh: null, impFile: null, impErrors: [], impPreview: [], importing: false,
      previewOpen: false, previewUrl: '',
      diffThreshold: 0.5, diffLoading: false, diffDoneMap: {},
      diffResult: { missing: [], extra: [], mismatch: [], weightSimilar: [] },
      diffDialogOpen: false, diffDialogWh: null, saving: false,
      discSelected: []
    };
  },
  mounted() { this.loadWarehouses(); },
  watch: { planId() { this.activeIdx = 0; this.loadWarehouses(); } },
  methods: {
    formatTime(val) { if (!val) return ''; return parseTime(val, '{y}-{m}-{d} {h}:{i}'); },
    loadWarehouses() {
      if (!this.planId) return;
      this.whLoading = true; var self = this;
      listCountPlanWarehouse({ planId: this.planId, pageNum: 1, pageSize: 999 }).then(function(r) {
        self.warehouseList = r.rows || [];
        self.$emit('loaded', self.warehouseList);
        if (self.warehouseList.length > 0) self.loadDisc(self.warehouseList[0].relId);
      }).finally(function() { self.whLoading = false; });
    },
    loadDisc(relId, pageNum) {
      pageNum = pageNum || this.discPageMap[relId] || 1;
      this.$set(this.discPageMap, relId, pageNum);
      this.$set(this.discLoadingMap, relId, true); var self = this;
      listCountDiscrepancy({ relId, pageNum: pageNum, pageSize: this.discPageSize }).then(function(r) {
        self.$set(self.discMap, relId, (r.rows || []).map(function(item) {
          if (item._processResult === undefined) item._processResult = item.processResult || '';
          if (item._needResolve === undefined) item._needResolve = item.processStatus === 1;
          if (item._approveRemark === undefined) item._approveRemark = item.remark || '';
          return item;
        }));
        self.$set(self.discTotalMap, relId, r.total || 0);
      }).finally(function() { self.$set(self.discLoadingMap, relId, false); });
    },
    loadAllDisc() { var self = this; this.warehouseList.forEach(function(wh) { self.loadDisc(wh.relId); }); },
    switchWh(idx) { this.activeIdx = idx; var wh = this.warehouseList[idx]; if (wh) this.loadDisc(wh.relId); },
    refreshOneDisc(relId) { this.loadDisc(relId); },
    getActiveWarehouse() { return this.warehouseList[this.activeIdx] || null; },
    refreshAll() { this.activeIdx = 0; this.loadWarehouses(); },

    // ===== 快照生成 =====
    async doGenSnapshot(wh) {
      if (!wh) return;
      var p = { dataType: 1, status: 0 };
      if (wh.warehouseId) p.warehouseId = String(wh.warehouseId);
      if (wh.actualWarehouseId) p.actualWarehouseId = String(wh.actualWarehouseId);
      if (!p.warehouseId && !p.actualWarehouseId) { this.$message.warning('无库区条件'); return; }
      this.genLoading = true;
      try {
        var resp = await exportCoilWithAll(p);
        var label = wh.warehouseName || wh.actualWarehouseName || '';
        var file = new File([new Blob([resp])], label + '_快照.xlsx', { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
        var up = await uploadFile(file);
        await updateCountPlanWarehouse({ relId: wh.relId, snapshotCoilLogic: up.data.ossId });
        var arr = await resp.arrayBuffer();
        var wb = XLSX.read(new Uint8Array(arr), { type: 'array' });
        var rows = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
        var cnt = rows.length, tw = 0;
        rows.forEach(function(r) { tw += Number(r['重量'] || r['重量(kg)'] || 0); });
        await updateCountPlanWarehouse({ relId: wh.relId, systemCoilCount: cnt, systemTotalWeight: Math.round(tw * 100) / 100 });
        this.$message.success('快照已生成');
        this.refreshAll();
      } catch (e) { this.$message.error('生成失败'); }
      finally { this.genLoading = false; }
    },

    // ===== 实盘导入 =====
    openImport(wh) { this.importWh = wh; this.resetImport(); this.importOpen = true; },
    onImpFile(file) {
      if (this.importing) return;
      this.impFile = file.raw; this.impErrors = []; this.impPreview = [];
      var self = this;
      var fr = new FileReader();
      fr.readAsArrayBuffer(file.raw);
      fr.onload = function(e) {
        try {
          var wb = XLSX.read(new Uint8Array(e.target.result), { type: 'array' });
          var data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1 });
          var h = data[0];
          for (var i = 0; i < IMP_TEMPLATE.length; i++) { if (h[i] !== IMP_TEMPLATE[i]) self.impErrors.push({ rowNum: 1, errorMsg: '表头第' + (i + 1) + '列应为' + IMP_TEMPLATE[i] }); }
          data.slice(1).filter(function(r) { return r.length > 0; }).forEach(function(r, i) {
            if (!r[0] || !String(r[0]).trim()) self.impErrors.push({ rowNum: i + 2, errorMsg: '入场钢卷号为空' });
            if (r[2] && isNaN(Number(r[2]))) self.impErrors.push({ rowNum: i + 2, errorMsg: '重量非数字' });
            self.impPreview.push({
              enterCoilNo: String(r[0] || '').trim(), currentCoilNo: String(r[1] || '').trim(), netWeight: r[2],
              specification: r[3], material: r[4], manufacturer: r[5], qualityStatus: r[6],
              actualWarehouseName: r[7], length: r[8]
            });
          });
          if (self.impErrors.length === 0) self.$message.success('校验通过，共 ' + self.impPreview.length + ' 条');
        } catch (ex) { self.impErrors.push({ rowNum: 0, errorMsg: ex.message }); }
      };
    },
    async doImport() {
      if (this.importing || this.impErrors.length > 0 || !this.impFile) return;
      this.importing = true; var self = this;
      try {
        var up = await uploadFile(this.impFile);
        var cnt = 0, tw = 0;
        var fr2 = new FileReader();
        fr2.readAsArrayBuffer(this.impFile);
        await new Promise(function(resolve) {
          fr2.onload = function(e) {
            var wb = XLSX.read(new Uint8Array(e.target.result), { type: 'array' });
            var data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1 });
            data.slice(1).filter(function(r) { return r.length > 0; }).forEach(function(r) { cnt++; tw += Number(r[2]) || 0; });
            resolve();
          };
        });
        await updateCountPlanWarehouse({ relId: self.importWh.relId, snapshotCoilStats: up.data.ossId, actualCoilCount: cnt, actualTotalWeight: Math.round(tw * 100) / 100 });
        self.$message.success('上传成功');
        self.importOpen = false;
        self.refreshAll();
      } catch (e) { self.$message.error('上传失败'); }
      finally { self.importing = false; }
    },
    resetImport() { this.impFile = null; this.impErrors = []; this.impPreview = []; this.importing = false; if (this.$refs.impUpload) this.$refs.impUpload.clearFiles(); },
    downloadTpl() {
      var data = [IMP_TEMPLATE, ['LOT001', 'COIL001', 1000.5, '1.0*1000', 'Q235', '宝钢', '正品', 'A库区', 2000, '示例']];
      var wb = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(data), '模板');
      XLSX.writeFile(wb, '盘库实盘导入模板.xlsx');
    },

    // ===== 预览 =====
    showPreview(ossId) {
      var self = this; this.previewUrl = ''; this.previewOpen = true;
      listByIds(ossId).then(function(r) { var list = r.data || r.rows || []; if (list.length > 0) self.previewUrl = list[0].url; else { self.$message.error('未找到'); self.previewOpen = false; } }).catch(function() { self.$message.error('失败'); self.previewOpen = false; });
    },

    // ===== 差异保存 =====
    saveDiscRow(row) {
      if (!row || !row.discrepancyId) return;
      updateCountDiscrepancy({ discrepancyId: row.discrepancyId, reasonAnalysis: row.reasonAnalysis, processSuggestion: row.processSuggestion }).catch(function() {});
    },
    saveDiscMark(row) {
      if (!row || !row.discrepancyId) return;
      updateCountDiscrepancy({ discrepancyId: row.discrepancyId, processStatus: row._needResolve ? 1 : 0, remark: row._approveRemark }).catch(function() {});
    },

    // ===== 对比 =====
    async doCompare(wh) {
      if (!wh.snapshotCoilLogic) { this.$message.warning('请先生成快照'); return; }
      if (!wh.snapshotCoilStats) { this.$message.warning('请先上传实盘'); return; }
      this.diffLoading = true; this.diffResult = { missing: [], extra: [], mismatch: [], weightSimilar: [] };
      try {
        var snapRows = await downloadAndParseExcel(wh.snapshotCoilLogic, SNAPSHOT_COL_MAP);
        var physRows = await downloadAndParseExcel(wh.snapshotCoilStats, PHYSICAL_HEADER_MAP);
        this.diffResult = compareCoils(snapRows, physRows, this.diffThreshold);
        this.$set(this.diffDoneMap, wh.relId, true);
      } catch (e) { this.$message.error('对比失败：' + (e.message || '')); }
      finally { this.diffLoading = false; }
    },
    openDiffDialog(wh) {
      if (!this.diffResult.missing.length && !this.diffResult.extra.length && !this.diffResult.mismatch.length && !this.diffResult.weightSimilar.length) {
        this.$message.warning('无对比结果'); return;
      }
      this.diffDialogWh = wh;
      this.diffDialogOpen = true;
    },
    async doSaveResult(wh) {
      var r = this.diffResult;
      if (!r.missing.length && !r.extra.length && !r.mismatch.length && !r.weightSimilar.length) { this.$message.warning('无对比结果'); return; }
      var bos = [];
      r.missing.forEach(function(item) { bos.push({ relId: wh.relId, discrepancyType: 2, enterCoilNo: item.enterCoilNo || '', currentCoilNo: item.currentCoilNo || '', discrepancyDetail: '盘亏' }); });
      r.extra.forEach(function(item) { bos.push({ relId: wh.relId, discrepancyType: 1, enterCoilNo: item.enterCoilNo || '', currentCoilNo: item.currentCoilNo || '', discrepancyDetail: '盘盈' }); });
      r.mismatch.forEach(function(item) { var d = (item.diffs || []).map(function(x) { return x.label + ': 快照[' + (x.snapshotValue ?? '') + '] 实盘[' + (x.physicalValue ?? '') + ']'; }).join('; '); bos.push({ relId: wh.relId, discrepancyType: 4, enterCoilNo: item.enterCoilNo || '', currentCoilNo: item.currentCoilNo || '', discrepancyDetail: '不一致：' + d }); });
      r.weightSimilar.forEach(function(item) { var d = (item.diffs || []).map(function(x) { return x.label + ': 快照[' + (x.snapshotValue ?? '') + '] 实盘[' + (x.physicalValue ?? '') + ']'; }).join('; '); bos.push({ relId: wh.relId, discrepancyType: 4, enterCoilNo: item.enterCoilNo || '', currentCoilNo: item.currentCoilNo || '', discrepancyDetail: '重量不同(阈值内)：' + d }); });
      this.saving = true;
      try {
        await batchAddCountDiscrepancy(bos);
        this.$message.success('已保存 ' + bos.length + ' 条差异记录');
        this.diffDialogOpen = false;
        this.loadDisc(wh.relId);
      } catch (e) { this.$message.error('保存失败'); }
      finally { this.saving = false; }
    },
    // 删除单条差异
    delOneDisc(row, relId) {
      var self = this;
      this.$modal.confirm('确认删除该差异记录？').then(function() {
        return delCountDiscrepancy(row.discrepancyId);
      }).then(function() { self.$message.success('已删除'); self.loadDisc(relId); }).catch(function() {});
    },
    // 批量删除差异
    batchDelDisc(wh) {
      var self = this;
      if (!this.discSelected || this.discSelected.length === 0) { this.$message.warning('请至少选择一条'); return; }
      this.$modal.confirm('确认删除选中的 ' + this.discSelected.length + ' 条差异记录？').then(function() {
        var ids = self.discSelected.map(function(row) { return row.discrepancyId; }).join(',');
        return delCountDiscrepancy(ids);
      }).then(function() { self.$message.success('批量删除成功'); self.discSelected = []; self.loadDisc(wh.relId); }).catch(function() {});
    },

  }
};
</script>
<style scoped>
.wh-panel { }
.wh-empty { padding: 16px 0; color: #909399; font-size: 13px; }
.wh-detail-list { margin: 8px 0 16px; border: 1px solid #e8e4de; border-radius: 2px; overflow: hidden; }
.wh-detail-row { display: flex; padding: 8px 14px; font-size: 13px; border-bottom: 1px solid #f0ece6; }
.wh-detail-row:last-child { border-bottom: none; }
.wh-detail-label { width: 120px; flex-shrink: 0; color: #606266; font-weight: 500; }
.wh-detail-value { color: #303133; }
.doc-tabs-header { display: flex; border-bottom: 1px solid #d4d0c8; margin-bottom: 12px; }
.doc-tab-item { padding: 8px 16px; cursor: pointer; color: #8c8c8c; font-size: 13px; font-weight: 500; border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color 0.2s, border-color 0.2s; display: flex; align-items: center; gap: 6px; user-select: none; }
.doc-tab-item:hover { color: #1a3c6e; }
.doc-tab-item.active { color: #1a3c6e; font-weight: 600; border-bottom-color: #1a3c6e; }
.doc-tab-label { white-space: nowrap; }
.doc-tab-badge { font-size: 11px; color: #909399; }
.doc-tab-item.active .doc-tab-badge { color: #1a3c6e; }
.wh-overview { display: flex; gap: 12px; margin-bottom: 14px; }
.wh-box { flex: 1; border: 1px solid #e8e4de; border-radius: 2px; overflow: hidden; }
.wh-box-title { padding: 6px 10px; background: #f7f5f0; font-size: 12px; font-weight: 600; color: #1a1a1a; border-bottom: 1px solid #e8e4de; display: flex; align-items: center; justify-content: space-between; }
.wh-box-body { padding: 8px 10px; font-size: 12px; color: #606266; line-height: 1.8; }
.wh-box-body b { color: #1a3c6e; }
.section-title { font-size: 14px; font-weight: 700; color: #1a1a1a; margin: 16px 0 10px; padding-bottom: 8px; border-bottom: 1px solid #d4d0c8; letter-spacing: 0.3px; }
.wh-empty-tip { padding: 8px 0; color: #909399; font-size: 13px; }
.console-section { margin: 12px 0; }
.console-steps { display: flex; flex-direction: column; gap: 6px; }
.console-step { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: #faf8f5; border: 1px solid #e8e4de; border-radius: 2px; }
.console-step.done { background: #f0f9eb; border-color: #c2e7b0; }
.step-icon { width: 28px; height: 28px; border-radius: 50%; background: #e4e7ed; display: flex; align-items: center; justify-content: center; font-size: 14px; color: #909399; flex-shrink: 0; }
.console-step.done .step-icon { background: #67c23a; color: #fff; }
.step-info { flex: 1; display: flex; flex-direction: column; }
.step-title { font-size: 13px; font-weight: 600; color: #303133; }
.step-desc { font-size: 11px; color: #909399; margin-top: 1px; }
.step-stats { font-size: 11px; color: #606266; margin-top: 2px; }
.step-stats b { color: #1a3c6e; }
.wh-diff-summary { margin: 10px 0; padding: 12px; background: #faf8f5; border: 1px solid #e8e4de; border-radius: 2px; }
.result-header { font-size: 13px; font-weight: 600; color: #1a1a1a; margin-bottom: 8px; padding-bottom: 6px; border-bottom: 1px solid #e0dcd6; }
.result-grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 8px; }
.result-item { padding: 8px; border-radius: 2px; font-size: 12px; font-weight: 500; text-align: center; }
.result-item.miss { background: #fef0f0; color: #f56c6c; }
.result-item.extra { background: #f0f9eb; color: #67c23a; }
.result-item.diff { background: #fdf6ec; color: #e6a23c; }
.result-item.weight-similar { background: #f0f5ff; color: #409eff; }
.diff-block { margin-bottom: 10px; }
.diff-block-title { font-size: 13px; font-weight: 600; padding: 4px 0; border-bottom: 1px solid #e4e7ed; margin-bottom: 4px; }
</style>
