<template>
  <div class="aps-req-page">
    <el-row :gutter="20" class="aps-req-row">
      <!-- 左侧：产需单列表 -->
      <el-col :span="8" class="aps-req-left" v-loading="reqLoading">
        <!-- 筛选区 -->
        <div class="filter-section" style="padding: 10px; border-bottom: 1px solid #e4e7ed;">
          <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;">
            <div style="display: flex; align-items: center; gap: 4px; flex-wrap: wrap;">
              <el-input v-model="queryParams.scheduleNo" placeholder="产需单号" clearable @keyup.enter.native="handleSearch"
                style="width: 130px;" size="small" />
              <el-input v-model="queryParams.customerName" placeholder="客户名" clearable
                @keyup.enter.native="handleSearch" style="width: 130px;" size="small" />
              <el-date-picker v-model="queryParams.prodDate" type="date" placeholder="生产日期" value-format="yyyy-MM-dd"
                style="width: 130px;" size="small" clearable @change="handleSearch" />
              <el-button class="aps-btn-red" icon="el-icon-search" size="mini" @click="handleSearch">筛选</el-button>
              <el-button class="aps-btn-red" icon="el-icon-plus" size="mini" @click="handleAdd"></el-button>
            </div>
          </div>
        </div>

        <div class="panel-header">
          <span>产需单列表</span>
          <span style="font-weight:normal;color:var(--text-muted);font-size:11px;">共 {{ total }} 条</span>
        </div>

        <div class="list-container">
          <div v-for="item in reqList" :key="item.scheduleId" class="list-item"
            :class="{ active: currentReq && currentReq.scheduleId === item.scheduleId }" @click="handleReqClick(item)">
            <div class="list-item-body">
              <div class="list-item-left">
                <div class="item-title">
                  {{ item.scheduleNo }}
                  <span class="badge" :class="'badge-' + statusBadgeType(item.scheduleStatus)">{{
                    statusMap[item.scheduleStatus] || '未知' }}</span>
                </div>
                <div class="item-sub">
                  生产日期：{{ item.prodDate || '-' }}
                </div>
                <div class="item-sub">
                  客户：{{ item.customerName || '-' }}　业务员：{{ item.businessUser || '-' }}
                </div>
                <div class="item-actions">
                  <button class="link-btn" @click.stop="handleDelete(item)">删除</button>
                </div>
              </div>
              <div class="list-item-right">
                <el-button size="mini" plain @click.stop="handleJumpToSchedule(item)">跳转排产</el-button>
              </div>
            </div>
          </div>
          <div v-if="reqList.length === 0 && !reqLoading" style="padding: 40px; text-align: center; color: #909399;">
            暂无产需单数据
          </div>
        </div>

        <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
          :limit.sync="queryParams.pageSize" @pagination="getList"
          style="padding: 10px; margin-bottom: 10px !important;" />
      </el-col>

      <!-- 右侧：详情区 -->
      <el-col :span="16" class="aps-req-right">
        <el-empty v-if="!currentReq" description="选择产需单查看更多信息" />

        <div v-else class="detail-panel">
          <div class="detail-card">
            <div class="detail-card-header">
              <span>产需单信息</span>
              <div style="display:flex; gap:6px;">
                <button class="header-btn"
                  :disabled="currentReq.scheduleStatus !== 0 && currentReq.scheduleStatus !== 3"
                  @click="handleEdit(currentReq)">编辑</button>
                <button v-if="currentReq.scheduleStatus === 0 || currentReq.scheduleStatus === 3" class="header-btn"
                  style="background:rgba(255,255,255,0.4);border-color:rgba(255,255,255,0.7);"
                  @click="handleDispatch">{{ currentReq.scheduleStatus === 3 ? '重新下发' : '下发' }}</button>
              </div>
            </div>
            <div class="detail-card-body">
              <table class="req-info-table">
                <tbody>
                  <tr>
                    <td class="req-td-label">产需单号</td>
                    <td class="req-td-value">{{ currentReq.scheduleNo }}</td>
                    <td class="req-td-label">生产日期</td>
                    <td class="req-td-value">{{ currentReq.prodDate }}</td>
                  </tr>
                  <tr>
                    <td class="req-td-label">排产状态</td>
                    <td class="req-td-value"><span class="aps-status-tag"
                        :class="'status-' + (currentReq.scheduleStatus || 0)">{{ statusMap[currentReq.scheduleStatus] ||
                          '未知' }}</span></td>
                    <td class="req-td-label">业务员</td>
                    <td class="req-td-value">{{ currentReq.businessUser }}</td>
                  </tr>
                  <tr>
                    <td class="req-td-label">联系电话</td>
                    <td class="req-td-value">{{ currentReq.businessPhone }}</td>
                    <td class="req-td-label">订货单位</td>
                    <td class="req-td-value">{{ currentReq.customerName }}</td>
                  </tr>
                  <tr>
                    <td class="req-td-label">交货期(天)</td>
                    <td class="req-td-value">{{ currentReq.deliveryCycle }}</td>
                    <td class="req-td-label">产品用途</td>
                    <td class="req-td-value">{{ currentReq.usePurpose }}</td>
                  </tr>
                  <tr>
                    <td class="req-td-label">品名</td>
                    <td class="req-td-value" colspan="3">{{ currentReq.productType }}</td>
                  </tr>
                  <tr>
                    <td class="req-td-label">厚度公差</td>
                    <td class="req-td-value">{{ currentReq.thicknessTolerance }}</td>
                    <td class="req-td-label">宽度公差</td>
                    <td class="req-td-value">{{ currentReq.widthTolerance }}</td>
                  </tr>
                  <tr>
                    <td class="req-td-label">表面质量</td>
                    <td class="req-td-value">{{ currentReq.surfaceQuality }}</td>
                    <td class="req-td-label">表面处理</td>
                    <td class="req-td-value">{{ currentReq.surfaceTreatment }}</td>
                  </tr>
                  <tr>
                    <td class="req-td-label">内径尺寸</td>
                    <td class="req-td-value">{{ currentReq.innerDiameter }}</td>
                    <td class="req-td-label">外径要求</td>
                    <td class="req-td-value">{{ currentReq.outerDiameter }}</td>
                  </tr>
                  <tr>
                    <td class="req-td-label">包装要求</td>
                    <td class="req-td-value">{{ currentReq.packReq }}</td>
                    <td class="req-td-label">切边要求</td>
                    <td class="req-td-value">{{ currentReq.cutEdgeReq }}</td>
                  </tr>
                  <tr>
                    <td class="req-td-label">单件重量</td>
                    <td class="req-td-value">{{ currentReq.singleCoilWeight }}</td>
                    <td class="req-td-label">交货重量偏差</td>
                    <td class="req-td-value">{{ currentReq.weightDeviation }}</td>
                  </tr>
                  <tr>
                    <td class="req-td-label">其他技术要求</td>
                    <td class="req-td-value" colspan="3">{{ currentReq.otherTechReq }}</td>
                  </tr>
                  <tr>
                    <td class="req-td-label">付款情况说明</td>
                    <td class="req-td-value" colspan="3">{{ currentReq.paymentDesc }}</td>
                  </tr>
                  <tr>
                    <td class="req-td-label">备注</td>
                    <td class="req-td-value" colspan="3">{{ currentReq.remark }}</td>
                  </tr>
                  <tr v-if="currentReq.returnReason">
                    <td class="req-td-label" style="color:#e74c3c;">驳回原因</td>
                    <td class="req-td-value" colspan="3" style="color:#e74c3c;background:#fdecea;">{{
                      currentReq.returnReason }}</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>

          <div class="detail-card">
            <div class="detail-card-header">
              <span>已绑定的销售订单（{{ (currentReq.orderList || []).length }} 条）</span>
              <button v-if="canEdit" class="header-btn" @click="openBindDialog">+ 添加订单</button>
            </div>
            <div class="detail-card-body" v-loading="boundLoading">
              <div v-if="(currentReq.orderList || []).length === 0"
                style="padding: 16px; text-align: center; color: #909399;">暂无绑定订单</div>
              <div v-else class="bound-order-cards">
                <div v-for="order in currentReq.orderList" :key="order.orderId" class="bound-order-card">
                  <div class="bound-order-card-header">
                    <span>{{ order.orderCode || ('订单 #' + order.orderId) }}</span>
                    <button v-if="canEdit" class="link-btn" @click="handleUnbindByOrderId(order)">解绑</button>
                  </div>
                  <div class="bound-order-card-body">
                    <div style="font-size:12px; color:#7f8c8d; margin-bottom:3px;">
                      客户：<span style="color:#2c3e50;">{{ order.companyName || '-' }}</span>
                    </div>
                    <div style="font-size:12px; color:#7f8c8d; margin-bottom:3px;">
                      销售员：<span style="color:#2c3e50;">{{ order.salesman || '-' }}</span>
                    </div>
                    <div style="font-size:12px; color:#7f8c8d;">
                      交货日期：<span style="color:#2c3e50;">{{ order.deliveryDate || '-' }}</span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <div class="detail-card">
            <div class="detail-card-header">
              <span>排产明细（{{ requirementDetailList.length }} 条，合计 {{ detailTotalWeight }} T）</span>
              <button v-if="canEdit" class="header-btn" @click="handleDetailAdd">+ 新增</button>
            </div>
            <div class="detail-card-body" style="padding:0;">
              <el-table :data="requirementDetailList" border size="small" v-loading="detailLoading" class="aps-table">
                <el-table-column label="规格" prop="spec" min-width="120" />
                <el-table-column label="材质" prop="material" width="90" align="center" />
                <el-table-column label="排产吨数" prop="scheduleWeight" width="100" align="right" />
                <el-table-column label="备注" prop="remark" min-width="120" />
                <el-table-column label="操作" width="130" align="center" fixed="right">
                  <template slot-scope="scope">
                    <span style="white-space:nowrap;">
                      <el-button v-if="canEdit" type="text" size="small" style="color:#409EFF;"
                        @click="handleDetailEdit(scope.row)">编辑</el-button>
                      <el-button v-if="canEdit" type="text" size="small" style="color:#ff4d4f;"
                        @click="handleDetailDelete(scope.row)">删除</el-button>
                    </span>
                  </template>
                </el-table-column>
              </el-table>
              <el-empty v-if="requirementDetailList.length === 0 && !detailLoading" description="暂无排产明细" />
            </div>
          </div>
        </div>
      </el-col>
    </el-row>

    <!-- 新增/编辑对话框 -->
    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="900px" append-to-body
      :close-on-click-modal="false">
      <div style="display: flex; gap: 16px;">
        <div style="flex: 1; min-width: 0;">
          <el-form ref="reqForm" :model="reqForm" :rules="reqRules" label-width="80px" size="small">
            <!-- 第一行：必填项 -->
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="产需单号" prop="scheduleNo">
              <el-input v-model="reqForm.scheduleNo" placeholder="自动生成或手动填写" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="生产日期" prop="prodDate">
              <el-date-picker v-model="reqForm.prodDate" type="date" value-format="yyyy-MM-dd" style="width:100%" />
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 基本信息 -->
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="订货单位" prop="customerName">
              <el-input v-model="reqForm.customerName" />
            </el-form-item>
            <el-form-item label="业务员" prop="businessUser">
              <el-input v-model="reqForm.businessUser" />
            </el-form-item>
            <el-form-item label="联系电话" prop="businessPhone">
              <el-input v-model="reqForm.businessPhone" />
            </el-form-item>
            <el-form-item label="品名" prop="productType">
              <el-input v-model="reqForm.productType" />
            </el-form-item>
            <el-form-item label="交货期(天)" prop="deliveryCycle">
              <el-input-number v-model="reqForm.deliveryCycle" :min="0" :max="999" style="width:100%" />
            </el-form-item>
            <el-form-item label="产品用途" prop="usePurpose">
              <el-input v-model="reqForm.usePurpose" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="厚度公差" prop="thicknessTolerance">
              <el-input v-model="reqForm.thicknessTolerance" />
            </el-form-item>
            <el-form-item label="宽度公差" prop="widthTolerance">
              <el-input v-model="reqForm.widthTolerance" />
            </el-form-item>
            <el-form-item label="表面质量" prop="surfaceQuality">
              <el-input v-model="reqForm.surfaceQuality" />
            </el-form-item>
            <el-form-item label="表面处理" prop="surfaceTreatment">
              <el-input v-model="reqForm.surfaceTreatment" />
            </el-form-item>
            <el-form-item label="内径尺寸" prop="innerDiameter">
              <el-input v-model="reqForm.innerDiameter" />
            </el-form-item>
            <el-form-item label="外径要求" prop="outerDiameter">
              <el-input v-model="reqForm.outerDiameter" />
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 包装及其他 -->
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="包装要求" prop="packReq">
              <el-input v-model="reqForm.packReq" />
            </el-form-item>
            <el-form-item label="切边要求" prop="cutEdgeReq">
              <el-input v-model="reqForm.cutEdgeReq" />
            </el-form-item>
            <el-form-item label="单件重量" prop="singleCoilWeight">
              <el-input v-model="reqForm.singleCoilWeight" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="交货重量偏差" prop="weightDeviation">
              <el-input v-model="reqForm.weightDeviation" />
            </el-form-item>

            <el-form-item label="付款情况说明" prop="paymentDesc">
              <el-input v-model="reqForm.paymentDesc" type="textarea" :rows="2" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="24">
            <el-form-item label="其他技术要求" prop="otherTechReq">
              <el-input v-model="reqForm.otherTechReq" type="textarea" :rows="2" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="备注" prop="remark">
          <el-input v-model="reqForm.remark" type="textarea" :rows="2" />
        </el-form-item>
      </el-form>
        </div>
        <!-- 右侧：历史记录 -->
        <div style="width: 200px; flex-shrink: 0;" v-if="!reqForm.scheduleId && scheduleNoHistory.length > 0">
          <div style="font-size: 13px; font-weight: 600; color: #2c3e50; margin-bottom: 8px; padding-left: 8px; border-left: 3px solid #ff4d4f;">
            历史记录
          </div>
          <div style="border: 1px solid #e4e7ed; border-radius: 4px; max-height: 450px; overflow-y: auto;">
            <div v-for="item in scheduleNoHistory" :key="item.scheduleNo" class="history-item"
              @click="useHistoryRecord(item)"
              style="padding: 8px 10px; border-bottom: 1px solid #ecf0f1; cursor: pointer; font-size: 12px; transition: background 0.15s;">
              <div style="font-weight: 500; color: #2c3e50;">{{ item.scheduleNo }}</div>
              <div style="color: #7f8c8d; margin-top: 2px;">{{ item.customerName || '-' }}</div>
              <div style="color: #b0b0b0; font-size: 11px;">{{ item.prodDate || '-' }}</div>
            </div>
          </div>
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button :loading="btnLoading" type="danger" @click="submitForm">确 定</el-button>
        <el-button @click="dialogVisible = false">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 绑定订单对话框 -->
    <el-dialog title="添加绑定订单" :visible.sync="bindDialogVisible" width="860px" append-to-body
      :close-on-click-modal="false" class="aps-bind-dialog">
      <div style="display: flex; gap: 16px; height: 420px;">
        <!-- 左侧：订单列表 -->
        <div style="width: 45%; display: flex; flex-direction: column;">
          <div style="display: flex; gap: 6px; margin-bottom: 10px;">
            <el-input v-model="bindQuery.keyword" placeholder="搜索订单编号/客户名" size="small" clearable style="flex:1;"
              @change="searchBindOrders" />
            <el-button size="small" class="aps-btn-red" icon="el-icon-search" @click="searchBindOrders">搜索</el-button>
          </div>
          <div style="flex:1; overflow-y: auto; border: 1px solid #e4e7ed; border-radius: 4px;"
            v-loading="bindSearchLoading" element-loading-text="搜索中...">
            <div v-for="item in candidateOrderList" :key="item.orderId" class="bind-order-item"
              :class="{ selected: isBindSelected(item), previewing: bindPreviewOrder && bindPreviewOrder.orderId === item.orderId }"
              @click="handleBindRowClick(item)">
              <el-checkbox :value="isBindSelected(item)" @change="toggleBindOrder(item)" @click.stop
                style="margin-right: 8px;" />
              <div style="flex:1; min-width:0;">
                <div style="font-weight:500; font-size:13px; color:#2c3e50;">{{ item.orderCode }}</div>
                <div style="font-size:11px; color:#7f8c8d; margin-top:2px;">{{ item.companyName }} · {{ item.salesman }}
                </div>
              </div>
            </div>
            <div v-if="candidateOrderList.length === 0" style="padding:30px; text-align:center; color:#909399;">暂无订单
            </div>
          </div>
        </div>

        <!-- 右侧：产品内容预览 + 已绑定产需单信息 -->
        <div style="width: 55%; display: flex; flex-direction: column;">
          <div
            style="font-size:13px; font-weight:600; color:#2c3e50; margin-bottom:8px; padding-left:8px; border-left:3px solid #ff4d4f;">
            {{ bindPreviewOrder ? bindPreviewOrder.orderCode + ' - 产品明细' : '点击订单行预览产品明细' }}
          </div>
          <div style="flex:1; overflow-y: auto; border: 1px solid #e4e7ed; border-radius: 4px; padding: 10px;"
            v-if="bindPreviewOrder">
            <el-table :data="bindPreviewProducts" border size="small" style="width:100%;">
              <el-table-column label="规格" prop="spec" min-width="100" />
              <el-table-column label="材质" prop="material" width="80" />
              <el-table-column label="数量(吨)" prop="quantity" width="80" align="right" />
              <!-- <el-table-column label="含税单价" prop="taxPrice" width="80" align="right" /> -->
              <el-table-column label="备注" prop="remark" min-width="80" />
            </el-table>
            <div style="margin-top:8px; font-size:12px; color:#7f8c8d; display:flex; gap:16px;">
              <span>产品名称：{{ bindPreviewProductName }}</span>
              <span>总数量：{{ bindPreviewTotalQty }} 吨</span>
              <span>含税总额：{{ bindPreviewTotalAmount }}</span>
            </div>
            <!-- 已绑定产需单信息 -->
            <div v-if="bindPreviewExistingRels.length > 0" style="margin-top:12px; padding-top:10px; border-top:1px dashed #e4e7ed;">
              <div style="font-size:12px; font-weight:600; color:#e74c3c; margin-bottom:6px;">
                该订单已绑定以下产需单：
              </div>
              <div style="display:flex; flex-wrap:wrap; gap:6px;">
                <el-tag
                  v-for="rel in bindPreviewExistingRels"
                  :key="rel.scheduleId"
                  size="small"
                  :type="rel.scheduleStatus === 3 ? 'danger' : 'info'"
                  effect="plain"
                  :style="rel.scheduleStatus === 2 ? 'color:#555;border-color:#ccc;background:#f5f5f5;' : ''"
                >
                  {{ rel.scheduleNo }}
                  <span style="margin-left:4px; opacity:0.7;">{{ bindPreviewRelStatusMap[rel.scheduleStatus] || '' }}</span>
                </el-tag>
              </div>
            </div>
          </div>
          <div v-else
            style="flex:1; display:flex; align-items:center; justify-content:center; color:#bfbfbf; font-size:13px;">
            请点击左侧订单行查看产品明细
          </div>
        </div>
      </div>

      <div slot="footer" class="dialog-footer" style="margin-top:12px;">
        <span style="font-size:12px; color:#7f8c8d; margin-right:auto;">已选 {{ selectedBindOrders.length }} 个订单</span>
        <el-button :loading="bindBtnLoading" type="danger" @click="confirmBind">确 定 绑 定</el-button>
        <el-button @click="bindDialogVisible = false">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 排产明细新增/编辑对话框 -->
    <el-dialog :title="detailDialogTitle" :visible.sync="detailDialogVisible" width="500px" append-to-body
      :close-on-click-modal="false">
      <el-form ref="detailForm" :model="detailForm" :rules="detailFormRules" label-width="100px" size="small">
        <el-form-item label="规格" prop="spec">
          <el-input v-model="detailForm.spec" placeholder="请输入规格" />
        </el-form-item>
        <el-form-item label="材质" prop="material">
          <el-input v-model="detailForm.material" placeholder="请输入材质" />
        </el-form-item>
        <el-form-item label="排产吨数" prop="scheduleWeight">
          <el-input-number v-model="detailForm.scheduleWeight" :min="0" :precision="3" :controls="false"
            style="width:100%" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="detailForm.remark" type="textarea" :rows="2" placeholder="可选" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button :loading="detailBtnLoading" type="danger" @click="submitDetailForm">确 定</el-button>
        <el-button @click="detailDialogVisible = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  listRequirement,
  getRequirement,
  addRequirement,
  updateRequirement,
  delRequirement,
  addRel,
  delRel,
  listRel,
  addRequirementDetail,
  updateRequirementDetail,
  delRequirementDetail
} from '@/api/aps/requirement'
import { listCrmOrder } from '@/api/aps/order'
import { parseProductContent } from '@/utils/productContent'

export default {
  name: 'ApsRequirement',
  data() {
    return {
      // 左侧列表
      reqLoading: false,
      reqList: [],
      total: 0,
      currentReq: null,
      queryParams: {
        scheduleNo: '',
        prodDate: '',
        customerName: '',
        pageNum: 1,
        pageSize: 10
      },
      statusMap: { 0: '草稿', 1: '待审核', 2: '已下达', 3: '已退回' },
      statusBadgeMap: { 0: 'gray', 1: 'blue', 2: 'green', 3: 'red' },

      // 绑定订单
      bindDialogVisible: false,
      bindQuery: { keyword: '', pageNum: 1, pageSize: 50 },
      candidateOrderList: [],
      selectedBindOrders: [],
      bindBtnLoading: false,
      bindSearchLoading: false,
      bindPreviewOrder: null,
      bindPreviewProducts: [],
      bindPreviewProductName: '',
      bindPreviewTotalQty: 0,
      bindPreviewTotalAmount: 0,
      // 当前预览订单已绑定的产需单列表
      bindPreviewExistingRels: [],
      // 产需单状态映射（用于展示绑定状态）
      bindPreviewRelStatusMap: { 0: '草稿', 1: '待审核', 2: '已下达', 3: '已退回' },

      // 排产明细
      detailLoading: false,
      requirementDetailList: [],

      // 排产明细新增/编辑对话框
      detailDialogVisible: false,
      detailDialogTitle: '新增排产明细',
      detailBtnLoading: false,
      detailForm: this.getEmptyDetailForm(),
      detailFormRules: {
        spec: [{ required: true, message: '规格不能为空', trigger: 'blur' }],
        material: [{ required: true, message: '材质不能为空', trigger: 'blur' }],
        scheduleWeight: [{ required: true, message: '排产吨数不能为空', trigger: 'change' }]
      },

      // 新增/编辑对话框
      dialogVisible: false,
      dialogTitle: '新增产需单',
      btnLoading: false,
      scheduleNoHistory: [],
      reqForm: this.getEmptyForm(),
      reqRules: {
        scheduleNo: [{ required: true, message: '产需单号不能为空', trigger: 'blur' }],
        prodDate: [{ required: true, message: '生产日期不能为空', trigger: 'change' }]
      }
    }
  },
  computed: {
    canEdit() {
      return this.currentReq && (this.currentReq.scheduleStatus === 0 || this.currentReq.scheduleStatus === 3)
    },
    detailTotalWeight() {
      return this.requirementDetailList.reduce((sum, item) => {
        const n = Number(item.scheduleWeight)
        return isNaN(n) ? sum : sum + n
      }, 0)
    }
  },
  created() {
    this.getList()
  },
  methods: {
    getEmptyForm() {
      return {
        scheduleId: undefined,
        scheduleNo: '',
        prodDate: '',
        customerName: '',
        businessUser: '',
        businessPhone: '',
        deliveryCycle: undefined,
        usePurpose: '',
        productType: '',
        thicknessTolerance: '',
        widthTolerance: '',
        surfaceQuality: '',
        surfaceTreatment: '',
        innerDiameter: '',
        outerDiameter: '',
        packReq: '',
        cutEdgeReq: '',
        singleCoilWeight: '',
        weightDeviation: '',
        otherTechReq: '',
        paymentDesc: '',
        remark: ''
      }
    },

    getEmptyDetailForm() {
      return {
        scheduleDetailId: undefined,
        scheduleId: undefined,
        orderDetailId: undefined,
        spec: '',
        material: '',
        scheduleWeight: 0,
        productType: '',
        remark: ''
      }
    },

    handleSearch() {
      this.queryParams.pageNum = 1
      this.getList()
    },

    // 跳转到排产单页面（路由跳转）
    handleJumpToSchedule(item) {
      this.$router.push({
        path: '/aps/schedule',
        query: {
          prodDate: item.prodDate || '',
          scheduleNo: item.scheduleNo || '',
          scheduleStatus: item.scheduleStatus
        }
      })
    },

    statusBadgeType(status) {
      return this.statusBadgeMap[status] || 'gray'
    },

    getList() {
      this.reqLoading = true
      listRequirement(this.queryParams).then(res => {
        this.reqList = res.rows || []
        this.total = res.total || 0
      }).catch(() => {
        this.reqList = []
        this.total = 0
      }).finally(() => {
        this.reqLoading = false
      })
    },

    handleReqClick(item) {
      this.currentReq = item
      this.detailLoading = true
      getRequirement(item.scheduleId).then(res => {
        if (res.data) {
          this.currentReq = res.data
          this.requirementDetailList = res.data.detailList || []
        }
      }).catch(() => {
        this.requirementDetailList = []
      }).finally(() => {
        this.detailLoading = false
      })
    },

    // ====== 新增/编辑 ======
    resetForm() {
      this.reqForm = this.getEmptyForm()
    },

    handleAdd() {
      this.resetForm()
      this.reqForm.scheduleNo = this.generateScheduleNo()
      this.reqForm.prodDate = this.getTodayStr()
      const lastForm = this.getLastFormData()
      if (lastForm) {
        Object.keys(lastForm).forEach(key => {
          if (key !== 'scheduleId' && key !== 'scheduleNo' && key !== 'prodDate' && lastForm[key] !== undefined && lastForm[key] !== '' && lastForm[key] !== null) {
            this.reqForm[key] = lastForm[key]
          }
        })
      }
      this.scheduleNoHistory = this.getScheduleNoHistory()
      this.dialogTitle = '新增产需单'
      this.dialogVisible = true
      this.$nextTick(() => {
        this.$refs.reqForm && this.$refs.reqForm.clearValidate()
      })
    },

    handleEdit(item) {
      getRequirement(item.scheduleId).then(res => {
        this.reqForm = { ...this.getEmptyForm(), ...res.data }
        this.dialogTitle = '编辑产需单'
        this.dialogVisible = true
        this.$nextTick(() => {
          this.$refs.reqForm && this.$refs.reqForm.clearValidate()
        })
      })
    },

    submitForm() {
      this.$refs.reqForm.validate(valid => {
        if (!valid) return
        this.btnLoading = true
        const isNew = !this.reqForm.scheduleId
        const action = isNew ? addRequirement : updateRequirement
        action(this.reqForm).then(() => {
          this.$modal.msgSuccess(isNew ? '新增成功' : '修改成功')
          if (isNew) {
            this.saveHistoryRecord(this.reqForm)
            this.saveLastFormData(this.reqForm)
          }
          this.dialogVisible = false
          this.getList()
        }).catch(() => {
          this.$modal.msgError('操作失败')
        }).finally(() => {
          this.btnLoading = false
        })
      })
    },

    handleDelete(item) {
      this.$confirm(`确认删除产需单「${item.scheduleNo}」吗？`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        delRequirement(item.scheduleId).then(() => {
          this.$modal.msgSuccess('删除成功')
          if (this.currentReq && this.currentReq.scheduleId === item.scheduleId) {
            this.currentReq = null
          }
          this.getList()
        })
      }).catch(() => { })
    },

    getTodayStr() {
      return new Date().toISOString().split('T')[0]
    },

    generateScheduleNo() {
      const now = new Date()
      const dateStr = now.getFullYear().toString() +
        (now.getMonth() + 1).toString().padStart(2, '0') +
        now.getDate().toString().padStart(2, '0')
      const prefix = 'PCXD' + dateStr
      const existingNums = this.reqList
        .filter(item => item.scheduleNo && item.scheduleNo.startsWith(prefix))
        .map(item => {
          const seq = parseInt(item.scheduleNo.substring(prefix.length), 10)
          return isNaN(seq) ? 0 : seq
        })
      const maxSeq = existingNums.length > 0 ? Math.max(...existingNums) : 0
      const newSeq = (maxSeq + 1).toString().padStart(3, '0')
      return prefix + newSeq
    },

    getScheduleNoHistory() {
      try {
        return JSON.parse(localStorage.getItem('aps_requirement_history') || '[]')
      } catch (e) {
        return []
      }
    },

    saveHistoryRecord(formData) {
      if (!formData.scheduleNo) return
      const history = this.getScheduleNoHistory()
      const idx = history.findIndex(item => item.scheduleNo === formData.scheduleNo)
      if (idx >= 0) history.splice(idx, 1)
      history.unshift({ ...formData })
      delete history[0].scheduleId
      if (history.length > 20) history.pop()
      localStorage.setItem('aps_requirement_history', JSON.stringify(history))
    },

    useHistoryRecord(item) {
      Object.keys(item).forEach(key => {
        if (key !== 'scheduleId' && item[key] !== undefined) {
          this.reqForm[key] = item[key]
        }
      })
      this.$nextTick(() => {
        this.$refs.reqForm && this.$refs.reqForm.clearValidate()
      })
    },

    getLastFormData() {
      try {
        return JSON.parse(localStorage.getItem('aps_requirement_last_form') || 'null')
      } catch (e) {
        return null
      }
    },

    saveLastFormData(formData) {
      const data = { ...formData }
      delete data.scheduleId
      localStorage.setItem('aps_requirement_last_form', JSON.stringify(data))
    },

    openBindDialog() {
      this.bindDialogVisible = true
      this.selectedBindOrders = []
      this.bindPreviewOrder = null
      this.bindPreviewProducts = []
      this.bindPreviewProductName = ''
      this.bindPreviewTotalQty = 0
      this.bindPreviewTotalAmount = 0
      this.bindPreviewExistingRels = []
      this.searchBindOrders()
    },

    searchBindOrders() {
      this.bindSearchLoading = true
      listCrmOrder(this.bindQuery).then(res => {
        const boundOrderIds = (this.currentReq?.orderList || []).map(o => o.orderId)
        this.candidateOrderList = (res.rows || []).filter(o => !boundOrderIds.includes(o.orderId))
      }).catch(() => {
        this.candidateOrderList = []
      }).finally(() => {
        this.bindSearchLoading = false
      })
    },

    isBindSelected(order) {
      return this.selectedBindOrders.some(o => o.orderId === order.orderId)
    },

    toggleBindOrder(order) {
      const idx = this.selectedBindOrders.findIndex(o => o.orderId === order.orderId)
      if (idx >= 0) {
        this.selectedBindOrders.splice(idx, 1)
      } else {
        this.selectedBindOrders.push(order)
      }
    },

    handleBindRowClick(order) {
      this.bindPreviewOrder = order
      if (order.productContent) {
        const parsed = parseProductContent(order.productContent)
        this.bindPreviewProducts = parsed.products || []
        this.bindPreviewProductName = parsed.productName || ''
        this.bindPreviewTotalQty = parsed.totalQuantity || 0
        this.bindPreviewTotalAmount = parsed.totalTaxTotal || 0
      } else {
        this.bindPreviewProducts = []
        this.bindPreviewProductName = ''
        this.bindPreviewTotalQty = 0
        this.bindPreviewTotalAmount = 0
      }
      // 查询该订单已关联了哪些产需单
      this.bindPreviewExistingRels = []
      listRel({ orderId: order.orderId }).then(res => {
        const rows = res.rows || []
        // 按 scheduleId 去重，并与当前已有的 reqList 匹配获取单号
        const seen = new Set()
        const reqMap = new Map()
        ;(this.reqList || []).forEach(r => reqMap.set(r.scheduleId, r))
        const unique = []
        rows.forEach(r => {
          const key = r.scheduleId
          if (!key || seen.has(key)) return
          seen.add(key)
          // 从已加载的 reqList 中找单号，找不到则不展示（已删除或不在当前页）
          const match = reqMap.get(key)
          if (match) {
            unique.push({ ...r, scheduleNo: match.scheduleNo, scheduleStatus: match.scheduleStatus })
          }
        })
        this.bindPreviewExistingRels = unique
      }).catch(() => {
        this.bindPreviewExistingRels = []
      })
    },

    confirmBind() {
      if (this.selectedBindOrders.length === 0) {
        this.$message.warning('请选择要绑定的订单')
        return
      }
      this.bindBtnLoading = true
      const scheduleId = this.currentReq.scheduleId

      const orderTasks = this.selectedBindOrders.map(order => {
        return addRel({
          orderId: order.orderId,
          scheduleId: scheduleId,
          relWeight: null,
          remark: ''
        }).then(() => {
          if (!order.productContent) return
          let products = []
          let productType = ''
          try {
            const parsed = parseProductContent(order.productContent)
            products = (parsed.products || []).filter(p => p.spec && p.material)
            productType = parsed.productName || ''
          } catch (e) {
            return
          }
          if (products.length === 0) return
          const detailPromises = products.map(prod =>
            addRequirementDetail({
              scheduleId: scheduleId,
              orderDetailId: order.orderId,
              spec: prod.spec,
              material: prod.material,
              scheduleWeight: prod.quantity || 0,
              productType: productType,
              remark: prod.remark || ''
            })
          )
          return Promise.all(detailPromises)
        })
      })

      Promise.allSettled(orderTasks).then(results => {
        const successCount = results.filter(r => r.status === 'fulfilled').length
        const failCount = results.filter(r => r.status === 'rejected').length
        this.bindDialogVisible = false
        this.handleReqClick(this.currentReq)
        if (failCount === 0) {
          this.$modal.msgSuccess(`成功绑定 ${successCount} 个订单，排产明细已生成`)
        } else if (successCount === 0) {
          this.$modal.msgError('绑定失败，请重试')
        } else {
          this.$modal.msgWarning(`成功绑定 ${successCount} 个，${failCount} 个失败`)
        }
      }).finally(() => {
        this.bindBtnLoading = false
      })
    },

    handleUnbindByOrderId(order) {
      this.$confirm('确认解绑该订单吗？解绑将同时删除对应的排产明细。', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const tasks = []
        // 1. 删除该订单关联的排产明细
        const detailIds = this.requirementDetailList
          .filter(d => d.orderDetailId === order.orderId)
          .map(d => d.scheduleDetailId)
        detailIds.forEach(id => {
          tasks.push(delRequirementDetail(id))
        })
        // 2. 查询并删除关联表记录
        tasks.push(
          listRel({ orderId: order.orderId, scheduleId: this.currentReq.scheduleId }).then(res => {
            const rows = res.rows || []
            if (rows.length === 0) {
              throw new Error('未找到关联记录')
            }
            const relId = rows[0].id || rows[0].relId
            return delRel(relId)
          })
        )
        Promise.all(tasks).then(() => {
          this.$modal.msgSuccess('解绑成功')
          this.handleReqClick(this.currentReq)
        }).catch(() => {
          this.$modal.msgError('解绑失败')
        })
      }).catch(() => { })
    },

    // ====== 下发 ======
    handleDispatch() {
      this.$confirm('确认下发该产需单吗？下发后将进入审核流程。', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        updateRequirement({
          scheduleId: this.currentReq.scheduleId,
          scheduleStatus: 1
        }).then(() => {
          this.$modal.msgSuccess('下发成功')
          this.getList()
          this.handleReqClick(this.currentReq)
        }).catch(() => {
          this.$modal.msgError('下发失败')
        })
      }).catch(() => { })
    },

    // ====== 排产明细新增/编辑/删除 ======
    resetDetailForm() {
      this.detailForm = this.getEmptyDetailForm()
    },

    handleDetailAdd() {
      if (!this.currentReq) {
        this.$message.warning('请先选择一个产需单')
        return
      }
      this.resetDetailForm()
      this.detailForm.scheduleId = this.currentReq.scheduleId
      this.detailDialogTitle = '新增排产明细'
      this.detailDialogVisible = true
      this.$nextTick(() => {
        this.$refs.detailForm && this.$refs.detailForm.clearValidate()
      })
    },

    handleDetailEdit(row) {
      this.detailForm = { ...this.getEmptyDetailForm(), ...row }
      this.detailDialogTitle = '编辑排产明细'
      this.detailDialogVisible = true
      this.$nextTick(() => {
        this.$refs.detailForm && this.$refs.detailForm.clearValidate()
      })
    },

    submitDetailForm() {
      this.$refs.detailForm.validate(valid => {
        if (!valid) return
        this.detailBtnLoading = true
        const formData = { ...this.detailForm }
        if (this.detailForm.scheduleDetailId) {
          // 更新
          updateRequirementDetail(formData).then(() => {
            this.$modal.msgSuccess('修改成功')
            this.detailDialogVisible = false
            this.refreshDetailList()
          }).catch(() => {
            this.$modal.msgError('修改失败')
          }).finally(() => {
            this.detailBtnLoading = false
          })
        } else {
          // 新增
          addRequirementDetail(formData).then(() => {
            this.$modal.msgSuccess('新增成功')
            this.detailDialogVisible = false
            this.refreshDetailList()
          }).catch(() => {
            this.$modal.msgError('新增失败')
          }).finally(() => {
            this.detailBtnLoading = false
          })
        }
      })
    },

    handleDetailDelete(row) {
      this.$confirm(`确认删除排产明细「${row.spec} / ${row.material}」吗？`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        delRequirementDetail(row.scheduleDetailId).then(() => {
          this.$modal.msgSuccess('删除成功')
          this.refreshDetailList()
        }).catch(() => {
          this.$modal.msgError('删除失败')
        })
      }).catch(() => { })
    },

    refreshDetailList() {
      if (!this.currentReq) return
      this.detailLoading = true
      getRequirement(this.currentReq.scheduleId).then(res => {
        if (res.data) {
          this.requirementDetailList = res.data.detailList || []
        }
      }).catch(() => {
        this.requirementDetailList = []
      }).finally(() => {
        this.detailLoading = false
      })
    },
  }
}
</script>

<style scoped lang="scss">
@import './scss/aps-theme.scss';

.aps-req-page {
  height: 100%;
  padding: 8px;
  box-sizing: border-box;
  background: $aps-silver-1;
}

.aps-req-row {
  height: 100%;
}

// ====== 左侧（参照 HTML 产需单列表） ======
.aps-req-left {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #fff;
  border: 1px solid $aps-silver-3;
  border-radius: 6px;
  box-sizing: border-box;
  overflow: hidden;
  min-height: 0;
}

.panel-header {
  background: $aps-silver-mid;
  padding: 8px 12px;
  font-size: 12px;
  font-weight: 600;
  color: $aps-text;
  border-bottom: 1px solid $aps-border;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.list-container {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

.list-item {
  padding: 10px 12px;
  border-bottom: 1px solid $aps-silver-1;
  cursor: pointer;
  transition: background 0.15s;
}

.list-item-body {
  display: flex;
  align-items: stretch;
  gap: 8px;
}

.list-item-left {
  flex: 1;
  min-width: 0;
}

.list-item-right {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  padding-left: 4px;
}

.item-actions {
  display: flex;
  gap: 8px;
  margin-top: 4px;
}

.list-item:hover {
  background: $aps-silver-1;
}

.list-item.active {
  background: $aps-red-1;
  border-left: 3px solid $aps-red-2;
}

.list-item .item-title {
  font-weight: 500;
  color: $aps-text;
  font-size: 13px;
  margin-bottom: 3px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.list-item .item-sub {
  font-size: 12px;
  color: $aps-text-muted;
  margin-bottom: 4px;
}


// ====== 徽标 ======
.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 500;
}

.badge-red {
  background: #fdecea;
  color: $aps-red-2;
  border: 1px solid #f5b7b1;
}

.badge-green {
  background: #eafaf1;
  color: #27ae60;
  border: 1px solid #a9dfbf;
}

.badge-blue {
  background: #eaf4fb;
  color: #2980b9;
  border: 1px solid #aed6f1;
}

.badge-gray {
  background: $aps-silver-1;
  color: $aps-text-muted;
  border: 1px solid $aps-border;
}

// ====== 右侧（平铺） ======
.aps-req-right {
  height: 100%;
  background: #fff;
  border: 1px solid $aps-silver-3;
  border-radius: 6px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
}

.detail-panel {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  background: $aps-bg;
  min-height: 0;
}

// ====== 右侧详情卡片 ======
.detail-card {
  background: $aps-white;
  border: 1px solid $aps-border;
  border-radius: $aps-radius;
  box-shadow: $aps-shadow-sm;
  overflow: hidden;
}

.detail-card-header {
  background: linear-gradient(to right, $aps-red-2, $aps-red-3);
  color: white;
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.detail-card-header .header-btn {
  background: rgba(255, 255, 255, 0.25);
  color: white;
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 3px;
  padding: 4px 12px;
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
}

.detail-card-header .header-btn:hover {
  background: rgba(255, 255, 255, 0.4);
  border-color: rgba(255, 255, 255, 0.7);
}

.detail-card-header .header-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.detail-card-body {
  padding: 0;
}

.req-info-table {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid $aps-border;
  font-size: 13px;

  td {
    border: 1px solid $aps-border;
    padding: 6px 10px;
    vertical-align: middle;
  }

  .req-td-label {
    background: $aps-silver-1;
    color: $aps-text-muted;
    font-weight: 500;
    font-size: 12px;
    white-space: nowrap;
    width: 100px;
    text-align: right;
  }

  .req-td-value {
    color: $aps-text;
    background: #fff;
    word-break: break-all;

    &:empty::after {
      content: '-';
      color: $aps-silver-3;
    }
  }
}

.aps-status-tag {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 3px;
  font-size: 12px;
  font-weight: 500;

  &.status-0 {
    background: $aps-silver-2;
    color: $aps-silver-4;
  }

  &.status-1 {
    background: #e6f7ff;
    color: #1890ff;
  }

  &.status-2 {
    background: #f6ffed;
    color: #52c41a;
  }

  &.status-3 {
    background: $aps-red-1;
    color: $aps-red-2;
  }
}

.aps-table {
  width: 100%;

  ::v-deep th {
    background: $aps-silver-1 !important;
    color: $aps-silver-5 !important;
    font-weight: 600 !important;
  }
}

.link-btn {
  color: $aps-red-2;
  cursor: pointer;
  font-size: 12px;
  text-decoration: none;
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
}

.link-btn:hover {
  text-decoration: underline;
}

// ====== Element 按钮覆盖 ======
::v-deep .el-button--danger {
  background: $aps-red-2;
  border-color: $aps-red-2;
}

::v-deep .el-button--danger:hover {
  background: $aps-red-3;
  border-color: $aps-red-3;
}

// ====== 按钮 ======
.aps-btn-red {
  @include aps-btn-red;
}

.aps-btn-silver {
  @include aps-btn-silver;
}

// ====== 绑定订单卡片 ======
.bound-order-cards {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.bound-order-card {
  border: 1px solid $aps-border;
  border-radius: $aps-radius;
  background: $aps-white;
  flex: 1;
  min-width: 200px;
  max-width: 300px;
}

.bound-order-card .bound-order-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  background: $aps-silver-1;
  border-bottom: 1px solid $aps-border;
  font-size: 13px;
  font-weight: 600;
  color: $aps-text;
  border-radius: $aps-radius $aps-radius 0 0;
}

.bound-order-card .bound-order-card-body {
  padding: 10px 12px;
}

// ====== 绑定弹窗 ======
.bind-order-item {
  display: flex;
  align-items: center;
  padding: 8px 10px;
  border-bottom: 1px solid #ecf0f1;
  cursor: pointer;
  transition: background 0.15s;
}

.bind-order-item:hover {
  background: #f5f5f5;
}

.bind-order-item.selected {
  background: #fdecea;
}

.bind-order-item.previewing {
  background: #fdecea;
  border-left: 3px solid $aps-red-2;
}

.aps-bind-dialog ::v-deep .el-dialog__body {
  padding: 16px 20px 0 20px;
}

.history-item:hover {
  background: #fdecea;
}
</style>
