<template>
  <div class="bom-form-page">
    <!-- 表头卡片 -->
    <el-card class="header-card" shadow="never">
      <div class="header-bar">
        <h3 class="title">EBOM清单</h3>
        <div class="actions">
          <el-button type="primary" @click="handleSave" :disabled="isReadonly" :loading="saveLoading">保存</el-button>
          <el-button @click="handleCancel">取消</el-button>
          <el-button
            type="success"
            @click="handleApprove"
            :disabled="isReadonly || form.status === 'APPROVED'"
          >审核</el-button>
          <el-button
            type="warning"
            @click="handleUnApprove"
            :disabled="form.status !== 'APPROVED'"
          >反审核</el-button>
          <el-button type="primary" link @click="collapsed = !collapsed">
            {{ collapsed ? '展开' : '收起' }}
          </el-button>
        </div>
      </div>

      <!-- 表头表单 -->
      <el-form
        v-show="!collapsed"
        ref="formRef"
        :model="form"
        :rules="formRules"
        label-width="80px"
        class="grid-form"
      >
        <!-- 第1行 -->
        <el-row :gutter="24">
          <el-col :span="6">
            <el-form-item label="单据编码" prop="bomCode">
              <el-input v-model="form.bomCode" disabled placeholder="自动生成" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="业务类型" prop="businessType">
              <el-select v-model="form.businessType" :disabled="isReadonly" style="width: 100%">
                <el-option v-for="opt in BIZ_TYPE_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="物料编码" prop="itemCode">
              <div class="inline-select">
                <el-input v-model="form.itemCode" disabled />
                <el-button link type="primary" :disabled="isReadonly" @click="openProductDialog">选择</el-button>
              </div>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="图纸号">
              <el-input v-model="form.drawingNo" :disabled="isReadonly" />
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 第2行 -->
        <el-row :gutter="24">
          <el-col :span="6">
            <el-form-item label="单据日期" prop="bomDate">
              <el-date-picker
                v-model="form.bomDate"
                type="date"
                value-format="YYYY-MM-DD"
                :disabled="isReadonly"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="操作员">
              <el-input v-model="form.operatorName" disabled />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="物料名称">
              <el-input v-model="form.itemName" disabled />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="版本号" prop="version">
              <el-input-number
                v-model="versionNumber"
                :min="1"
                :step="0.1"
                :precision="1"
                :disabled="isReadonly"
                controls-position="right"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 第3行 -->
        <el-row :gutter="24">
          <el-col :span="6">
            <el-form-item label="单据状态">
              <el-tag :type="form.status === 'APPROVED' ? 'success' : form.status === 'REJECTED' ? 'warning' : 'info'">
                {{ STATUS_MAP[form.status]?.label || '开立' }}
              </el-tag>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="审核员">
              <el-input v-model="form.approverName" disabled />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="计量单位">
              <el-input v-model="form.unitName" disabled />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="版本说明">
              <el-input v-model="form.versionDesc" :disabled="isReadonly" />
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 第4行 -->
        <el-row :gutter="24">
          <el-col :span="6">
            <el-form-item label="业务状态">
              <el-select v-model="form.businessStatus" :disabled="isReadonly" style="width: 100%">
                <el-option v-for="opt in BIZ_STATUS_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="审核日期">
              <el-date-picker v-model="form.approveDate" type="date" value-format="YYYY-MM-DD" disabled style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="母件基数" prop="baseQty">
              <el-input-number v-model="form.baseQty" :min="1" :step="1" :disabled="isReadonly" style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="备注信息">
              <el-input v-model="form.remark" type="textarea" :rows="1" :disabled="isReadonly" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </el-card>

    <!-- 物料明细卡片 -->
    <el-card class="lines-card" shadow="never">
      <div class="lines-header">
        <span class="lines-title">物料信息</span>
        <div class="lines-actions">
          <el-button type="primary" plain :icon="Plus" :disabled="isReadonly" @click="addEmptyLine">新增物料</el-button>
        </div>
      </div>

      <el-table :data="lines" border size="small" max-height="420">
        <el-table-column label="序号" type="index" width="60" align="center" />
        <el-table-column label="物料编码" min-width="160">
          <template #default="{ row, $index }">
            <div class="inline-select">
              <span class="mono">{{ row.bomItemCode || '请添加物料' }}</span>
              <el-button link type="primary" :disabled="isReadonly" @click="openItemDialog($index)">选择</el-button>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="bomItemName" label="物料名称" min-width="160" show-overflow-tooltip />
        <el-table-column prop="bomItemSpec" label="型号规格" min-width="130" show-overflow-tooltip />
        <el-table-column prop="unitName" label="主计量" width="80" align="center" />
        <el-table-column label="计划线路" width="110" align="center">
          <template #default="{ row }">
            <el-select v-model="row.supplyType" :disabled="isReadonly" size="small" style="width: 100%">
              <el-option v-for="opt in SUPPLY_TYPE_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="领料方式" width="110" align="center">
          <template #default="{ row }">
            <el-select v-model="row.pickType" :disabled="isReadonly" size="small" style="width: 100%">
              <el-option v-for="opt in PICK_TYPE_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="分子" width="100" align="right">
          <template #default="{ row }">
            <el-input-number
              v-model="row.quantity"
              :min="0"
              :precision="4"
              :disabled="isReadonly"
              size="small"
              controls-position="right"
              style="width: 100%"
            />
          </template>
        </el-table-column>
        <el-table-column label="用量方式" width="110" align="center">
          <template #default="{ row }">
            <el-select v-model="row.usageType" :disabled="isReadonly" size="small" style="width: 100%">
              <el-option v-for="opt in USAGE_TYPE_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="图纸号" width="110">
          <template #default="{ row }">
            <el-input v-model="row.drawingNo" :disabled="isReadonly" size="small" />
          </template>
        </el-table-column>
        <el-table-column label="备注" min-width="110">
          <template #default="{ row }">
            <el-input v-model="row.remark" :disabled="isReadonly" size="small" />
          </template>
        </el-table-column>
        <el-table-column label="操作" width="70" align="center" fixed="right">
          <template #default="{ $index }">
            <el-button link type="danger" :disabled="isReadonly" @click="removeLine($index)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- ==================== 选择产品(母件)弹窗 ==================== -->
    <el-dialog v-model="productDialogVisible" title="选择物料" width="900px" destroy-on-close>
      <div class="item-select-layout">
        <!-- 左侧分类树 -->
        <div class="item-select-tree">
          <el-input v-model="treeFilterText" placeholder="请输入分类名称" clearable style="margin-bottom: 8px" />
          <el-tree
            ref="treeRef"
            :data="itemTypeTreeData"
            :props="{ label: 'label', children: 'children' }"
            :filter-node-method="filterNode"
            highlight-current
            default-expand-all
            @node-click="handleTreeNodeClick"
          />
        </div>
        <!-- 右侧列表 -->
        <div class="item-select-table">
          <el-form :inline="true" @submit.prevent="searchProductItems" style="margin-bottom: 8px">
            <el-form-item label="物料编码">
              <el-input v-model="productQuery.itemCode" placeholder="请输入" clearable style="width: 120px" />
            </el-form-item>
            <el-form-item label="物料名称">
              <el-input v-model="productQuery.itemName" placeholder="请输入" clearable style="width: 120px" />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="searchProductItems">搜索</el-button>
              <el-button @click="resetProductSearch">重置</el-button>
            </el-form-item>
            <el-form-item>
              <el-button @click="queryAllProducts">查询所有</el-button>
            </el-form-item>
          </el-form>
          <el-table :data="productList" border size="small" max-height="380" v-loading="productLoading">
            <el-table-column prop="itemCode" label="物料编码" width="130" />
            <el-table-column prop="itemName" label="物料名称" min-width="160" show-overflow-tooltip />
            <el-table-column prop="specification" label="型号规格" width="130" show-overflow-tooltip />
            <el-table-column prop="unitName" label="主计量" width="70" align="center" />
            <el-table-column label="供应方式" width="80" align="center">
              <template #default="{ row }">
                {{ getSupplyLabel(row.itemOrProduct) }}
              </template>
            </el-table-column>
            <el-table-column label="操作" width="70" align="center">
              <template #default="{ row }">
                <el-button type="primary" link @click="confirmProduct(row)">选择</el-button>
              </template>
            </el-table-column>
          </el-table>
          <div class="pagination-wrapper" style="margin-top: 8px">
            <el-pagination
              v-model:current-page="productQuery.pageNum"
              v-model:page-size="productQuery.pageSize"
              :page-sizes="[50, 100]"
              :total="productTotal"
              layout="total, sizes, prev, pager, next"
              small
              @size-change="searchProductItems"
              @current-change="searchProductItems"
            />
          </div>
        </div>
      </div>
    </el-dialog>

    <!-- ==================== 选择子件物料弹窗 ==================== -->
    <el-dialog v-model="itemDialogVisible" title="选择物料" width="900px" destroy-on-close>
      <div class="item-select-layout">
        <div class="item-select-tree">
          <el-input v-model="itemTreeFilterText" placeholder="请输入分类名称" clearable style="margin-bottom: 8px" />
          <el-tree
            ref="itemTreeRef"
            :data="itemTypeTreeData"
            :props="{ label: 'label', children: 'children' }"
            :filter-node-method="filterNode"
            highlight-current
            default-expand-all
            @node-click="handleItemTreeClick"
          />
        </div>
        <div class="item-select-table">
          <el-form :inline="true" @submit.prevent="searchSubItems" style="margin-bottom: 8px">
            <el-form-item label="物料编码">
              <el-input v-model="itemQuery.itemCode" placeholder="请输入" clearable style="width: 120px" />
            </el-form-item>
            <el-form-item label="物料名称">
              <el-input v-model="itemQuery.itemName" placeholder="请输入" clearable style="width: 120px" />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="searchSubItems">搜索</el-button>
              <el-button @click="resetItemSearch">重置</el-button>
            </el-form-item>
            <el-form-item>
              <el-button @click="queryAllItems">查询所有</el-button>
            </el-form-item>
          </el-form>
          <el-table :data="itemList" border size="small" max-height="380" v-loading="itemLoading">
            <el-table-column prop="itemCode" label="物料编码" width="130" />
            <el-table-column prop="itemName" label="物料名称" min-width="160" show-overflow-tooltip />
            <el-table-column prop="specification" label="型号规格" width="130" show-overflow-tooltip />
            <el-table-column prop="unitName" label="主计量" width="70" align="center" />
            <el-table-column label="供应方式" width="80" align="center">
              <template #default="{ row }">
                {{ getSupplyLabel(row.itemOrProduct) }}
              </template>
            </el-table-column>
            <el-table-column label="操作" width="70" align="center">
              <template #default="{ row }">
                <el-button type="primary" link @click="confirmItem(row)">选择</el-button>
              </template>
            </el-table-column>
          </el-table>
          <div class="pagination-wrapper" style="margin-top: 8px">
            <el-pagination
              v-model:current-page="itemQuery.pageNum"
              v-model:page-size="itemQuery.pageSize"
              :page-sizes="[50, 100]"
              :total="itemTotal"
              layout="total, sizes, prev, pager, next"
              small
              @size-change="searchSubItems"
              @current-change="searchSubItems"
            />
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, ElMessageBox, type FormRules } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import {
  getEbom,
  addEbom,
  updateEbom,
  approveEbom,
  unapproveEbom,
  listEbomLines,
  addEbomLine,
  updateEbomLine,
  STATUS_MAP,
  BIZ_TYPE_OPTIONS,
  BIZ_STATUS_OPTIONS,
  PICK_TYPE_OPTIONS,
  USAGE_TYPE_OPTIONS,
  SUPPLY_TYPE_OPTIONS,
  type EbomHeader,
  type EbomLine
} from '@/api/rd/ebom'
import { listMdItem, type MdItem } from '@/api/masterdata/item'
import { listItemType, handleTree, type ItemType } from '@/api/masterdata/itemtype'

const route = useRoute()
const router = useRouter()

// ============ 页面模式 ============

const bomId = computed(() => {
  const raw = route.params.id
  if (!raw) return undefined
  const n = Number(raw)
  return Number.isFinite(n) ? n : undefined
})

const mode = computed<'new' | 'edit' | 'view'>(() => {
  if (route.name === 'EbomNew') return 'new'
  if (route.name === 'EbomEdit') return 'edit'
  return 'view'
})

const isReadonly = computed(() => mode.value === 'view' || form.status === 'APPROVED')

// ============ 表单数据 ============

const collapsed = ref(false)
const saveLoading = ref(false)
const formRef = ref()

const form = reactive<any>({
  bomId: undefined,
  bomCode: '',
  bomName: '',
  bomDate: new Date().toISOString().slice(0, 10),
  version: '1.0',
  versionDesc: '',
  status: 'DRAFT',
  businessType: 'MECHANICAL',
  businessStatus: 'NORMAL',
  drawingNo: '',
  itemId: undefined,
  itemCode: '',
  itemName: '',
  itemSpec: '',
  unitName: '',
  baseQty: 1,
  operatorName: 'admin',
  approverName: '',
  approveDate: '',
  remark: ''
})

const formRules: FormRules = {
  bomDate: [{ required: true, message: '请选择单据日期', trigger: 'blur' }],
  businessType: [{ required: true, message: '请选择业务类型', trigger: 'change' }],
  itemCode: [{ required: true, message: '请选择产品物料', trigger: 'blur' }],
  baseQty: [{ required: true, message: '请输入母件基数', trigger: 'blur' }]
}

const versionNumber = computed({
  get() {
    const n = parseFloat(form.version || '1.0')
    return Number.isFinite(n) ? n : 1.0
  },
  set(v: number) {
    form.version = v.toFixed(1)
  }
})

const lines = ref<any[]>([])

// ============ 物料明细操作 ============

function addEmptyLine() {
  lines.value.push({
    lineId: undefined,
    bomItemId: undefined,
    bomItemCode: '',
    bomItemName: '',
    bomItemSpec: '',
    unitOfMeasure: '',
    unitName: '',
    itemOrProduct: 'ITEM',
    quantity: 1,
    supplyType: 'PURCHASE',
    pickType: 'ORDER',
    usageType: 'RATIO',
    drawingNo: '',
    remark: '',
    _isNew: true
  })
}

function removeLine(idx: number) {
  lines.value.splice(idx, 1)
}

// ============ 数据加载 ============

async function loadData() {
  if (!bomId.value) {
    lines.value = []
    addEmptyLine()
    addEmptyLine()
    return
  }
  try {
    const header = (await getEbom(bomId.value)).data
    Object.assign(form, {
      ...header,
      bomDate: header.bomDate || header.createTime?.slice(0, 10) || '',
      operatorName: header.operatorName || header.createBy || 'admin',
      businessType: header.businessType || 'MECHANICAL',
      businessStatus: header.businessStatus || 'NORMAL'
    })

    const linesRes = await listEbomLines({ bomCode: header.bomCode, pageNum: 1, pageSize: 500 })
    lines.value = (linesRes.rows || []).map(row => ({
      ...row,
      pickType: row.pickType || row.attr1 || 'ORDER',
      usageType: row.usageType || row.attr2 || 'RATIO',
      drawingNo: row.drawingNo || ''
    }))
    if (lines.value.length === 0) addEmptyLine()
  } catch (e) {
    console.error(e)
    ElMessage.error('加载BOM数据失败')
  }
}

// ============ 保存 ============

/** 校验子件无重复物料（同一BOM下子物料编码/ID不能重复） */
function validateNoDuplicateSubItems(): boolean {
  const withItem = lines.value.filter((row) => row.bomItemId != null || (row.bomItemCode && String(row.bomItemCode).trim()))
  const byCode = new Map<string, number>()
  const byId = new Map<number, number>()
  for (let i = 0; i < withItem.length; i++) {
    const row = withItem[i]
    const code = (row.bomItemCode && String(row.bomItemCode).trim()) || ''
    const id = row.bomItemId
    if (code && byCode.has(code)) {
      ElMessage.warning(`存在重复的子物料编码：${code}，请删除重复行后再保存`)
      return false
    }
    if (id != null && byId.has(id)) {
      ElMessage.warning(`存在重复的子物料：${row.bomItemCode || id}，请删除重复行后再保存`)
      return false
    }
    if (code) byCode.set(code, i)
    if (id != null) byId.set(id, i)
  }
  return true
}

async function handleSave() {
  if (!form.itemId) {
    ElMessage.warning('请先选择产品物料')
    return
  }
  if (!validateNoDuplicateSubItems()) {
    return
  }
  saveLoading.value = true
  try {
    const headerPayload: Partial<EbomHeader> = {
      bomId: form.bomId,
      bomCode: form.bomCode,
      bomName: form.bomName || `${form.itemName} BOM`,
      bomDate: form.bomDate,
      version: form.version,
      versionDesc: form.versionDesc,
      status: form.status,
      businessType: form.businessType,
      businessStatus: form.businessStatus,
      drawingNo: form.drawingNo,
      itemId: form.itemId,
      itemCode: form.itemCode,
      itemName: form.itemName,
      itemSpec: form.itemSpec,
      unitName: form.unitName,
      baseQty: form.baseQty,
      remark: form.remark
    }

    const saved = headerPayload.bomId
      ? (await updateEbom(headerPayload)).data
      : (await addEbom(headerPayload)).data
    Object.assign(form, saved)

    // 保存明细行
    for (const row of lines.value) {
      if (!row.bomItemId) continue
      const linePayload: Partial<EbomLine> = {
        lineId: row.lineId || row.bomId, // 兼容旧字段
        bomId: form.bomId,
        bomCode: form.bomCode,
        bomItemId: row.bomItemId,
        bomItemCode: row.bomItemCode,
        bomItemName: row.bomItemName,
        bomItemSpec: row.bomItemSpec,
        unitOfMeasure: row.unitOfMeasure || row.unitName || '',
        unitName: row.unitName,
        itemOrProduct: row.itemOrProduct || 'ITEM',
        quantity: row.quantity,
        supplyType: row.supplyType,
        lossRate: row.lossRate,
        remark: row.remark
      }
      if (row._isNew || !row.lineId) {
        const savedLine = (await addEbomLine({
          ...linePayload,
          lineId: undefined,
          // 兼容旧 API 所需字段
          itemId: form.itemId,
          itemCode: form.itemCode,
          itemName: form.itemName,
          bomName: form.bomName,
          version: form.version,
          versionDesc: form.versionDesc,
          status: form.status,
          enableFlag: 'Y',
          attr1: row.pickType,
          attr2: row.usageType
        } as any)).data
        row.lineId = savedLine?.lineId || savedLine?.bomId
        row._isNew = false
      } else {
        await updateEbomLine({
          ...linePayload,
          itemId: form.itemId,
          itemCode: form.itemCode,
          itemName: form.itemName,
          bomName: form.bomName,
          version: form.version,
          status: form.status,
          enableFlag: 'Y',
          attr1: row.pickType,
          attr2: row.usageType
        } as any)
      }
    }

    ElMessage.success('保存成功')
    if (mode.value === 'new' && form.bomId) {
      router.replace({ name: 'EbomEdit', params: { id: form.bomId } })
    }
  } catch (e) {
    console.error(e)
    ElMessage.error('保存失败')
  } finally {
    saveLoading.value = false
  }
}

// ============ 审核/反审核 ============

async function handleApprove() {
  try {
    await ElMessageBox.confirm('确认审核此BOM单据？', '提示', { type: 'warning' })
    if (form.bomId) {
      await approveEbom(form.bomId)
    }
    form.status = 'APPROVED'
    form.approveDate = new Date().toISOString().slice(0, 10)
    ElMessage.success('审核成功')
  } catch (error: any) {
    if (error !== 'cancel') ElMessage.error('审核失败')
  }
}

async function handleUnApprove() {
  try {
    await ElMessageBox.confirm('确认反审核此BOM单据？', '提示', { type: 'warning' })
    if (form.bomId) {
      await unapproveEbom(form.bomId)
    }
    form.status = 'DRAFT'
    form.approveDate = ''
    form.approverName = ''
    ElMessage.success('反审核成功')
  } catch (error: any) {
    if (error !== 'cancel') ElMessage.error('反审核失败')
  }
}

function handleCancel() {
  router.push({ name: 'EbomList' })
}

// ============ 物料分类树 ============

const itemTypeTreeData = ref<any[]>([])
const treeFilterText = ref('')
const itemTreeFilterText = ref('')
const treeRef = ref()
const itemTreeRef = ref()

function filterNode(value: string, data: any) {
  if (!value) return true
  return data.label?.includes(value)
}

watch(treeFilterText, (val) => {
  treeRef.value?.filter(val)
})

watch(itemTreeFilterText, (val) => {
  itemTreeRef.value?.filter(val)
})

async function loadItemTypeTree() {
  try {
    const res = await listItemType({ enableFlag: 'Y' })
    const list = (res as any).data || res || []
    itemTypeTreeData.value = Array.isArray(list) ? handleTree(list).map(toTreeNode) : []
  } catch {
    itemTypeTreeData.value = []
  }
}

function toTreeNode(item: ItemType): any {
  return {
    id: item.itemTypeId,
    label: `${item.itemTypeCode || ''}-${item.itemTypeName || ''}`.replace(/^-/, ''),
    children: item.children?.map(toTreeNode) || []
  }
}

function getSupplyLabel(value?: string): string {
  const map: Record<string, string> = {
    PRODUCT: '生产', ITEM: '采购', PRODUCE: '生产',
    PURCHASE: '采购', OUTSOURCE: '委外', ASSEMBLY: '装配', PROCESS: '加工'
  }
  return map[value || ''] || value || '-'
}

// ============ 选择产品(母件)弹窗 ============

const productDialogVisible = ref(false)
const productLoading = ref(false)
const productList = ref<MdItem[]>([])
const productTotal = ref(0)
const productQuery = reactive({ itemCode: '', itemName: '', itemTypeId: undefined as number | undefined, pageNum: 1, pageSize: 100 })

function openProductDialog() {
  productDialogVisible.value = true
  productQuery.itemCode = ''
  productQuery.itemName = ''
  productQuery.itemTypeId = undefined
  searchProductItems()
}

async function searchProductItems() {
  productLoading.value = true
  try {
    const res = await listMdItem({
      itemCode: productQuery.itemCode || undefined,
      itemName: productQuery.itemName || undefined,
      itemTypeId: productQuery.itemTypeId,
      enableFlag: 'Y',
      pageNum: productQuery.pageNum,
      pageSize: productQuery.pageSize
    })
    productList.value = res.rows
    productTotal.value = res.total
  } finally {
    productLoading.value = false
  }
}

function resetProductSearch() {
  productQuery.itemCode = ''
  productQuery.itemName = ''
  productQuery.pageNum = 1
  searchProductItems()
}

function queryAllProducts() {
  productQuery.itemCode = ''
  productQuery.itemName = ''
  productQuery.itemTypeId = undefined
  productQuery.pageNum = 1
  searchProductItems()
}

function handleTreeNodeClick(node: any) {
  productQuery.itemTypeId = node.id
  productQuery.pageNum = 1
  searchProductItems()
}

function confirmProduct(row: MdItem) {
  form.itemId = row.itemId
  form.itemCode = row.itemCode
  form.itemName = row.itemName
  form.itemSpec = row.specification
  form.unitName = row.unitName
  if (!form.bomName) form.bomName = `${row.itemName} BOM`
  productDialogVisible.value = false
}

// ============ 选择子件物料弹窗 ============

const itemDialogVisible = ref(false)
const itemLoading = ref(false)
const itemList = ref<MdItem[]>([])
const itemTotal = ref(0)
const itemQuery = reactive({ itemCode: '', itemName: '', itemTypeId: undefined as number | undefined, pageNum: 1, pageSize: 100 })
const editingLineIndex = ref(-1)

function openItemDialog(idx: number) {
  editingLineIndex.value = idx
  itemDialogVisible.value = true
  itemQuery.itemCode = ''
  itemQuery.itemName = ''
  itemQuery.itemTypeId = undefined
  searchSubItems()
}

async function searchSubItems() {
  itemLoading.value = true
  try {
    const res = await listMdItem({
      itemCode: itemQuery.itemCode || undefined,
      itemName: itemQuery.itemName || undefined,
      itemTypeId: itemQuery.itemTypeId,
      enableFlag: 'Y',
      pageNum: itemQuery.pageNum,
      pageSize: itemQuery.pageSize
    })
    // 排除母件自身
    itemList.value = res.rows.filter(it => it.itemId !== form.itemId)
    itemTotal.value = res.total
  } finally {
    itemLoading.value = false
  }
}

function resetItemSearch() {
  itemQuery.itemCode = ''
  itemQuery.itemName = ''
  itemQuery.pageNum = 1
  searchSubItems()
}

function queryAllItems() {
  itemQuery.itemCode = ''
  itemQuery.itemName = ''
  itemQuery.itemTypeId = undefined
  itemQuery.pageNum = 1
  searchSubItems()
}

function handleItemTreeClick(node: any) {
  itemQuery.itemTypeId = node.id
  itemQuery.pageNum = 1
  searchSubItems()
}

function confirmItem(row: MdItem) {
  const idx = editingLineIndex.value
  if (idx < 0) {
    itemDialogVisible.value = false
    return
  }
  // 检查子件重复（按物料ID或物料编码，避免同一BOM下重复子件）
  const exists = lines.value.some(
    (l, i) => i !== idx && (l.bomItemId === row.itemId || (l.bomItemCode && l.bomItemCode === row.itemCode))
  )
  if (exists) {
    ElMessage.warning(`该物料已存在（${row.itemCode || row.itemName}），请勿重复添加`)
    return
  }
  const line = lines.value[idx]
  line.bomItemId = row.itemId
  line.bomItemCode = row.itemCode
  line.bomItemName = row.itemName
  line.bomItemSpec = row.specification
  line.unitOfMeasure = row.unitOfMeasure || ''
  line.unitName = row.unitName || ''
  line.itemOrProduct = row.itemOrProduct || 'ITEM'
  itemDialogVisible.value = false
}

// ============ 生命周期 ============

onMounted(() => {
  loadData()
  loadItemTypeTree()
})
</script>

<style scoped>
.bom-form-page {
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.header-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 10px;
  margin-bottom: 12px;
  border-bottom: 1px solid #ebeef5;
}

.title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

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

.grid-form :deep(.el-form-item) {
  margin-bottom: 12px;
}

.inline-select {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
}

.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 13px;
}

.lines-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.lines-title {
  font-size: 14px;
  font-weight: 600;
}

.lines-actions {
  display: flex;
  gap: 8px;
}

/* 物料选择弹窗布局 */
.item-select-layout {
  display: flex;
  gap: 12px;
  min-height: 460px;
}

.item-select-tree {
  width: 180px;
  flex-shrink: 0;
  border-right: 1px solid #ebeef5;
  padding-right: 12px;
  overflow-y: auto;
  max-height: 500px;
}

.item-select-table {
  flex: 1;
  overflow: hidden;
}

.pagination-wrapper {
  display: flex;
  justify-content: flex-end;
}
</style>
