<template>
  <Teleport to="body">
    <div v-if="open" class="workflow-drawer-mask" @click.self="handleClose">
      <aside class="workflow-drawer product-workflow-drawer">
        <header class="workflow-drawer-head">
          <div>
            <p class="eyebrow">02-1 产品流程配置</p>
            <div class="drawer-title-row" title="把产品资料、供应商、原材料、BOM 和工艺路线收进同一个配置流程，减少来回跳转。">
              <h3>{{ workflowMode === "edit" ? "编辑产品流程" : "新增产品流程" }}</h3>
            </div>
          </div>
          <div class="workflow-drawer-head-actions">
            <span class="panel-tag">{{ currentProductLabel || "未保存产品" }}</span>
            <button class="ghost-button" type="button" :disabled="isBusy" @click="handleClose">关闭</button>
          </div>
        </header>

        <div ref="drawerScrollRef" class="workflow-drawer-scroll">
        <div v-if="feedbackMessage" class="feedback-banner">{{ feedbackMessage }}</div>
        <div v-if="errorMessage" class="feedback-banner error-banner">{{ errorMessage }}</div>

        <div class="workflow-stepper">
          <button
            v-for="(step, index) in workflowSteps"
            :key="step.key"
            class="workflow-step"
            :class="{
              'workflow-step-active': index === currentStepIndex,
              'workflow-step-completed': index < currentStepIndex,
              'workflow-step-locked': step.requiresProduct && !currentProductId
            }"
            type="button"
            @click="goToStep(index)"
          >
            <span class="workflow-step-index">{{ String(index + 1).padStart(2, "0") }}</span>
            <div class="workflow-step-body" :title="step.desc">
              <strong>{{ step.label }}</strong>
            </div>
          </button>
        </div>

        <div class="workflow-drawer-grid">
        <section class="workflow-drawer-main">
          <div v-if="busy.loading" class="workflow-empty-card">正在加载流程资料...</div>

          <template v-else-if="activeStep.key === 'product'">
            <section class="workflow-section-card">
              <div class="panel-header">
                <div>
                  <p class="eyebrow">步骤一</p>
                  <span
                    class="title-with-help"
                    title="同一产品编码允许维护多个版本。编辑时如果修改版本号，系统会自动保存成新版本。"
                  >
                    <h3>产品资料</h3>
                  </span>
                </div>
                <span class="panel-tag">{{ workflowMode === "edit" ? "编辑模式" : "新建模式" }}</span>
              </div>

              <form class="stack-form" @submit.prevent="saveProduct(false)">
                <div class="double-field">
                  <label class="form-field">
                    <span>产品编码</span>
                    <input :value="productCodePreview" type="text" disabled readonly />
                  </label>
                  <label class="form-field">
                    <span>版本号 <i class="required-mark">*</i></span>
                    <input v-model.trim="productForm.version_no" type="text" required />
                  </label>
                </div>

                <label class="form-field">
                  <span>产品名称 <i class="required-mark">*</i></span>
                  <input v-model.trim="productForm.item_name" type="text" required />
                </label>

                <div class="double-field">
                  <label class="form-field">
                    <span>产品规格</span>
                    <input v-model.trim="productForm.specification" type="text" />
                  </label>
                  <label class="form-field">
                    <span>图号</span>
                    <input v-model.trim="productForm.drawing_no" type="text" />
                  </label>
                </div>

                <div class="double-field">
                  <label class="form-field">
                    <span>产品系列</span>
                    <input v-model.trim="productForm.product_family" type="text" />
                  </label>
                  <label class="form-field">
                    <span>状态</span>
                    <select v-model="productForm.status">
                      <option v-for="option in statusOptions" :key="option.value" :value="option.value">
                        {{ option.label }}
                      </option>
                    </select>
                  </label>
                </div>

                <div class="double-field">
                  <label class="form-field">
                    <span>单重(kg) <i class="required-mark">*</i></span>
                    <input v-model.number="productForm.unit_weight_kg" type="number" min="0.001" step="0.001" required />
                  </label>
                  <label class="form-field">
                    <span>允许报废率</span>
                    <input v-model.number="productForm.allowed_scrap_rate" type="number" min="0" step="0.0001" />
                  </label>
                </div>

                <div class="double-field">
                  <label class="form-field">
                    <span>标准产出数量</span>
                    <input v-model.number="productForm.standard_output_qty" type="number" min="0" step="0.01" />
                  </label>
                  <label class="form-field">
                    <span>安全库存重量(kg)</span>
                    <input v-model.number="productForm.safety_stock_weight_kg" type="number" min="0" step="0.001" />
                  </label>
                </div>

                <label class="form-field">
                  <span>质量标准</span>
                  <textarea v-model.trim="productForm.quality_standard" rows="3"></textarea>
                </label>

                <div class="form-toolbar">
                  <button class="primary-button" type="submit" :disabled="busy.product">
                    {{ busy.product ? "保存中..." : "保存产品资料" }}
                  </button>
                  <button class="ghost-button" type="button" :disabled="busy.product" @click="saveProduct(true)">
                    保存并进入下一步
                  </button>
                </div>
              </form>
            </section>
          </template>

          <template v-else-if="activeStep.key === 'suppliers'">
            <section class="workflow-section-card">
              <div class="panel-header">
                <div>
                  <p class="eyebrow">步骤二</p>
                  <span class="title-with-help" title="这里先勾选后续产品要用到的供应商，没有的供应商可以直接快速新建。">
                    <h3>供应商管理</h3>
                  </span>
                </div>
                <span class="panel-tag">勾选可采购来源</span>
              </div>

              <div class="workflow-selection-bar">
                <strong>已勾选 {{ selectedSupplierIds.length }} 家供应商</strong>
                <button class="ghost-button" type="button" @click="showSupplierCreateForm = !showSupplierCreateForm">
                  {{ showSupplierCreateForm ? "收起新建" : "新建供应商" }}
                </button>
              </div>

              <div class="workflow-picker-grid">
                <label
                  v-for="supplier in suppliers"
                  :key="supplier.id"
                  class="workflow-picker-card"
                  :class="{ 'workflow-picker-card-selected': selectedSupplierIds.includes(supplier.id) }"
                >
                  <input v-model="selectedSupplierIds" type="checkbox" :value="supplier.id" />
                  <div class="workflow-picker-content">
                    <strong>{{ supplier.supplier_name }}</strong>
                    <p>{{ supplier.contact_name || "未维护联系人" }} · {{ supplier.contact_phone || "未维护电话" }}</p>
                    <p>默认税率 {{ Number(supplier.default_tax_rate || 0).toFixed(4) }} · 正式供应商</p>
                  </div>
                </label>

                <div v-if="!suppliers.length" class="workflow-empty-card">还没有供应商，请先新增供应商。</div>
              </div>

              <form v-if="showSupplierCreateForm" class="stack-form workflow-inline-form" @submit.prevent="createSupplier">
                <div class="subsection-head">
                  <strong>快速新建供应商</strong>
                </div>

                <label class="form-field">
                  <span>供应商名称 <i class="required-mark">*</i></span>
                  <input v-model.trim="supplierForm.supplier_name" type="text" required />
                </label>

                <div class="double-field">
                  <label class="form-field">
                    <span>简称</span>
                    <input v-model.trim="supplierForm.short_name" type="text" />
                  </label>
                  <label class="form-field">
                    <span>联系人</span>
                    <input v-model.trim="supplierForm.contact_name" type="text" />
                  </label>
                </div>

                <div class="double-field">
                  <label class="form-field">
                    <span>联系电话</span>
                    <input v-model.trim="supplierForm.contact_phone" type="text" />
                  </label>
                  <label class="form-field">
                    <span>默认税率</span>
                    <input v-model.number="supplierForm.default_tax_rate" type="number" min="0" step="0.0001" />
                  </label>
                  <label class="form-field">
                    <span>状态</span>
                    <select v-model="supplierForm.status">
                      <option v-for="option in statusOptions" :key="option.value" :value="option.value">
                        {{ option.label }}
                      </option>
                    </select>
                  </label>
                </div>

                <label class="form-field">
                  <span>地址</span>
                  <input v-model.trim="supplierForm.address" type="text" />
                </label>

                <label class="form-field">
                  <span>备注</span>
                  <textarea v-model.trim="supplierForm.remark" rows="2"></textarea>
                </label>

                <div class="form-toolbar">
                  <button class="primary-button" type="submit" :disabled="busy.supplier">
                    {{ busy.supplier ? "保存中..." : "保存供应商" }}
                  </button>
                </div>
              </form>
            </section>
          </template>

          <template v-else-if="activeStep.key === 'materials'">
            <section class="workflow-section-card">
              <div class="panel-header">
                <div>
                  <p class="eyebrow">步骤三</p>
                  <span class="title-with-help" title="先选择产品会用到的原材料，BOM 步骤会基于这里的勾选结果自动带入明细候选。">
                    <h3>原材料管理</h3>
                  </span>
                </div>
                <span class="panel-tag">勾选 BOM 候选原料</span>
              </div>

              <div class="workflow-selection-bar">
                <strong>已勾选 {{ selectedMaterialIds.length }} 种原材料</strong>
                <button class="ghost-button" type="button" @click="showMaterialCreateForm = !showMaterialCreateForm">
                  {{ showMaterialCreateForm ? "收起新建" : "新建原材料" }}
                </button>
              </div>

              <div v-if="selectedSuppliers.length" class="workflow-chip-row">
                <span v-for="supplier in selectedSuppliers" :key="supplier.id" class="table-chip">
                  {{ supplier.supplier_name }}
                </span>
              </div>

              <div class="workflow-picker-grid">
                <label
                  v-for="material in filteredMaterials"
                  :key="material.item_id"
                  class="workflow-picker-card"
                  :class="{ 'workflow-picker-card-selected': selectedMaterialIds.includes(material.item_id) }"
                >
                  <input v-model="selectedMaterialIds" type="checkbox" :value="material.item_id" />
                  <div class="workflow-picker-content">
                    <strong>{{ material.item_code }} · {{ material.item_name }}</strong>
                    <p>{{ material.specification || "-" }} · {{ material.material_grade || "-" }}</p>
                    <p>{{ material.supplier_name || "未设默认供应商" }} · 废料单价 {{ Number(material.scrap_sale_price || 0).toFixed(4) }}</p>
                  </div>
                </label>

                <div v-if="!filteredMaterials.length" class="workflow-empty-card">
                  当前没有可选原材料，请先新建原材料或先勾选供应商。
                </div>
              </div>

              <form v-if="showMaterialCreateForm" class="stack-form workflow-inline-form" @submit.prevent="createMaterial">
                <div class="subsection-head">
                  <strong>快速新建原材料</strong>
                </div>

                <div class="double-field">
                  <label class="form-field">
                    <span>原材料编码</span>
                    <input :value="materialCodePreview" type="text" disabled readonly />
                  </label>
                  <label class="form-field">
                    <span>原材料名称 <i class="required-mark">*</i></span>
                    <input v-model.trim="materialForm.item_name" type="text" required />
                  </label>
                </div>

                <div class="double-field">
                  <label class="form-field">
                    <span>规格 <i class="required-mark">*</i></span>
                    <input v-model.trim="materialForm.specification" type="text" required />
                  </label>
                  <label class="form-field">
                    <span>材质牌号 <i class="required-mark">*</i></span>
                    <input v-model.trim="materialForm.material_grade" type="text" required />
                  </label>
                </div>

                <div class="double-field">
                  <label class="form-field">
                    <span>默认供应商 <i class="required-mark">*</i></span>
                    <select v-model.number="materialForm.default_supplier_id" required>
                      <option disabled value="">请选择供应商</option>
                      <option v-for="supplier in suppliers" :key="supplier.id" :value="supplier.id">
                        {{ supplier.supplier_name }}
                      </option>
                    </select>
                  </label>
                  <label class="form-field">
                    <span>状态</span>
                    <select v-model="materialForm.status">
                      <option v-for="option in statusOptions" :key="option.value" :value="option.value">
                        {{ option.label }}
                      </option>
                    </select>
                  </label>
                </div>

                <div class="triple-field">
                  <label class="form-field">
	                    <span>重量基准(kg) <i class="required-mark">*</i></span>
                    <input v-model.number="materialForm.unit_weight_kg" type="number" min="0.001" step="0.001" required />
                  </label>
                  <label class="form-field">
                    <span>安全库存重量(kg)</span>
                    <input v-model.number="materialForm.safety_stock_weight_kg" type="number" min="0" step="0.001" />
                  </label>
                  <label class="form-field">
                    <span>废料单价(元/kg)</span>
                    <input v-model.number="materialForm.scrap_sale_price" type="number" min="0" step="0.0001" />
                  </label>
                </div>

                <div class="triple-field">
                  <label class="form-field">
                    <span>最小采购重量(kg)</span>
                    <input v-model.number="materialForm.min_purchase_qty" type="number" min="0" step="0.001" />
                  </label>
                  <label class="form-field">
                    <span>采购倍数重量(kg) <i class="required-mark">*</i></span>
                    <input
                      v-model.number="materialForm.purchase_multiple_weight_kg"
                      type="number"
                      min="0.001"
                      step="0.001"
                      required
                    />
                  </label>
                  <label class="form-field">
                    <span>采购提前期(天)</span>
                    <input v-model.number="materialForm.lead_time_days" type="number" min="0" step="1" />
                  </label>
                </div>

                <label class="form-field">
                  <span>来料质检规则</span>
                  <input v-model.trim="materialForm.quality_rule" type="text" />
                </label>

                <div class="form-toolbar">
                  <button class="primary-button" type="submit" :disabled="busy.material">
                    {{ busy.material ? "保存中..." : "保存原材料" }}
                  </button>
                </div>
              </form>
            </section>
          </template>

          <template v-else-if="activeStep.key === 'bom'">
            <section class="workflow-section-card">
              <div class="panel-header">
                <div>
                  <p class="eyebrow">步骤四</p>
                  <span
                    class="title-with-help"
                    title="当前 BOM 只针对当前产品版本生效。右侧列表按 BOM 编码聚合版本，编辑时改版本号会自动保存为新版本。"
                  >
                    <h3>BOM 管理</h3>
                  </span>
                </div>
                <div class="workflow-inline-actions">
                  <button class="ghost-button" type="button" :disabled="!currentProductId" @click="resetBomForm(true)">新建 BOM</button>
                  <button class="ghost-button" type="button" :disabled="!selectedMaterialIds.length" @click="seedBomItemsFromSelectedMaterials">
                    从已勾选原料带入
                  </button>
                </div>
              </div>

              <div v-if="!currentProductId" class="workflow-empty-card">请先在步骤一保存产品资料，再维护该产品的 BOM。</div>

              <template v-else>
                <div class="table-wrap">
                  <table class="data-table compact-table">
                    <thead>
                      <tr>
                        <th>BOM编码</th>
                        <th>版本</th>
                        <th>默认</th>
                        <th>状态</th>
                        <th>明细数</th>
                        <th>操作</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr v-for="bom in paginatedBoms" :key="bom.bom_code">
                        <td>{{ bom.bom_code }}</td>
                        <td>
                          <select v-model.number="bomVersionSelections[bom.bom_code]" @change="applyBomVersion(bom.bom_code)">
                            <option v-for="option in bom.version_options" :key="option.bom_id" :value="option.bom_id">
                              {{ option.version_no }}
                            </option>
                          </select>
                        </td>
                        <td>{{ bom.is_default ? "是" : "否" }}</td>
                        <td>{{ formatStatusLabel(bom.status) }}</td>
                        <td>{{ bom.item_count }}</td>
                        <td class="action-row">
                          <button class="ghost-button" type="button" @click="startEditBom(bom)">编辑</button>
                          <button class="ghost-button danger-ghost" type="button" @click="removeBom(bom)">删除</button>
                        </td>
                      </tr>
                      <tr v-if="!visibleBoms.length">
                        <td colspan="6" class="empty-row">当前产品还没有 BOM 版本</td>
                      </tr>
                    </tbody>
                  </table>
                </div>
                <PaginationBar v-model:page="bomPage" v-model:page-size="bomPageSize" :total="visibleBoms.length" />

                <form class="stack-form workflow-inline-form" @submit.prevent="saveBom">
                  <div class="double-field">
                    <label class="form-field">
                      <span>BOM编码</span>
                      <input :value="bomCodePreview" type="text" disabled readonly />
                    </label>
                    <label class="form-field">
                      <span>版本号 <i class="required-mark">*</i></span>
                      <input v-model.trim="bomForm.version_no" type="text" required />
                    </label>
                  </div>

                  <div class="triple-field">
                    <label class="form-field">
                      <span>生效日期</span>
                      <input v-model="bomForm.effective_date" type="date" />
                    </label>
                    <label class="form-field">
                      <span>状态</span>
                      <select v-model="bomForm.status">
                        <option v-for="option in statusOptions" :key="option.value" :value="option.value">
                          {{ option.label }}
                        </option>
                      </select>
                    </label>
                    <label class="checkbox-field workflow-inline-checkbox">
                      <input v-model="bomForm.is_default" type="checkbox" />
                      <span>设为默认 BOM</span>
                    </label>
                  </div>

                  <label class="form-field">
                    <span>备注</span>
                    <textarea v-model.trim="bomForm.remark" rows="2"></textarea>
                  </label>

                  <div class="subsection-head">
                    <strong>BOM明细</strong>
                    <button class="ghost-button" type="button" @click="addBomItem">增加一行</button>
                  </div>

                  <div class="order-item-stack">
                    <article v-for="(item, index) in bomForm.items" :key="index" class="order-item-card">
                      <div class="subsection-head">
                        <strong>明细 {{ index + 1 }}</strong>
                        <button v-if="bomForm.items.length > 1" class="ghost-button danger-ghost" type="button" @click="removeBomItem(index)">
                          删除
                        </button>
                      </div>

                      <div class="double-field">
                        <label class="form-field">
                          <span>序号 <i class="required-mark">*</i></span>
                          <input v-model.number="item.seq_no" type="number" min="1" step="1" required />
                        </label>
                        <label class="form-field">
                          <span>原材料 <i class="required-mark">*</i></span>
                          <select v-model.number="item.material_item_id" required>
                            <option disabled value="">请选择原材料</option>
                            <option v-for="material in bomMaterialOptions" :key="material.item_id" :value="material.item_id">
                              {{ material.item_code }} · {{ material.item_name }}
                            </option>
                          </select>
                        </label>
                      </div>

	                      <label class="form-field">
	                        <span>损耗率</span>
	                        <input v-model.number="item.loss_rate" type="number" min="0" step="0.0001" />
	                      </label>

	                      <div class="triple-field">
	                        <label class="form-field">
	                          <span>单件净重(kg)</span>
	                          <input v-model.number="item.net_weight_per_piece_kg" type="number" min="0" step="0.001" />
                        </label>
                        <label class="form-field">
                          <span>单件毛重(kg) <i class="required-mark">*</i></span>
                          <input v-model.number="item.gross_weight_per_piece_kg" type="number" min="0.001" step="0.001" required />
                        </label>
                        <label class="form-field">
                          <span>超发容差率</span>
	                          <input v-model.number="item.issue_over_tolerance_rate" type="number" min="0" step="0.0001" />
	                        </label>
	                      </div>

                      <label class="form-field">
                        <span>备注</span>
                        <input v-model.trim="item.remark" type="text" />
                      </label>
                    </article>
                  </div>

                  <div class="form-toolbar">
                    <button class="primary-button" type="submit" :disabled="busy.bom">
                      {{ busy.bom ? "保存中..." : editingBomId ? "更新 BOM" : "保存 BOM" }}
                    </button>
                  </div>
                </form>
              </template>
            </section>
          </template>

          <template v-else-if="activeStep.key === 'route'">
            <section class="workflow-section-card">
              <div class="panel-header">
                <div>
                  <p class="eyebrow">步骤五</p>
                  <span class="title-with-help" title="工艺路线只绑定当前产品版本，参考节拍用于后续和真实报工节拍对比。">
                    <h3>工艺路线</h3>
                  </span>
                </div>
                <button class="ghost-button" type="button" :disabled="!currentProductId" @click="resetRouteForm">新建工艺路线</button>
              </div>

              <div v-if="!currentProductId" class="workflow-empty-card">请先在步骤一保存产品资料，再维护该产品的工艺路线。</div>

              <template v-else>
                <div class="table-wrap">
                  <table class="data-table compact-table">
                    <thead>
                      <tr>
                        <th>路线编码</th>
                        <th>版本</th>
                        <th>默认</th>
                        <th>工序数</th>
                        <th>状态</th>
                        <th>操作</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr v-for="route in paginatedRoutes" :key="route.route_code">
                        <td>{{ route.route_code }}</td>
                        <td>
                          <select v-model.number="routeVersionSelections[route.route_code]" @change="applyRouteVersion(route.route_code)">
                            <option v-for="option in route.version_options" :key="option.route_id" :value="option.route_id">
                              {{ option.version_no }}
                            </option>
                          </select>
                        </td>
                        <td>{{ route.is_default ? "是" : "否" }}</td>
                        <td>{{ route.operation_count }}</td>
                        <td>{{ formatStatusLabel(route.status) }}</td>
                        <td class="action-row">
                          <button class="ghost-button" type="button" @click="startEditRoute(route)">编辑</button>
                          <button class="ghost-button danger-ghost" type="button" @click="removeRoute(route)">删除</button>
                        </td>
                      </tr>
                      <tr v-if="!visibleRoutes.length">
                        <td colspan="6" class="empty-row">当前产品还没有工艺路线版本</td>
                      </tr>
                    </tbody>
                  </table>
                </div>
                <PaginationBar v-model:page="routePage" v-model:page-size="routePageSize" :total="visibleRoutes.length" />

                <form class="stack-form workflow-inline-form" @submit.prevent="saveRoute">
                  <div class="double-field">
                    <label class="form-field">
                      <span>路线编码</span>
                      <input :value="routeCodePreview" type="text" disabled readonly />
                    </label>
                    <label class="form-field">
                      <span>路线名称 <i class="required-mark">*</i></span>
                      <input v-model.trim="routeForm.route_name" type="text" required />
                    </label>
                  </div>

                  <div class="triple-field">
                    <label class="form-field">
                      <span>版本号 <i class="required-mark">*</i></span>
                      <input v-model.trim="routeForm.version_no" type="text" required />
                    </label>
                    <label class="form-field">
                      <span>状态</span>
                      <select v-model="routeForm.status">
                        <option v-for="option in statusOptions" :key="option.value" :value="option.value">
                          {{ option.label }}
                        </option>
                      </select>
                    </label>
                    <label class="checkbox-field workflow-inline-checkbox">
                      <input v-model="routeForm.is_default" type="checkbox" />
                      <span>设为默认工艺路线</span>
                    </label>
                  </div>

                  <label class="form-field">
                    <span>备注</span>
                    <textarea v-model.trim="routeForm.remark" rows="2"></textarea>
                  </label>

                  <div class="subsection-head">
                    <strong>工序明细</strong>
                    <button class="ghost-button" type="button" @click="addOperationRow">增加一行</button>
                  </div>

                  <div class="order-item-stack">
                    <article v-for="(operation, index) in routeForm.operations" :key="index" class="order-item-card">
                      <div class="subsection-head">
                        <strong>工序 {{ index + 1 }}</strong>
                        <button
                          v-if="routeForm.operations.length > 1"
                          class="ghost-button danger-ghost"
                          type="button"
                          @click="removeOperationRow(index)"
                        >
                          删除
                        </button>
                      </div>

                      <div class="triple-field">
                        <label class="form-field">
                          <span>序号 <i class="required-mark">*</i></span>
                          <input v-model.number="operation.seq_no" type="number" min="1" step="1" required />
                        </label>
                        <label class="form-field">
                          <span>工序模板 <i class="required-mark">*</i></span>
                          <select v-model.number="operation.process_id" required @change="applyProcess(index)">
                            <option disabled value="">请选择工序</option>
                            <option v-for="process in processes" :key="process.process_id" :value="process.process_id">
                              {{ process.process_code }} · {{ process.process_name }}
                            </option>
                          </select>
                        </label>
                        <label class="form-field">
                          <span>工作中心 <i class="required-mark">*</i></span>
                          <select v-model.number="operation.work_center_id" required>
                            <option disabled value="">请选择工作中心</option>
                            <option v-for="center in workCenters" :key="center.id" :value="center.id">
                              {{ center.center_name }}
                            </option>
                          </select>
                        </label>
                      </div>

                      <div class="double-field">
                        <label class="form-field">
                          <span>工序名称 <i class="required-mark">*</i></span>
                          <input v-model.trim="operation.operation_name" type="text" required />
                        </label>
                        <label class="form-field">
                          <span>状态</span>
                          <select v-model="operation.status">
                            <option v-for="option in statusOptions" :key="option.value" :value="option.value">
                              {{ option.label }}
                            </option>
                          </select>
                        </label>
                      </div>

                      <div class="triple-field">
                        <label class="form-field">
                          <span>准备时长(分钟)</span>
                          <input v-model.number="operation.std_setup_minutes" type="number" min="0" step="0.01" />
                        </label>
                        <label class="form-field">
                          <span>参考节拍(秒/件)</span>
                          <input v-model.number="operation.std_cycle_seconds" type="number" min="0" step="0.01" />
                        </label>
                        <label class="form-field">
                          <span>允许报废率</span>
                          <input v-model.number="operation.allowed_scrap_rate" type="number" min="0" step="0.0001" />
                        </label>
                      </div>

                      <div class="checkbox-grid">
                        <label class="checkbox-field">
                          <input v-model="operation.report_required" type="checkbox" />
                          <span>要求报工</span>
                        </label>
                        <label class="checkbox-field">
                          <input v-model="operation.is_key_operation" type="checkbox" />
                          <span>关键工序</span>
                        </label>
                      </div>

                      <label class="form-field">
                        <span>备注</span>
                        <input v-model.trim="operation.remark" type="text" />
                      </label>
                    </article>
                  </div>

                  <div class="form-toolbar">
                    <button class="primary-button" type="submit" :disabled="busy.route">
                      {{ busy.route ? "保存中..." : editingRouteId ? "更新工艺路线" : "保存工艺路线" }}
                    </button>
                  </div>
                </form>
              </template>
            </section>
          </template>
        </section>

        <aside class="workflow-drawer-side">
          <section class="workflow-summary-card">
            <p class="eyebrow">流程摘要</p>
            <h3>{{ currentProductLabel || "未完成产品建档" }}</h3>
            <div class="workflow-summary-list">
              <div>
                <span>产品状态</span>
                <strong>{{ currentProductId ? "已保存" : "待保存" }}</strong>
              </div>
              <div>
                <span>供应商</span>
                <strong>{{ selectedSupplierIds.length }} 家</strong>
              </div>
              <div>
                <span>原材料</span>
                <strong>{{ selectedMaterialIds.length }} 种</strong>
              </div>
              <div>
                <span>BOM版本</span>
                <strong>{{ productBoms.length }} 条</strong>
              </div>
              <div>
                <span>工艺路线</span>
                <strong>{{ productRoutes.length }} 条</strong>
              </div>
            </div>
          </section>

          <section class="workflow-summary-card">
            <p class="eyebrow">当前配置</p>
            <div class="workflow-chip-column">
              <span v-for="supplier in selectedSuppliers" :key="supplier.id" class="table-chip">
                {{ supplier.supplier_name }}
              </span>
              <span v-if="!selectedSuppliers.length" class="workflow-muted-note">尚未勾选供应商</span>
            </div>
            <hr class="workflow-divider" />
            <div class="workflow-chip-column">
              <span v-for="material in selectedMaterials" :key="material.item_id" class="table-chip">
                {{ material.item_code }} · {{ material.item_name }}
              </span>
              <span v-if="!selectedMaterials.length" class="workflow-muted-note">尚未勾选原材料</span>
            </div>
          </section>

          <section class="workflow-summary-card">
            <p class="eyebrow">导航操作</p>
            <div class="workflow-side-actions">
              <button class="ghost-button" type="button" :disabled="currentStepIndex === 0" @click="previousStep">上一步</button>
              <button
                class="primary-button"
                type="button"
                :disabled="currentStepIndex >= workflowSteps.length - 1"
                @click="nextStep"
              >
                下一步
              </button>
            </div>
            <button class="ghost-button workflow-close-button" type="button" :disabled="isBusy" @click="handleClose">
              完成并关闭
            </button>
          </section>
        </aside>
      </div>
        </div>
      </aside>
    </div>
  </Teleport>
</template>

<script setup>
import { computed, nextTick, reactive, ref, toRef, watch } from "vue";

import PaginationBar from "./PaginationBar.vue";
import { useBodyScrollLock } from "../composables/useBodyScrollLock";
import { deleteResource, fetchResource, postResource, putResource } from "../services/api";
import {
  buildBomCodePreview,
  buildNextProductSpecCode,
  buildMaterialCodePreview,
  buildNextMaterialCode,
  buildProductCodePreview,
  buildRouteCodePreview
} from "../utils/codeRules";
import { STATUS_LABELS, buildVersionedRows, formatStatusLabel } from "../utils/dictionaries";
import { usePagination } from "../utils/pagination";

const props = defineProps({
  open: {
    type: Boolean,
    default: false
  },
  mode: {
    type: String,
    default: "create"
  },
  product: {
    type: Object,
    default: null
  }
});

const emit = defineEmits(["close", "saved"]);

useBodyScrollLock(toRef(props, "open"));
const drawerScrollRef = ref(null);

const workflowSteps = [
  {
    key: "product",
    label: "产品资料",
    desc: "维护产品资料、版本、单重和质量标准。",
    requiresProduct: false
  },
  {
    key: "suppliers",
    label: "供应商管理",
    desc: "勾选供应来源，没有的供应商可直接新建。",
    requiresProduct: false
  },
  {
    key: "materials",
    label: "原材料管理",
    desc: "选择后续 BOM 会使用的原材料。",
    requiresProduct: false
  },
  {
    key: "bom",
    label: "BOM管理",
    desc: "按当前产品版本配置多版本用料。",
    requiresProduct: true
  },
  {
    key: "route",
    label: "工艺路线",
    desc: "按当前产品版本配置工序链。",
    requiresProduct: true
  }
];

const statusOptions = [
  { value: "ACTIVE", label: STATUS_LABELS.ACTIVE },
  { value: "INACTIVE", label: STATUS_LABELS.INACTIVE }
];
const busy = reactive({
  loading: false,
  product: false,
  supplier: false,
  material: false,
  bom: false,
  route: false
});

const workflowMode = ref("create");
const currentStepIndex = ref(0);
const currentProductId = ref(null);
const editingBomId = ref(null);
const editingRouteId = ref(null);
const feedbackMessage = ref("");
const errorMessage = ref("");
const showSupplierCreateForm = ref(false);
const showMaterialCreateForm = ref(false);
const savedProductSnapshot = ref(null);

const products = ref([]);
const suppliers = ref([]);
const materials = ref([]);
const boms = ref([]);
const routes = ref([]);
const processes = ref([]);
const workCenters = ref([]);

const selectedSupplierIds = ref([]);
const selectedMaterialIds = ref([]);
const bomVersionSelections = reactive({});
const routeVersionSelections = reactive({});

const productForm = reactive(buildEmptyProductForm());
const supplierForm = reactive(buildEmptySupplierForm());
const materialForm = reactive(buildEmptyMaterialForm());
const bomForm = reactive(buildEmptyBomForm());
const routeForm = reactive(buildEmptyRouteForm());

const activeStep = computed(() => workflowSteps[currentStepIndex.value]);
const isBusy = computed(
  () => busy.loading || busy.product || busy.supplier || busy.material || busy.bom || busy.route
);
const productCodePreview = computed(() =>
  buildProductCodePreview(productForm, productForm.item_code, buildNextProductSpecCode(products.value))
);
const materialCodePreview = computed(() =>
  buildMaterialCodePreview(materialForm, materialForm.item_code, buildNextMaterialCode(materials.value))
);
const bomCodePreview = computed(() => buildBomCodePreview(productForm.item_code || productCodePreview.value, bomForm.bom_code));
const routeCodePreview = computed(() =>
  buildRouteCodePreview(productForm.item_code || productCodePreview.value, routeForm.route_code)
);
const currentProductLabel = computed(() =>
  [productForm.item_code || productCodePreview.value, productForm.item_name, productForm.version_no].filter(Boolean).join(" · ")
);
const selectedSuppliers = computed(() =>
  suppliers.value.filter((item) => selectedSupplierIds.value.includes(item.id))
);
const selectedMaterials = computed(() =>
  materials.value.filter((item) => selectedMaterialIds.value.includes(item.item_id))
);
const filteredMaterials = computed(() => {
  const supplierIds = new Set(selectedSupplierIds.value.map((value) => Number(value)));
  if (!supplierIds.size) {
    return materials.value;
  }
  return materials.value.filter(
    (item) => supplierIds.has(Number(item.default_supplier_id || 0)) || selectedMaterialIds.value.includes(item.item_id)
  );
});
const productBoms = computed(() =>
  boms.value.filter((item) => item.product_item_id === Number(currentProductId.value || 0))
);
const productRoutes = computed(() =>
  routes.value.filter((item) => item.product_item_id === Number(currentProductId.value || 0))
);
const visibleBoms = computed(() =>
  buildVersionedRows(productBoms.value, { codeKey: "bom_code", idKey: "bom_id" }).map((group) => {
    const selectedId = Number(bomVersionSelections[group.code] || group.active_id);
    const activeRow = group.rows.find((row) => row.bom_id === selectedId) || group.rows[0];
    return {
      ...activeRow,
      version_options: group.rows.map((row) => ({
        bom_id: row.bom_id,
        version_no: row.version_no
      }))
    };
  })
);
const {
  page: bomPage,
  pageSize: bomPageSize,
  rows: paginatedBoms
} = usePagination(visibleBoms);
const visibleRoutes = computed(() =>
  buildVersionedRows(productRoutes.value, { codeKey: "route_code", idKey: "route_id" }).map((group) => {
    const selectedId = Number(routeVersionSelections[group.code] || group.active_id);
    const activeRow = group.rows.find((row) => row.route_id === selectedId) || group.rows[0];
    return {
      ...activeRow,
      version_options: group.rows.map((row) => ({
        route_id: row.route_id,
        version_no: row.version_no
      }))
    };
  })
);
const {
  page: routePage,
  pageSize: routePageSize,
  rows: paginatedRoutes
} = usePagination(visibleRoutes);
const bomMaterialOptions = computed(() => {
  const materialIds = new Set(selectedMaterialIds.value.map((value) => Number(value)).filter(Boolean));
  bomForm.items.forEach((item) => {
    if (item.material_item_id) {
      materialIds.add(Number(item.material_item_id));
    }
  });
  if (!materialIds.size) {
    return filteredMaterials.value.length ? filteredMaterials.value : materials.value;
  }
  return materials.value.filter((item) => materialIds.has(Number(item.item_id)));
});

watch(
  () => [props.open, props.mode, props.product?.item_id || null],
  async ([open]) => {
    if (open) {
      await initializeDrawer();
      await nextTick();
      drawerScrollRef.value?.scrollTo({ top: 0, left: 0 });
    }
  },
  { immediate: true }
);

watch(
  productBoms,
  () => {
    syncVersionSelections(productBoms.value, bomVersionSelections, "bom_code", "bom_id");
  },
  { deep: true }
);

watch(
  productRoutes,
  () => {
    syncVersionSelections(productRoutes.value, routeVersionSelections, "route_code", "route_id");
  },
  { deep: true }
);

watch(
  selectedMaterialIds,
  (ids) => {
    const supplierSet = new Set(selectedSupplierIds.value.map((value) => Number(value)));
    materials.value.forEach((item) => {
      if (ids.includes(item.item_id) && item.default_supplier_id) {
        supplierSet.add(Number(item.default_supplier_id));
      }
    });
    selectedSupplierIds.value = Array.from(supplierSet);
  },
  { deep: true }
);

function getToday() {
  return new Date().toISOString().slice(0, 10);
}

function buildEmptyProductForm() {
  return {
    item_code: "",
    item_name: "",
    specification: "",
    drawing_no: "",
    product_family: "",
    version_no: "V1.0",
    unit_weight_kg: "",
    allowed_scrap_rate: 0,
    standard_output_qty: 0,
    quality_standard: "",
    safety_stock_weight_kg: 0,
    status: "ACTIVE"
  };
}

function buildEmptySupplierForm() {
  return {
    supplier_name: "",
    short_name: "",
    contact_name: "",
    contact_phone: "",
    address: "",
    default_tax_rate: 0,
    status: "ACTIVE",
    remark: ""
  };
}

function buildEmptyMaterialForm() {
  return {
    item_code: "",
    item_name: "",
    specification: "",
    material_grade: "",
    unit_weight_kg: 0,
    safety_stock_weight_kg: 0,
    scrap_sale_price: 0,
    default_supplier_id: "",
    min_purchase_qty: 0,
    purchase_multiple_weight_kg: 0,
    lead_time_days: 0,
    quality_rule: "",
    status: "ACTIVE"
  };
}

function buildEmptyBomItem(seqNo = 10, materialItemId = "") {
  return {
    seq_no: seqNo,
    material_item_id: materialItemId,
    usage_type: "WEIGHT",
    qty_per_piece: 1,
    net_weight_per_piece_kg: Number(productForm.unit_weight_kg || 0),
    gross_weight_per_piece_kg: 0,
    loss_rate: 0,
    issue_over_tolerance_rate: 0,
    remark: ""
  };
}

function buildEmptyBomForm() {
  return {
    bom_code: "",
    version_no: "V1.0",
    is_default: true,
    status: "ACTIVE",
    effective_date: getToday(),
    remark: "",
    items: [buildEmptyBomItem()]
  };
}

function buildEmptyOperation(seqNo = 10) {
  return {
    seq_no: seqNo,
    process_id: "",
    work_center_id: "",
    operation_name: "",
    std_setup_minutes: 0,
    std_cycle_seconds: 0,
    allowed_scrap_rate: 0,
    report_required: true,
    is_key_operation: false,
    status: "ACTIVE",
    remark: ""
  };
}

function buildEmptyRouteForm() {
  return {
    route_code: "",
    route_name: "",
    version_no: "V1.0",
    is_default: true,
    status: "ACTIVE",
    remark: "",
    operations: [buildEmptyOperation()]
  };
}

function clearMessages() {
  feedbackMessage.value = "";
  errorMessage.value = "";
}

function fillProductForm(product) {
  Object.assign(productForm, {
    item_code: product?.item_code || "",
    item_name: product?.item_name || "",
    specification: product?.specification || "",
    drawing_no: product?.drawing_no || "",
    product_family: product?.product_family || "",
    version_no: product?.version_no || "V1.0",
    unit_weight_kg:
      product?.unit_weight_kg === "" || product?.unit_weight_kg === null || product?.unit_weight_kg === undefined
        ? ""
        : Number(product.unit_weight_kg),
    allowed_scrap_rate: Number(product?.allowed_scrap_rate || 0),
    standard_output_qty: Number(product?.standard_output_qty || 0),
    quality_standard: product?.quality_standard || "",
    safety_stock_weight_kg: Number(product?.safety_stock_weight_kg || 0),
    status: product?.status || "ACTIVE"
  });
}

function normalizeSnapshotText(value) {
  const text = String(value ?? "").trim();
  return text || null;
}

function normalizeSnapshotNumber(value) {
  return Number(value || 0);
}

function buildProductPayload() {
  return {
    item_code: productForm.item_code || null,
    item_name: productForm.item_name,
    specification: productForm.specification || null,
    drawing_no: productForm.drawing_no || null,
    product_family: productForm.product_family || null,
    version_no: productForm.version_no,
    unit_weight_kg: Number(productForm.unit_weight_kg || 0),
    allowed_scrap_rate: Number(productForm.allowed_scrap_rate || 0),
    standard_output_qty: Number(productForm.standard_output_qty || 0),
    quality_standard: productForm.quality_standard || null,
    safety_stock_weight_kg: Number(productForm.safety_stock_weight_kg || 0),
    status: productForm.status
  };
}

function buildProductSnapshot(payload) {
  return JSON.stringify({
    item_code: normalizeSnapshotText(payload.item_code),
    item_name: normalizeSnapshotText(payload.item_name),
    specification: normalizeSnapshotText(payload.specification),
    drawing_no: normalizeSnapshotText(payload.drawing_no),
    product_family: normalizeSnapshotText(payload.product_family),
    version_no: normalizeSnapshotText(payload.version_no),
    unit_weight_kg: normalizeSnapshotNumber(payload.unit_weight_kg),
    allowed_scrap_rate: normalizeSnapshotNumber(payload.allowed_scrap_rate),
    standard_output_qty: normalizeSnapshotNumber(payload.standard_output_qty),
    quality_standard: normalizeSnapshotText(payload.quality_standard),
    safety_stock_weight_kg: normalizeSnapshotNumber(payload.safety_stock_weight_kg),
    status: normalizeSnapshotText(payload.status)
  });
}

function captureProductSnapshot() {
  savedProductSnapshot.value = currentProductId.value ? buildProductSnapshot(buildProductPayload()) : null;
}

function hasProductFormChanges() {
  if (!currentProductId.value || !savedProductSnapshot.value) {
    return true;
  }
  return savedProductSnapshot.value !== buildProductSnapshot(buildProductPayload());
}

function advanceStep() {
  if (currentStepIndex.value < workflowSteps.length - 1) {
    currentStepIndex.value += 1;
  }
}

function resetSupplierForm() {
  Object.assign(supplierForm, buildEmptySupplierForm());
}

function resetMaterialForm() {
  Object.assign(materialForm, buildEmptyMaterialForm());
}

function createBomDraft() {
  return {
    bom_code: "",
    version_no: "V1.0",
    is_default: !productBoms.value.some((item) => item.is_default),
    status: "ACTIVE",
    effective_date: getToday(),
    remark: "",
    items: [buildEmptyBomItem()]
  };
}

function createRouteDraft() {
  return {
    route_code: "",
    route_name: productForm.item_name ? `${productForm.item_name}标准工艺路线` : "",
    version_no: "V1.0",
    is_default: !productRoutes.value.some((item) => item.is_default),
    status: "ACTIVE",
    remark: "",
    operations: [buildEmptyOperation()]
  };
}

function resetBomForm(seedItems = false) {
  editingBomId.value = null;
  Object.assign(bomForm, createBomDraft());
  if (seedItems) {
    seedBomItemsFromSelectedMaterials(false, true);
  }
}

function resetRouteForm() {
  editingRouteId.value = null;
  Object.assign(routeForm, createRouteDraft());
}

function fillBomForm(bom) {
  if (!bom) {
    resetBomForm(true);
    return;
  }
  editingBomId.value = bom.bom_id;
  bomVersionSelections[bom.bom_code] = bom.bom_id;
  Object.assign(bomForm, {
    bom_code: bom.bom_code,
    version_no: bom.version_no,
    is_default: Boolean(bom.is_default),
    status: bom.status,
    effective_date: bom.effective_date || getToday(),
    remark: bom.remark || "",
    items: (bom.items || []).map((item) => ({
      seq_no: Number(item.seq_no || 0),
      material_item_id: item.material_item_id,
	      usage_type: "WEIGHT",
	      qty_per_piece: 1,
      net_weight_per_piece_kg: Number(item.net_weight_per_piece_kg || 0),
      gross_weight_per_piece_kg: Number(item.gross_weight_per_piece_kg || 0),
      loss_rate: Number(item.loss_rate || 0),
      issue_over_tolerance_rate: Number(item.issue_over_tolerance_rate || 0),
      remark: item.remark || ""
    }))
  });
}

function fillRouteForm(route) {
  if (!route) {
    resetRouteForm();
    return;
  }
  editingRouteId.value = route.route_id;
  routeVersionSelections[route.route_code] = route.route_id;
  Object.assign(routeForm, {
    route_code: route.route_code,
    route_name: route.route_name,
    version_no: route.version_no,
    is_default: Boolean(route.is_default),
    status: route.status,
    remark: route.remark || "",
    operations: (route.operations || []).map((item) => ({
      seq_no: Number(item.seq_no || 0),
      process_id: item.process_id,
      work_center_id: item.work_center_id,
      operation_name: item.operation_name,
      std_setup_minutes: Number(item.std_setup_minutes || 0),
      std_cycle_seconds: Number(item.std_cycle_seconds || 0),
      allowed_scrap_rate: Number(item.allowed_scrap_rate || 0),
      report_required: Boolean(item.report_required),
      is_key_operation: Boolean(item.is_key_operation),
      status: item.status,
      remark: item.remark || ""
    }))
  });
}

function syncVersionSelections(rows, target, codeKey, idKey) {
  const groups = buildVersionedRows(rows, { codeKey, idKey });
  const validCodes = new Set(groups.map((group) => group.code));
  Object.keys(target).forEach((code) => {
    if (!validCodes.has(code)) {
      delete target[code];
    }
  });
  groups.forEach((group) => {
    const currentSelection = Number(target[group.code] || 0);
    if (!group.rows.some((row) => Number(row[idKey]) === currentSelection)) {
      target[group.code] = group.active_id;
    }
  });
}

async function loadReferenceData() {
  const [productRows, supplierRows, materialRows, bomRows, routeRows, processRows, centerRows] = await Promise.all([
    fetchResource("/master-data/products?limit=200", []),
    fetchResource("/purchase/suppliers", []),
    fetchResource("/master-data/materials", []),
    fetchResource("/master-data/boms", []),
    fetchResource("/master-data/process-routes", []),
    fetchResource("/master-data/processes", []),
    fetchResource("/master-data/work-centers", [])
  ]);

  products.value = productRows;
  suppliers.value = supplierRows;
  materials.value = materialRows;
  boms.value = bomRows;
  routes.value = routeRows;
  processes.value = processRows;
  workCenters.value = centerRows;
}

function deriveSelectionsFromExisting(force = false) {
  if (!force && (selectedSupplierIds.value.length || selectedMaterialIds.value.length)) {
    return;
  }

  const materialIds = Array.from(
    new Set(
      productBoms.value.flatMap((bom) => (bom.items || []).map((item) => Number(item.material_item_id || 0))).filter(Boolean)
    )
  );
  const supplierIds = Array.from(
    new Set(
      materials.value
        .filter((material) => materialIds.includes(Number(material.item_id)))
        .map((material) => Number(material.default_supplier_id || 0))
        .filter(Boolean)
    )
  );

  selectedMaterialIds.value = materialIds;
  selectedSupplierIds.value = supplierIds;
}

function initializeNestedForms(preferExisting = false) {
  syncVersionSelections(productBoms.value, bomVersionSelections, "bom_code", "bom_id");
  syncVersionSelections(productRoutes.value, routeVersionSelections, "route_code", "route_id");

  if (preferExisting && visibleBoms.value.length) {
    fillBomForm(visibleBoms.value[0]);
  } else {
    resetBomForm(true);
  }

  if (preferExisting && visibleRoutes.value.length) {
    fillRouteForm(visibleRoutes.value[0]);
  } else {
    resetRouteForm();
  }
}

async function initializeDrawer() {
  clearMessages();
  busy.loading = true;
  workflowMode.value = props.mode || "create";
  currentStepIndex.value = 0;
  showSupplierCreateForm.value = false;
  showMaterialCreateForm.value = false;
  editingBomId.value = null;
  editingRouteId.value = null;
  selectedSupplierIds.value = [];
  selectedMaterialIds.value = [];
  resetSupplierForm();
  resetMaterialForm();

  if (workflowMode.value === "edit" && props.product) {
    currentProductId.value = props.product.item_id;
    fillProductForm(props.product);
  } else {
    currentProductId.value = null;
    fillProductForm(buildEmptyProductForm());
  }
  captureProductSnapshot();

  await loadReferenceData();

  if (currentProductId.value) {
    deriveSelectionsFromExisting(true);
    initializeNestedForms(true);
  } else {
    resetBomForm(false);
    resetRouteForm();
  }

  busy.loading = false;
}

function handleClose() {
  if (isBusy.value) {
    return;
  }
  emit("close");
}

function goToStep(index) {
  const targetStep = workflowSteps[index];
  if (!targetStep) {
    return;
  }
  if (targetStep.requiresProduct && !currentProductId.value) {
    errorMessage.value = "请先保存产品资料，再继续维护 BOM 和工艺路线。";
    return;
  }
  currentStepIndex.value = index;
}

function previousStep() {
  if (currentStepIndex.value > 0) {
    currentStepIndex.value -= 1;
  }
}

async function nextStep() {
  clearMessages();
  if (currentStepIndex.value === 0) {
    if (currentProductId.value && !hasProductFormChanges()) {
      advanceStep();
      return;
    }
    await saveProduct(true);
    return;
  }

  advanceStep();
}

async function saveProduct(moveNext = false) {
  clearMessages();
  if (currentProductId.value && !hasProductFormChanges()) {
    if (moveNext) {
      advanceStep();
    } else {
      feedbackMessage.value = "产品资料无变更";
    }
    return;
  }

  busy.product = true;

  const payload = buildProductPayload();

  try {
    const previousProductId = Number(currentProductId.value || 0);
    const result =
      workflowMode.value === "edit" && currentProductId.value
        ? await putResource(`/master-data/products/${currentProductId.value}`, payload)
        : await postResource("/master-data/products", payload);

    workflowMode.value = "edit";
    currentProductId.value = result.item_id;
    fillProductForm(result);
    captureProductSnapshot();

    await loadReferenceData();

    const productChanged = previousProductId !== Number(result.item_id);
    if (productChanged) {
      initializeNestedForms(true);
    } else {
      syncVersionSelections(productBoms.value, bomVersionSelections, "bom_code", "bom_id");
      syncVersionSelections(productRoutes.value, routeVersionSelections, "route_code", "route_id");
    }

    if (!selectedSupplierIds.value.length && !selectedMaterialIds.value.length) {
      deriveSelectionsFromExisting(true);
    }

    const message = `产品 ${result.item_name} ${result.version_no} 已保存`;
    feedbackMessage.value = message;
    emit("saved", { product: result, message });

    if (moveNext && currentStepIndex.value < workflowSteps.length - 1) {
      advanceStep();
    }
  } catch (error) {
    errorMessage.value = error.message || "保存产品失败";
  } finally {
    busy.product = false;
  }
}

async function createSupplier() {
  clearMessages();
  busy.supplier = true;

  try {
    const result = await postResource("/purchase/suppliers", {
      supplier_name: supplierForm.supplier_name,
      short_name: supplierForm.short_name || null,
      contact_name: supplierForm.contact_name || null,
      contact_phone: supplierForm.contact_phone || null,
      address: supplierForm.address || null,
      default_tax_rate: Number(supplierForm.default_tax_rate || 0),
      status: supplierForm.status,
      remark: supplierForm.remark || null
    });

    await loadReferenceData();
    selectedSupplierIds.value = Array.from(new Set([...selectedSupplierIds.value, result.id]));
    resetSupplierForm();
    showSupplierCreateForm.value = false;
    feedbackMessage.value = `供应商 ${result.supplier_name} 已保存`;
  } catch (error) {
    errorMessage.value = error.message || "保存供应商失败";
  } finally {
    busy.supplier = false;
  }
}

async function createMaterial() {
  clearMessages();
  busy.material = true;

  try {
    const payload = {
      item_code: materialForm.item_code || null,
      item_name: materialForm.item_name,
      specification: materialForm.specification,
      material_grade: materialForm.material_grade,
      unit_weight_kg: Number(materialForm.unit_weight_kg || 0),
      safety_stock_weight_kg: Number(materialForm.safety_stock_weight_kg || 0),
      scrap_sale_price: Number(materialForm.scrap_sale_price || 0),
      default_supplier_id: Number(materialForm.default_supplier_id || 0),
      purchase_calc_mode: "BY_WEIGHT",
      min_purchase_qty: Number(materialForm.min_purchase_qty || 0),
      purchase_multiple_qty: 0,
      purchase_multiple_weight_kg: Number(materialForm.purchase_multiple_weight_kg || 0),
      lead_time_days: Number(materialForm.lead_time_days || 0),
      quality_rule: materialForm.quality_rule || null,
      status: materialForm.status
    };

    const result = await postResource("/master-data/materials", payload);

    await loadReferenceData();
    selectedMaterialIds.value = Array.from(new Set([...selectedMaterialIds.value, result.item_id]));
    if (result.default_supplier_id) {
      selectedSupplierIds.value = Array.from(new Set([...selectedSupplierIds.value, result.default_supplier_id]));
    }
    if (!editingBomId.value && isBomDraftBlank()) {
      seedBomItemsFromSelectedMaterials(false, true);
    }
    resetMaterialForm();
    showMaterialCreateForm.value = false;
    feedbackMessage.value = `原材料 ${result.item_name} 已保存`;
  } catch (error) {
    errorMessage.value = error.message || "保存原材料失败";
  } finally {
    busy.material = false;
  }
}

	function isBomDraftBlank() {
	  return bomForm.items.every(
	    (item) =>
	      !item.material_item_id &&
	      Number(item.gross_weight_per_piece_kg || 0) === 0 &&
	      Number(item.net_weight_per_piece_kg || 0) === 0 &&
	      !item.remark
	  );
	}

function seedBomItemsFromSelectedMaterials(confirmReplace = true, silent = false) {
  if (!selectedMaterialIds.value.length) {
    if (!silent) {
      errorMessage.value = "请先在步骤三勾选原材料，再带入 BOM 明细。";
    }
    return;
  }

  if (confirmReplace && !isBomDraftBlank() && !window.confirm("当前 BOM 明细会被已勾选原材料重新带入，确认继续吗？")) {
    return;
  }

  bomForm.items = selectedMaterialIds.value.map((materialId, index) => buildEmptyBomItem((index + 1) * 10, materialId));
}

function addBomItem() {
  const nextSeq = bomForm.items.length ? Math.max(...bomForm.items.map((item) => Number(item.seq_no || 0))) + 10 : 10;
  bomForm.items.push(buildEmptyBomItem(nextSeq));
}

function removeBomItem(index) {
  bomForm.items.splice(index, 1);
}

function applyBomVersion(bomCode) {
  const selectedBom = productBoms.value.find((item) => item.bom_id === Number(bomVersionSelections[bomCode] || 0));
  if (selectedBom) {
    fillBomForm(selectedBom);
  }
}

function startEditBom(bom) {
  fillBomForm(productBoms.value.find((item) => item.bom_id === bom.bom_id) || bom);
}

async function saveBom() {
  clearMessages();
  if (!currentProductId.value) {
    errorMessage.value = "请先保存产品资料。";
    return;
  }

  busy.bom = true;

  try {
    const payload = {
      bom_code: bomForm.bom_code || null,
      product_item_id: Number(currentProductId.value),
      version_no: bomForm.version_no,
      is_default: Boolean(bomForm.is_default),
      status: bomForm.status,
      effective_date: bomForm.effective_date || null,
      expire_date: null,
      remark: bomForm.remark || null,
      items: bomForm.items.map((item) => ({
        seq_no: Number(item.seq_no || 0),
        material_item_id: Number(item.material_item_id || 0),
	        usage_type: "WEIGHT",
	        qty_per_piece: 1,
	        net_weight_per_piece_kg: Number(item.net_weight_per_piece_kg || 0),
	        gross_weight_per_piece_kg: Number(item.gross_weight_per_piece_kg || 0),
        loss_rate: Number(item.loss_rate || 0),
        issue_over_tolerance_rate: Number(item.issue_over_tolerance_rate || 0),
        remark: item.remark || null
      }))
    };

    const result = editingBomId.value
      ? await putResource(`/master-data/boms/${editingBomId.value}`, payload)
      : await postResource("/master-data/boms", payload);

    await loadReferenceData();
    syncVersionSelections(productBoms.value, bomVersionSelections, "bom_code", "bom_id");
    fillBomForm(productBoms.value.find((item) => item.bom_id === result.bom_id) || result);
    deriveSelectionsFromExisting(true);
    feedbackMessage.value = `BOM ${result.bom_code} ${result.version_no} 已保存`;
  } catch (error) {
    errorMessage.value = error.message || "保存 BOM 失败";
  } finally {
    busy.bom = false;
  }
}

async function removeBom(bom) {
  clearMessages();
  if (!window.confirm(`确认删除 BOM“${bom.bom_code} ${bom.version_no}”吗？`)) {
    return;
  }

  try {
    const result = await deleteResource(`/master-data/boms/${bom.bom_id}`);
    await loadReferenceData();
    deriveSelectionsFromExisting(true);
    initializeNestedForms(visibleBoms.value.length > 0 || visibleRoutes.value.length > 0);
    feedbackMessage.value = result.message || `BOM ${bom.bom_code} 已删除`;
  } catch (error) {
    errorMessage.value = error.message || "删除 BOM 失败";
  }
}

function addOperationRow() {
  const nextSeq = routeForm.operations.length
    ? Math.max(...routeForm.operations.map((item) => Number(item.seq_no || 0))) + 10
    : 10;
  routeForm.operations.push(buildEmptyOperation(nextSeq));
}

function removeOperationRow(index) {
  routeForm.operations.splice(index, 1);
}

function applyProcess(index) {
  const process = processes.value.find((item) => item.process_id === Number(routeForm.operations[index].process_id));
  if (!process) {
    return;
  }
  if (!routeForm.operations[index].operation_name) {
    routeForm.operations[index].operation_name = process.process_name;
  }
  routeForm.operations[index].report_required = Boolean(process.is_report_required);
}

function applyRouteVersion(routeCode) {
  const selectedRoute = productRoutes.value.find((item) => item.route_id === Number(routeVersionSelections[routeCode] || 0));
  if (selectedRoute) {
    fillRouteForm(selectedRoute);
  }
}

function startEditRoute(route) {
  fillRouteForm(productRoutes.value.find((item) => item.route_id === route.route_id) || route);
}

async function saveRoute() {
  clearMessages();
  if (!currentProductId.value) {
    errorMessage.value = "请先保存产品资料。";
    return;
  }

  busy.route = true;

  try {
    const payload = {
      route_code: routeForm.route_code || null,
      route_name: routeForm.route_name,
      product_item_id: Number(currentProductId.value),
      version_no: routeForm.version_no,
      is_default: Boolean(routeForm.is_default),
      status: routeForm.status,
      effective_date: null,
      expire_date: null,
      remark: routeForm.remark || null,
      operations: routeForm.operations.map((item) => ({
        seq_no: Number(item.seq_no || 0),
        process_id: Number(item.process_id || 0),
        work_center_id: Number(item.work_center_id || 0),
        operation_name: item.operation_name,
        std_setup_minutes: Number(item.std_setup_minutes || 0),
        std_cycle_seconds: Number(item.std_cycle_seconds || 0),
        std_labor_cost: 0,
        std_machine_cost: 0,
        std_outsource_cost: 0,
        allowed_scrap_rate: Number(item.allowed_scrap_rate || 0),
        report_required: Boolean(item.report_required),
        is_key_operation: Boolean(item.is_key_operation),
        status: item.status,
        remark: item.remark || null
      }))
    };

    const result = editingRouteId.value
      ? await putResource(`/master-data/process-routes/${editingRouteId.value}`, payload)
      : await postResource("/master-data/process-routes", payload);

    await loadReferenceData();
    syncVersionSelections(productRoutes.value, routeVersionSelections, "route_code", "route_id");
    fillRouteForm(productRoutes.value.find((item) => item.route_id === result.route_id) || result);
    feedbackMessage.value = `工艺路线 ${result.route_code} ${result.version_no} 已保存`;
  } catch (error) {
    errorMessage.value = error.message || "保存工艺路线失败";
  } finally {
    busy.route = false;
  }
}

async function removeRoute(route) {
  clearMessages();
  if (!window.confirm(`确认删除工艺路线“${route.route_code} ${route.version_no}”吗？`)) {
    return;
  }

  try {
    const result = await deleteResource(`/master-data/process-routes/${route.route_id}`);
    await loadReferenceData();
    initializeNestedForms(visibleBoms.value.length > 0 || visibleRoutes.value.length > 0);
    feedbackMessage.value = result.message || `工艺路线 ${route.route_code} 已删除`;
  } catch (error) {
    errorMessage.value = error.message || "删除工艺路线失败";
  }
}
</script>
