<template>
  <el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="0px"
    :inline-message="true" :disabled="false">
    <el-table :data="formData" size="small" show-summary :summary-method="getSummaries" class="-mt-10px">
      <el-table-column :label="t('common.index')" type="index" align="center" width="60" />
      <el-table-column v-if="!isProductStockOut" :label="t('ErpStock.Item.warehouse')" min-width="125">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${$index}.warehouseId`" :rules="formRules.warehouseId" class="mb-0px!">
            <el-input v-if="disabled" :model-value="getWarehouseName(row.warehouseId)" readonly />
            <el-select v-else v-model="row.warehouseId" clearable filterable
              :placeholder="t('ErpStock.Item.placeholderWarehouse')" @change="onChangeWarehouse($event, row)">
              <el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
            </el-select>
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="isProductMaterialStockOut && !isProductStockOut" :label="t('ErpStock.Item.area')"
        min-width="140">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${$index}.areaId`" :rules="formRules.areaId" class="mb-0px!">
            <el-input v-if="disabled" :model-value="getAreaName(row.areaId)" readonly />
            <el-select v-else v-model="row.areaId" clearable filterable
              :placeholder="t('ErpStock.Item.placeholderArea')" :disabled="!row.warehouseId"
              @change="handleAreaChange(row)">
              <el-option v-for="item in getAreaOptions(row.warehouseId)" :key="item.id" :label="getAreaLabel(item)"
                :value="item.id" />
            </el-select>
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column :label="codeColumnLabel" min-width="160">
        <!--        <template #default="{ row }">
                  <el-form-item class="mb-0px!">
                    <el-input disabled v-model="row.productBarCode" />
                  </el-form-item>
                </template>-->
        <template #default="{ row, $index }">
          <el-form-item :prop="`${$index}.productBarCode`" class="mb-0px!">
            <div class="product-code-select">
              <el-input v-model="row.productBarCode" readonly :clearable="!disabled"
                :placeholder="t('ErpStock.Item.placeholderBarcode')" @click="handleProductInputClick(row)"
                @clear="handleProductClear(row)" />
            </div>
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column :label="t('ErpStock.Item.product')" min-width="180">
        <template #default="{ row, $index }">
          <el-form-item v-if="isProductMaterialStockOut" :prop="`${$index}.productId`" :rules="formRules.productId"
            class="mb-0px!">
            <el-input v-model="row.productName" disabled :placeholder="t('ErpStock.Item.placeholderProduct')" />
          </el-form-item>
          <el-form-item v-else :prop="`${$index}.productId`" :rules="formRules.productId" class="mb-0px!">
            <el-input v-if="disabled" :model-value="row.productName || '-'" readonly />
            <el-cascader v-model="row.productId" :options="productCascaderOptions" :props="productCascaderProps" v-else
              :show-all-levels="false" clearable filterable @change="onChangeProduct($event, row)"
              :placeholder="t('ErpStock.Item.placeholderProduct')" class="!w-100%" />
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="!isProductStockOut" :label="t('ErpStock.Item.stock')" min-width="100">
        <template #default="{ row }">
          <el-form-item class="mb-0px!">
            <el-input disabled v-model="row.stockCount" />
          </el-form-item>
        </template>
      </el-table-column>

      <el-table-column v-if="!isProductStockOut" :label="t('ErpStock.Item.inventoryUnit')" min-width="80">
        <template #default="{ row }">
          <el-form-item class="mb-0px!">
            <el-input disabled v-model="row.productUnitName" />
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="isProductStockOut" :label="t('ErpStock.Item.packageItemCount')" min-width="120">
        <template #default="{ row }">
          <el-input :model-value="row.packageQuantity ?? '-'" disabled />
        </template>
      </el-table-column>
      <el-table-column v-if="isPurchaseUnitStockOut" :label="t('ErpStock.Item.purchaseUnit')" min-width="100">
        <template #default="{ row }">
          <el-form-item class="mb-0px!">
            <el-input disabled v-model="row.purchaseUnitName" />
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="isPurchaseUnitStockOut" :label="t('ErpStock.Item.defaultSupplier')" min-width="130">
        <template #default="{ row }">
          <el-form-item class="mb-0px!">
            <el-input disabled v-model="row.supplierName" />
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="isPurchaseUnitStockOut" min-width="120">
        <template #header>
          {{ t('ErpStock.Item.purchaseUnitConvertQuantity') }}
          <el-tooltip effect="dark" placement="top">
            <template #content>
              {{ purchaseUnitConvertTipText }}
            </template>
            <Icon icon="ep:question-filled" class="ml-4px"
              style="vertical-align: middle; color: #909399; cursor: pointer;" />
          </el-tooltip>
        </template>
        <template #default="{ row }">
          <el-form-item class="mb-0px!">
            <el-input disabled v-model="row.purchaseUnitConvertQuantity" />
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="isSparePartStockOut" :label="t('ErpStock.Item.outboundPurpose')" min-width="140">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${$index}.outUsageType`" :rules="formRules.outUsageType" class="mb-0px!">
            <el-input v-if="disabled" :model-value="getOutboundPurposeLabel(row.outUsageType)" readonly />
            <el-select v-else v-model="row.outUsageType" clearable
              :placeholder="t('ErpStock.Item.placeholderOutboundPurpose')" @change="handleOutboundPurposeChange(row)">
              <el-option v-for="dict in outboundPurposeOptions" :key="dict.value" :label="dict.label"
                :value="dict.value" />
            </el-select>
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="isProductStockOut" :label="t('ErpStock.Item.outMode')" width="200">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${$index}.outMode`" :rules="formRules.outMode" class="mb-0px!">
            <el-input v-if="disabled" :model-value="getOutModeLabel(row.outMode)" readonly />
            <el-radio-group v-else v-model="row.outMode" class="out-mode-radio-group"
              @change="handleOutModeChange(row)">
              <el-radio-button :label="1">{{ t('ErpStock.Item.outModeWholePallet') }}</el-radio-button>
              <el-radio-button :label="2">{{ t('ErpStock.Item.outModeSplitPallet') }}</el-radio-button>
            </el-radio-group>
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="isProductStockOut" :label="t('ErpStock.Item.palletCode')" min-width="180">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${$index}.pallets`" :rules="formRules.pallets" class="mb-0px!">
            <el-input v-model="row.palletCode" readonly :clearable="!disabled"
              :placeholder="t('ErpStock.Item.placeholderPalletCode')" @click="openPalletSelectDialog(row)"
              @clear="clearPallet(row)" />
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="showRelatedRepairColumn" :label="t('ErpStock.Item.relatedRepairOrder')" min-width="190">
        <template #default="{ row, $index }">
          <el-form-item v-if="isRepairPurpose(row.outUsageType)" :prop="`${$index}.relatedOrderNo`" class="mb-0px!">
            <el-input v-model="row.relatedOrderNo" readonly :placeholder="getRelatedOrderPlaceholder(row.outUsageType)">
              <template v-if="!disabled" #append>
                <el-button @click="openRelatedOrderDialog(row)">
                  <Icon icon="ep:search" />
                </el-button>
              </template>
            </el-input>
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="showRelatedMaintainColumn" :label="t('ErpStock.Item.relatedMaintainRecord')"
        min-width="190">
        <template #default="{ row, $index }">
          <el-form-item v-if="isMaintainPurpose(row.outUsageType)" :prop="`${$index}.relatedMaintenanceNo`"
            class="mb-0px!">
            <el-input v-model="row.relatedMaintenanceNo" readonly
              :placeholder="getRelatedOrderPlaceholder(row.outUsageType)">
              <template v-if="!disabled" #append>
                <el-button @click="openRelatedOrderDialog(row)">
                  <Icon icon="ep:search" />
                </el-button>
              </template>
            </el-input>
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="isProductMaterialStockOut" :label="t('ErpStock.Item.count')" prop="inputCount"
        min-width="140">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${$index}.inputCount`" :rules="formRules.inputCount" class="mb-0px!">
            <el-input v-if="disabled || isProductStockOut" :model-value="row.pieceCount ?? row.inputCount ?? '-'"
              readonly />
            <el-input-number v-else v-model="row.inputCount" controls-position="right" :min="0" :precision="0"
              class="!w-100%" @blur="handleInputCountBlur(row)" />
          </el-form-item>
        </template>
      </el-table-column>
      <!--      <el-table-column :label="t('ErpStock.Item.price')" fixed="right" min-width="120">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${$index}.productPrice`" class="mb-0px!">
            <el-input-number
              v-model="row.productPrice"
              controls-position="right"
              :min="0.00"
              :precision="2"
              class="!w-100%"
            />
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column :label="t('ErpStock.Item.totalPrice')" prop="totalPrice" fixed="right" min-width="100">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${$index}.totalPrice`" class="mb-0px!">
            <el-input disabled v-model="row.totalPrice" :formatter="erpPriceInputFormatter" />
          </el-form-item>
        </template>
      </el-table-column>-->
      <el-table-column :label="t('ErpStock.Item.remark')" fixed="right" min-width="150">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${$index}.remark`" class="mb-0px!">
            <el-input v-model="row.remark" :readonly="disabled" :placeholder="t('ErpStock.Out.placeholderRemark')" />
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="!disabled" align="center" fixed="right" :label="t('ErpStock.Item.action')" width="60">
        <template #default="{ $index }">
          <el-button type="danger" @click="handleDelete($index)" link>
            <Icon icon="ep:delete" />
          </el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-form>
  <el-row justify="center" class="mt-3" v-if="!disabled">
    <el-button @click="handleAdd" round>+ {{ t('ErpStock.Out.addItem') }}</el-button>
  </el-row>

  <Dialog :title="t('ErpStock.Item.selectCode')" v-model="productDialogVisible" width="900px">
    <el-form :model="productQueryParams" :inline="true" class="-mb-15px">
      <el-form-item :label="t('ErpStock.Item.code')">
        <el-input v-model="productQueryParams.barCode" clearable :placeholder="t('ErpStock.Item.placeholderCode')"
          @keyup.enter="handleProductDialogQuery" />
      </el-form-item>
      <el-form-item :label="t('ErpStock.Item.name')">
        <el-input v-model="productQueryParams.name" clearable :placeholder="t('ErpStock.Item.placeholderName')"
          @keyup.enter="handleProductDialogQuery" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleProductDialogQuery">
          <Icon icon="ep:search" class="mr-5px" /> {{ t('common.query') }}
        </el-button>
      </el-form-item>
    </el-form>
    <el-table v-loading="productDialogLoading" :data="productDialogList" row-key="id" :stripe="true"
      :show-overflow-tooltip="true" @row-click="handleProductDialogRowClick">
      <el-table-column width="55" align="center">
        <template #default="{ row }">
          <el-radio v-model="selectedProductId" :label="row.id">&nbsp;</el-radio>
        </template>
      </el-table-column>
      <el-table-column :label="t('ErpStock.Item.code')" prop="barCode" min-width="160" />
      <el-table-column :label="t('ErpStock.Item.name')" prop="name" min-width="160" />
      <el-table-column :label="t('ErpStock.Item.spec')" prop="standard" min-width="120" />
      <el-table-column :label="t('ErpStock.Item.category')" prop="subCategoryName" min-width="120" />
      <el-table-column :label="t('ErpStock.Item.unit')" prop="unitName" min-width="80" />
      <el-table-column v-if="isPurchaseUnitStockOut" :label="t('ErpStock.Item.purchaseUnit')" prop="purchaseUnitName"
        min-width="100" />
      <el-table-column v-if="isPurchaseUnitStockOut" :label="t('ErpStock.Item.defaultSupplier')" min-width="130">
        <template #default="{ row }">
          {{ getDefaultSupplierName(row) || '-' }}
        </template>
      </el-table-column>
      <el-table-column v-if="isPurchaseUnitStockOut" :label="t('ErpStock.Item.purchaseUnitConvertQuantity')"
        prop="purchaseUnitConvertQuantity" min-width="120" />
    </el-table>
    <div class="product-dialog-pagination">
      <Pagination :total="productDialogTotal" v-model:page="productQueryParams.pageNo"
        v-model:limit="productQueryParams.pageSize" @pagination="getProductDialogList" />
    </div>
    <template #footer>
      <el-button type="primary" @click="confirmProductSelect">{{ t('common.ok') }}</el-button>
      <el-button @click="productDialogVisible = false">{{ t('common.cancel') }}</el-button>
    </template>
  </Dialog>

  <Dialog :title="t('ErpStock.Item.selectPalletCode')" v-model="palletDialogVisible"
    :width="disabled ? '900px' : '1280px'">
    <el-form v-if="!disabled" :model="palletQueryParams" :inline="true" class="-mb-15px">
      <el-form-item :label="t('ErpStock.Pallet.code')">
        <el-input v-model="palletQueryParams.code" clearable :placeholder="t('ErpStock.Pallet.placeholderCode')"
          @keyup.enter="handlePalletDialogQuery" />
      </el-form-item>
      <el-form-item :label="t('ErpStock.Pallet.status')">
        <el-select v-model="palletQueryParams.status" clearable :placeholder="t('ErpStock.Pallet.placeholderStatus')"
          class="!w-180px">
          <el-option v-for="dict in palletStatusOptions" :key="dict.value" :label="dict.label" :value="dict.value" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handlePalletDialogQuery">
          <Icon icon="ep:search" class="mr-5px" /> {{ t('common.query') }}
        </el-button>
      </el-form-item>
    </el-form>
    <el-table v-if="disabled" :data="selectedPalletRows" row-key="id" :stripe="true" :show-overflow-tooltip="true">
      <el-table-column :label="t('ErpStock.Pallet.code')" prop="code" min-width="150" />
      <el-table-column :label="t('ErpStock.Item.warehouse')" min-width="130">
        <template #default="{ row }">
          {{ getWarehouseName(row.warehouseId) }}
        </template>
      </el-table-column>
      <el-table-column :label="t('ErpStock.Item.area')" min-width="130">
        <template #default="{ row }">
          {{ getAreaName(row.areaId) }}
        </template>
      </el-table-column>
      <el-table-column :label="t('ErpStock.Item.outPackageCount')" min-width="130">
        <template #default="{ row }">
          <el-input :model-value="row.packageCount ?? '-'" readonly />
        </template>
      </el-table-column>
      <el-table-column :label="t('ErpStock.Item.outCount')" min-width="120">
        <template #default="{ row }">
          <el-input :model-value="getSelectedPalletOutCount(row)" readonly />
        </template>
      </el-table-column>
    </el-table>
    <el-table v-else ref="palletTableRef" v-loading="palletDialogLoading" :data="palletDialogList" row-key="id"
      :stripe="true" :show-overflow-tooltip="true" @row-click="handlePalletDialogRowClick"
      @selection-change="handlePalletDialogSelectionChange">
      <el-table-column type="selection" width="55" align="center" :reserve-selection="true" />
      <el-table-column :label="t('ErpStock.Pallet.code')" prop="code" min-width="150" />
      <el-table-column :label="t('ErpStock.Pallet.palletType')" prop="palletType" min-width="100">
        <template #default="{ row }">
          <dict-tag :type="DICT_TYPE.STORAGE_PALLET_TYPES" :value="row.palletType" />
        </template>
      </el-table-column>
      <el-table-column :label="t('ErpStock.Pallet.status')" prop="status" min-width="100">
        <template #default="{ row }">
          <dict-tag :type="DICT_TYPE.STORAGE_PALLET_STATUS" :value="row.status" />
        </template>
      </el-table-column>
      <el-table-column :label="t('ErpStock.Item.warehouse')" min-width="130">
        <template #default="{ row }">
          {{ getWarehouseName(row.warehouseId) }}
        </template>
      </el-table-column>
      <el-table-column :label="t('ErpStock.Item.area')" min-width="130">
        <template #default="{ row }">
          {{ getAreaName(row.areaId) }}
        </template>
      </el-table-column>
      <el-table-column :label="t('ErpStock.Pallet.productName')" prop="productName" min-width="100" />
      <el-table-column :label="t('ErpStock.Item.packageCount')" prop="productCount" min-width="100" />
      <el-table-column v-if="currentSelectRow?.outMode === 2" :label="t('ErpStock.Item.outPackageCount')"
        min-width="130">
        <template #default="{ row }">
          <el-input-number v-model="row.packageCount" controls-position="right" :min="0" :precision="0" class="!w-100%"
            @change="handlePalletPackageCountChange($event, row)" @click.stop />
        </template>
      </el-table-column>
      <el-table-column :label="t('ErpStock.Item.outCount')" min-width="120">
        <template #default="{ row }">
          <el-input :model-value="getPalletOutCount(row)" disabled />
        </template>
      </el-table-column>
    </el-table>
    <div v-if="!disabled" class="product-dialog-pagination">
      <Pagination :total="palletDialogTotal" v-model:page="palletQueryParams.pageNo"
        v-model:limit="palletQueryParams.pageSize" @pagination="getPalletDialogList" />
    </div>
    <template #footer>
      <el-button v-if="!disabled" type="primary" @click="confirmPalletSelect">{{ t('common.ok') }}</el-button>
      <el-button @click="palletDialogVisible = false">{{ t('common.cancel') }}</el-button>
    </template>
  </Dialog>

  <Dialog :title="relatedOrderDialogTitle" v-model="relatedOrderDialogVisible" width="1100px">
    <el-table v-loading="relatedOrderLoading" :data="relatedOrderList" :stripe="true" :show-overflow-tooltip="true"
      row-key="id" @row-click="handleRelatedOrderRowClick">
      <el-table-column width="55" align="center">
        <template #default="{ row }">
          <el-radio v-model="selectedRelatedOrderId" :label="row.id">&nbsp;</el-radio>
        </template>
      </el-table-column>
      <template v-if="relatedOrderType === 'repair'">
        <el-table-column :label="t('EquipmentManagement.DvRepair.repairCode')" align="center" prop="repairCode"
          min-width="180" />
        <el-table-column :label="t('EquipmentManagement.DvRepair.repairName')" align="center" prop="repairName"
          min-width="160" />
        <el-table-column :label="t('EquipmentManagement.DvRepair.status')" align="center" prop="status" width="110">
          <template #default="scope">
            <el-tag :type="getRepairStatusTagType(scope.row.status)" effect="light">
              {{ getRepairStatusLabel(scope.row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column :label="t('EquipmentManagement.DvRepair.repairStatus')" align="center" prop="repairStatus"
          min-width="120">
          <template #default="scope">
            <el-tag :type="getRepairResultTagType(scope.row.repairStatus)" effect="light">
              {{ getRepairResultLabel(scope.row.repairStatus) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column :label="t('EquipmentManagement.DvRepair.machineryName')" align="center" prop="machineryName"
          min-width="180" />
        <el-table-column :label="t('EquipmentManagement.DvRepair.machineryCode')" align="center" prop="machineryCode"
          min-width="180" />
        <el-table-column :label="t('EquipmentManagement.DvRepair.machinerySpec')" align="center" prop="machinerySpec"
          min-width="120" />
        <el-table-column :label="t('EquipmentManagement.DvRepair.machineryType')" align="center" prop="machineryTypeId"
          width="100">
          <template #default="scope">
            <dict-tag :type="DICT_TYPE.MES_MACHINE_TYPE" :value="scope.row.machineryTypeId" />
          </template>
        </el-table-column>
        <el-table-column :label="t('EquipmentManagement.DvRepair.requireDate')" align="center" prop="requireDate"
          :formatter="dateFormatter2" width="110" />
        <el-table-column :label="t('EquipmentManagement.DvRepair.finishDate')" align="center" prop="finishDate"
          :formatter="dateFormatter2" width="110" />
        <el-table-column :label="t('EquipmentManagement.DvRepair.confirmDate')" align="center" prop="confirmDate"
          :formatter="dateFormatter2" width="110" />
        <el-table-column :label="t('EquipmentManagement.DvRepair.acceptedBy')" align="center" prop="acceptedBy"
          min-width="150" />
        <el-table-column :label="t('EquipmentManagement.DvRepair.confirmBy')" align="center" prop="confirmBy"
          min-width="150" />
        <el-table-column :label="t('EquipmentManagement.DvRepair.createTime')" align="center" prop="createTime"
          :formatter="dateFormatter" width="170" />
      </template>
      <template v-else>
        <el-table-column :label="t('EquipmentManagement.WorkOrderManagement.planNo')" align="center" prop="planNo"
          min-width="160" />
        <el-table-column :label="t('EquipmentManagement.WorkOrderManagement.deviceName')" align="center"
          prop="deviceName" min-width="160" />
        <el-table-column :label="t('EquipmentManagement.WorkOrderManagement.planType')" align="center" prop="planType"
          width="90">
          <template #default="scope">
            <el-tag v-if="String(scope.row.planType) === '1'" type="primary">
              {{ t('EquipmentManagement.WorkOrderManagement.planTypeInspect') }}
            </el-tag>
            <el-tag v-else-if="String(scope.row.planType) === '2'" type="success">
              {{ t('EquipmentManagement.WorkOrderManagement.planTypeMaintain') }}
            </el-tag>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column :label="t('EquipmentManagement.WorkOrderManagement.configName')" align="center"
          prop="configName" min-width="160" />
        <el-table-column :label="t('EquipmentManagement.WorkOrderManagement.jobStatus')" align="center" prop="jobStatus"
          width="120">
          <template #default="scope">
            <dict-tag :type="'job_status'" :value="scope.row.jobStatus" />
          </template>
        </el-table-column>
        <el-table-column :label="t('EquipmentManagement.WorkOrderManagement.operatorName')" align="center"
          prop="operatorName" width="140" />
        <el-table-column :label="t('EquipmentManagement.WorkOrderManagement.taskTime')" align="center" prop="taskTime"
          :formatter="dateFormatter" width="180" />
        <el-table-column :label="t('EquipmentManagement.WorkOrderManagement.taskEndTime')" align="center"
          prop="taskEndTime" :formatter="dateFormatter" width="180" />
        <el-table-column :label="t('EquipmentManagement.WorkOrderManagement.jobResult')" align="center" prop="jobResult"
          width="90">
          <template #default="scope">
            <el-tag v-if="scope.row.jobResult == '1'" type="success">
              {{ t('EquipmentManagement.WorkOrderManagement.jobResultOk') }}
            </el-tag>
            <el-tag v-else-if="scope.row.jobResult == '2'" type="danger">
              {{ t('EquipmentManagement.WorkOrderManagement.jobResultNg') }}
            </el-tag>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column :label="t('EquipmentManagement.WorkOrderManagement.createTime')" align="center"
          prop="createTime" :formatter="dateFormatter" width="180" />
      </template>
    </el-table>
    <div class="product-dialog-pagination">
      <Pagination :total="relatedOrderTotal" v-model:page="relatedOrderQueryParams.pageNo"
        v-model:limit="relatedOrderQueryParams.pageSize" @pagination="getRelatedOrderList" />
    </div>
    <template #footer>
      <el-button type="primary" @click="confirmRelatedOrderSelect">{{ t('common.ok') }}</el-button>
      <el-button @click="relatedOrderDialogVisible = false">{{ t('common.cancel') }}</el-button>
    </template>
  </Dialog>
</template>
<script setup lang="ts">
import { Icon } from '@/components/Icon'
import { ProductApi, ProductVO } from '@/api/erp/product/product'
import { WarehouseApi, WarehouseVO } from '@/api/erp/stock/warehouse'
import { WarehouseAreaApi, WarehouseAreaVO } from '@/api/erp/stock/warehousearea'
import { StockApi } from '@/api/erp/stock/stock'
import { PalletApi, PalletVO } from '@/api/erp/stock/pallet'
import { DvRepairApi } from '@/api/mes/dvrepair'
import { TicketManagementApi } from '@/api/mes/ticketManagement'
import { DICT_TYPE, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
import {
  erpCountInputFormatter,
  erpPriceInputFormatter,
  erpPriceMultiply,
  getSumValue
} from '@/utils'

const props = defineProps<{
  items: any[] | undefined
  outType?: string
  disabled: boolean
}>()
const formLoading = ref(false) // 表单的加载中
const formData = ref([])
const { t } = useI18n()
const message = useMessage()
const formRules = reactive({
  warehouseId: [{ required: true, message: t('ErpStock.Item.validatorWarehouseRequired'), trigger: 'blur' }],
  areaId: [{ required: true, message: t('ErpStock.Item.validatorAreaRequired'), trigger: 'change' }],
  productId: [{ required: true, message: t('ErpStock.Item.validatorProductRequired'), trigger: 'blur' }],
  outUsageType: [{ required: true, message: t('ErpStock.Item.validatorOutboundPurposeRequired'), trigger: 'change' }],
  outMode: [{ required: true, message: t('ErpStock.Item.validatorOutModeRequired'), trigger: 'change' }],
  pallets: [{ validator: validatePallets, trigger: 'change' }],
  inputCount: [{ required: true, message: t('ErpStock.Item.validatorCountRequired'), trigger: 'blur' }],
  count: [{ required: true, message: t('ErpStock.Item.validatorCountRequired'), trigger: 'blur' }]
})
const formRef = ref([]) // 表单 Ref
const productList = ref<ProductVO[]>([]) // 产品列表
const warehouseList = ref<WarehouseVO[]>([]) // 仓库列表
const defaultWarehouse = ref<WarehouseVO>(undefined) // 默认仓库
const warehouseAreaMap = ref<Record<number, WarehouseAreaVO[]>>({})
const resolveStockOutCategoryType = (outType?: string) => {
  if (!outType) return undefined
  if (outType.includes('产品')) return 1
  if (outType.includes('物料') || outType.includes('原料') || outType.includes('领料')) return 2
  if (outType.includes('备件')) return 3
  return undefined
}
const activeCategoryType = computed(() => resolveStockOutCategoryType(props.outType))
const isProductMaterialStockOut = computed(() => Boolean(activeCategoryType.value))
const isProductStockOut = computed(() => activeCategoryType.value === 1)
const isPurchaseUnitStockOut = computed(() => activeCategoryType.value === 2 || activeCategoryType.value === 3)
const isSparePartStockOut = computed(() => activeCategoryType.value === 3)
const codeColumnLabel = computed(() => {
  if (activeCategoryType.value === 1) return t('ErpStock.Item.productLabel')
  if (activeCategoryType.value === 2) return t('ErpStock.Item.materialLabel')
  if (activeCategoryType.value === 3) return t('ErpStock.Item.sparePartLabel')
  return t('ErpStock.Item.barcode')
})
const outboundPurposeOptions = computed(() => getStrDictOptions(DICT_TYPE.WAREHOUSE_OUTBOUND_PURPOSE))
const purchaseUnitConvertTipText = computed(() => t('FactoryModeling.ProductInformation.dialogPurchaseUnitConvertTip'))
const productDialogVisible = ref(false)
const productDialogLoading = ref(false)
const productDialogList = ref<any[]>([])
const productDialogTotal = ref(0)
const productQueryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  categoryType: 1,
  barCode: undefined,
  name: undefined
})
const currentSelectRow = ref<any>()
const selectedProductId = ref<number>()
const palletDialogVisible = ref(false)
const palletDialogLoading = ref(false)
const palletDialogList = ref<PalletVO[]>([])
const palletDialogTotal = ref(0)
const palletTableRef = ref()
const selectedPalletRows = ref<PalletVO[]>([])
const palletQueryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  code: undefined,
  status: undefined,
  excludeStatus: 3
})
const palletStatusOptions = computed(() =>
  getIntDictOptions(DICT_TYPE.STORAGE_PALLET_STATUS).filter((dict) => Number(dict.value) !== 3)
)
const RELATED_PURPOSE_REPAIR = '1'
const RELATED_PURPOSE_MAINTAIN = '2'
const relatedOrderDialogVisible = ref(false)
const relatedOrderLoading = ref(false)
const relatedOrderType = ref<'repair' | 'maintain'>('repair')
const relatedOrderList = ref<any[]>([])
const relatedOrderTotal = ref(0)
const currentRelatedRow = ref<any>()
const selectedRelatedOrderId = ref<number>()
const repairCodeCache = new Map<number | string, string>()
const relatedOrderQueryParams = reactive({
  pageNo: 1,
  pageSize: 10
})
const relatedOrderDialogTitle = computed(() =>
  relatedOrderType.value === 'repair'
    ? t('ErpStock.Item.selectRelatedRepairOrder')
    : t('ErpStock.Item.selectRelatedMaintainRecord')
)
const showRelatedRepairColumn = computed(
  () => isSparePartStockOut.value && formData.value.some((row) => isRepairPurpose(row.outUsageType))
)
const showRelatedMaintainColumn = computed(
  () => isSparePartStockOut.value && formData.value.some((row) => isMaintainPurpose(row.outUsageType))
)

function validatePallets(_: any, value: any[], callback: (error?: Error) => void) {
  if (!isProductStockOut.value || (Array.isArray(value) && value.length > 0)) {
    callback()
    return
  }
  callback(new Error(t('ErpStock.Item.validatorPalletRequired')))
}

const productCascaderProps = {
  emitPath: false,
  value: 'value',
  label: 'label',
  children: 'children'
}

const productCascaderOptions = computed(() => {
  const map = new Map<number | string, { value: number | string; label: string; children: any[] }>()
  for (const item of productList.value) {
    const categoryKey = item.categoryId ?? item.categoryName ?? ''
    const categoryLabel = item.categoryName ?? String(categoryKey)
    if (!map.has(categoryKey)) {
      map.set(categoryKey, {
        value: categoryKey,
        label: categoryLabel,
        children: []
      })
    }
    const group = map.get(categoryKey)
    if (group) {
      group.children.push({
        value: item.id,
        label: item.name
      })
    }
  }
  return Array.from(map.values())
})

const loadWarehouseList = async () => {
  const categoryType = activeCategoryType.value
  warehouseList.value = await WarehouseApi.getWarehouseSimpleList(categoryType ? { categoryType } : undefined)
  const firstWarehouse = warehouseList.value[0]
  defaultWarehouse.value = firstWarehouse
  const warehouseIds = new Set((warehouseList.value || []).map((item) => item.id))
  formData.value.forEach((row) => {
    if (row.warehouseId && !warehouseIds.has(row.warehouseId)) {
      row.warehouseId = undefined
      row.areaId = undefined
      row.stockCount = 0
    }
    if (!row.warehouseId && firstWarehouse?.id) {
      row.warehouseId = firstWarehouse.id
      row.areaId = undefined
      row.stockCount = 0
    }
  })
  warehouseAreaMap.value = {}
}

/** 初始化设置入库项 */
watch(
  () => props.items,
  async (val) => {
    formData.value = val || []
    normalizeRows(formData.value)
    await fillRelatedRepairCodes(formData.value)
    fillProductNames(formData.value)
    if (isProductMaterialStockOut.value) {
      await loadRowsWarehouseAreas(formData.value)
    }
  },
  { immediate: true }
)

watch(
  () => props.outType,
  async () => {
    await loadWarehouseList()
    if (isProductMaterialStockOut.value) {
      formData.value.forEach((row) => {
        normalizeRow(row)
        row.inputCount = row.inputCount ?? row.count ?? 1
        if (isProductStockOut.value) {
          row.inputUnitType = row.inputUnitType || '个'
          row.outMode = Number(row.outMode || 1)
        }
        syncCountByInputCount(row)
      })
      await loadRowsWarehouseAreas(formData.value)
    }
  }
)

/** 监听合同产品变化，计算合同产品总价 */
watch(
  () => formData.value,
  (val) => {
    if (!val || val.length === 0) {
      return
    }
    // 循环处理
    val.forEach((item) => {
      item.totalPrice = erpPriceMultiply(item.productPrice, item.count)
    })
  },
  { deep: true }
)

/** 合计 */
const getSummaries = (param: SummaryMethodProps) => {
  const { columns, data } = param
  const sums: string[] = []
  columns.forEach((column, index) => {
    if (index === 0) {
      sums[index] = t('common.total')
      return
    }
    if (['inputCount', 'count', 'totalPrice'].includes(column.property)) {
      const sum = getSumValue(data.map((item) => Number(item[column.property])))
      sums[index] =
        column.property === 'inputCount' || column.property === 'count'
          ? erpCountInputFormatter(sum)
          : erpPriceInputFormatter(sum)
    } else {
      sums[index] = ''
    }
  })

  return sums
}

/** 新增按钮操作 */
const handleAdd = () => {
  const row = {
    id: undefined,
    warehouseId: defaultWarehouse.value?.id,
    areaId: undefined,
    productId: undefined,
    productName: undefined,
    productUnitName: undefined, // 产品单位
    productBarCode: undefined, // 产品条码
    productPrice: undefined,
    purchaseUnitId: undefined,
    purchaseUnitName: undefined,
    supplierName: undefined,
    purchaseUnitConvertQuantity: undefined,
    packagingSchemeRelationId: undefined,
    packagingSchemeId: undefined,
    packagingSchemeName: undefined,
    packageQuantity: undefined,
    palletPackageQuantity: undefined,
    palletTotalQuantity: undefined,
    palletCount: undefined,
    packageCount: undefined,
    pieceCount: undefined,
    inputUnitType: isProductStockOut.value ? '个' : undefined,
    inputCount: isProductMaterialStockOut.value ? 1 : undefined,
    stockCount: undefined,
    count: isProductMaterialStockOut.value ? undefined : 1,
    outMode: isProductStockOut.value ? 1 : undefined,
    outUsageType: undefined,
    pallets: [],
    palletCode: undefined,
    repairId: undefined,
    repairDeviceId: undefined,
    maintenanceId: undefined,
    relatedOrderNo: undefined,
    relatedOrderName: undefined,
    relatedMaintenanceNo: undefined,
    relatedMaintenanceName: undefined,
    relatedOrderType: undefined,
    totalPrice: undefined,
    remark: undefined
  }
  syncCountByInputCount(row)
  formData.value.push(row)
  if (row.warehouseId && isProductMaterialStockOut.value) {
    loadWarehouseAreas(row.warehouseId)
  }
}

/** 删除按钮操作 */
const handleDelete = (index) => {
  formData.value.splice(index, 1)
}

/** 处理产品变更 */
const onChangeProductCode = (productBarCode, row) => {
  const product = productList.value.find((item) => item.barCode === productBarCode)
  product ? fillRowByProduct(row, product) : clearProduct(row)
  // 加载库存
  setStockCount(row)
}

/** 处理仓库变更 */
const onChangeWarehouse = (warehouseId, row) => {
  row.areaId = undefined
  clearPallet(row)
  if (warehouseId && isProductMaterialStockOut.value) {
    loadWarehouseAreas(warehouseId)
  }
  // 加载库存
  setStockCount(row)
}

const handleAreaChange = (row: any) => {
  clearPallet(row)
  setStockCount(row)
}

/** 处理产品变更 */
const onChangeProduct = (productId, row) => {
  const product = productList.value.find((item) => item.id === productId)
  product ? fillRowByProduct(row, product) : clearProduct(row)
  // 加载库存
  setStockCount(row)
}

const fillRowByProduct = (row: any, product: any) => {
  row.productUnitName = product.unitName
  row.productBarCode = product.barCode
  row.productPrice = product.minPrice
  row.productId = product.id
  row.productName = product.name
  row.purchaseUnitId = product.purchaseUnitId
  row.purchaseUnitName = product.purchaseUnitName
  row.supplierName = getDefaultSupplierName(product)
  row.purchaseUnitConvertQuantity = product.purchaseUnitConvertQuantity
  fillPackagingSchemeByProduct(row, product)
  syncCountByInputCount(row)
}

const fillPackagingSchemeByProduct = (row: any, product: any) => {
  const schemes = Array.isArray(product?.packagingSchemes) ? product.packagingSchemes : []
  const defaultSchemeId = product?.defaultPackagingSchemeId
  const scheme =
    schemes.find((item: any) => Number(item?.defaultStatus) === 1) ||
    schemes.find((item: any) => item?.packagingSchemeId === defaultSchemeId || item?.id === defaultSchemeId) ||
    schemes[0]
  row.packagingSchemeRelationId = scheme?.id
  row.packagingSchemeId = scheme?.packagingSchemeId ?? scheme?.id
  row.packagingSchemeName = scheme?.packagingSchemeName ?? scheme?.name
  row.packageQuantity = scheme?.packageQuantity ?? product?.packageQuantity
  row.palletPackageQuantity = scheme?.palletPackageQuantity ?? product?.palletPackageQuantity
  row.palletTotalQuantity = scheme?.palletTotalQuantity ?? product?.palletTotalQuantity
  syncInputCountByPallets(row)
}

const getDefaultSupplierName = (product: any) => {
  if (!product) return undefined
  if (product.supplierName) return product.supplierName
  const suppliers = Array.isArray(product.suppliers) ? product.suppliers : []
  return suppliers.find((item) => Number(item?.defaultStatus) === 1)?.supplierName
}

const normalizeRows = (rows: any[]) => {
  ; (rows || []).forEach(normalizeRow)
}

const normalizeRow = (row: any) => {
  if (!row) return
  if (row.outUsageType !== undefined && row.outUsageType !== null) {
    row.outUsageType = String(row.outUsageType)
  }
  row.inputCount = row.inputCount ?? row.count
  if (isProductStockOut.value) {
    row.outMode = Number(row.outMode || 1)
    if (!Array.isArray(row.pallets)) {
      row.pallets = row.palletId ? [{ palletId: row.palletId, packageCount: row.packageCount }] : []
    }
    if (!row.palletCode && Array.isArray(row.pallets) && row.pallets.length > 0) {
      row.palletCode = row.pallets.map((item) => item.palletCode || item.code).filter(Boolean).join(', ')
    }
  }
  if (row.repairId) {
    row.relatedOrderNo = row.relatedOrderNo || row.repairCode || row.repairNo || String(row.repairId)
    row.relatedOrderName = row.relatedOrderName || row.repairName
    row.relatedOrderType = row.relatedOrderType || 'repair'
  }
  if (row.maintenanceId) {
    row.relatedMaintenanceNo =
      row.relatedMaintenanceNo ||
      row.maintenanceCode ||
      row.maintenanceNo ||
      row.planNo ||
      row.maintenanceName ||
      String(row.maintenanceId)
    row.relatedMaintenanceName = row.relatedMaintenanceName || row.maintenanceName
    row.relatedOrderType = row.relatedOrderType || 'maintain'
  }
}

const fillRelatedRepairCodes = async (rows: any[]) => {
  const repairRows = (rows || []).filter((row) => row?.repairId)
  await Promise.all(
    repairRows.map(async (row) => {
      const repairId = row.repairId
      let repairCode = repairCodeCache.get(repairId)
      if (!repairCode) {
        try {
          const repair = await DvRepairApi.getDvRepair(repairId)
          repairCode = repair?.repairCode
          if (repairCode) {
            repairCodeCache.set(repairId, repairCode)
          }
          row.repairDeviceId = row.repairDeviceId ?? repair?.machineryId
        } catch {
          repairCode = undefined
        }
      }
      row.relatedOrderNo = repairCode || row.repairCode || row.repairNo || String(repairId)
    })
  )
}

const clearProduct = (row: any) => {
  row.productUnitName = undefined
  row.productBarCode = undefined
  row.productPrice = undefined
  row.productId = undefined
  row.productName = undefined
  row.purchaseUnitId = undefined
  row.purchaseUnitName = undefined
  row.supplierName = undefined
  row.purchaseUnitConvertQuantity = undefined
  row.packagingSchemeRelationId = undefined
  row.packagingSchemeId = undefined
  row.packagingSchemeName = undefined
  row.packageQuantity = undefined
  row.palletPackageQuantity = undefined
  row.palletTotalQuantity = undefined
  row.palletCount = undefined
  row.packageCount = undefined
  row.pieceCount = undefined
  clearPallet(row)
  row.inputCount = isProductMaterialStockOut.value ? undefined : row.inputCount
  row.count = isProductMaterialStockOut.value ? undefined : row.count
}

const handleProductClear = (row: any) => {
  if (props.disabled) return
  clearProduct(row)
  setStockCount(row)
}

const handleProductInputClick = (row: any) => {
  if (props.disabled) return
  openProductSelectDialog(row)
}

const openProductSelectDialog = async (row: any) => {
  if (!activeCategoryType.value) return
  currentSelectRow.value = row
  selectedProductId.value = row.productId
  productQueryParams.pageNo = 1
  productQueryParams.categoryType = activeCategoryType.value
  productQueryParams.barCode = undefined
  productQueryParams.name = undefined
  productDialogVisible.value = true
  await getProductDialogList()
}

const getProductDialogList = async () => {
  productDialogLoading.value = true
  try {
    productQueryParams.categoryType = activeCategoryType.value || 1
    const data = await ProductApi.getProductPage(productQueryParams)
    productDialogList.value = data?.list || []
    productDialogTotal.value = data?.total || 0
  } finally {
    productDialogLoading.value = false
  }
}

const handleProductDialogQuery = () => {
  productQueryParams.pageNo = 1
  getProductDialogList()
}

const handleProductDialogRowClick = (row: any) => {
  selectedProductId.value = row.id
}

const confirmProductSelect = async () => {
  const product = productDialogList.value.find((item) => item.id === selectedProductId.value)
  if (!product || !currentSelectRow.value) return
  let finalProduct = product
  if (!Array.isArray((product as any).packagingSchemes)) {
    finalProduct = await ProductApi.getProduct(product.id)
  }
  fillRowByProduct(currentSelectRow.value, finalProduct)
  clearPallet(currentSelectRow.value)
  setStockCount(currentSelectRow.value)
  productDialogVisible.value = false
}

const handleOutModeChange = (row: any) => {
  if (props.disabled) return
  clearPallet(row)
}

const openPalletSelectDialog = async (row: any) => {
  currentSelectRow.value = row
  selectedPalletRows.value = getInitialSelectedPalletRows(row)
  await loadRowsWarehouseAreas(selectedPalletRows.value)
  palletQueryParams.pageNo = 1
  palletQueryParams.code = undefined
  palletQueryParams.status = undefined
  palletDialogVisible.value = true
  if (props.disabled) return
  await getPalletDialogList()
}

const getPalletDialogList = async () => {
  palletDialogLoading.value = true
  try {
    const data = await PalletApi.getPalletPage({
      ...palletQueryParams,
      productId: currentSelectRow.value?.productId,
      warehouseId: isProductStockOut.value ? undefined : currentSelectRow.value?.warehouseId,
      areaId: isProductStockOut.value ? undefined : currentSelectRow.value?.areaId
    })
    const selectedPackageMap = new Map((currentSelectRow.value?.pallets || []).map((item: any) => [item.palletId, item.packageCount]))
    palletDialogList.value = (data?.list || []).map((pallet: any) => {
      const selectedPackageCount = selectedPackageMap.get(pallet.id)
      return {
        ...pallet,
        packageCount: selectedPackageCount ?? 0
      }
    })
    palletDialogTotal.value = data?.total || 0
    await loadRowsWarehouseAreas(palletDialogList.value)
    await nextTick()
    syncPalletDialogSelection()
  } finally {
    palletDialogLoading.value = false
  }
}

const handlePalletDialogQuery = () => {
  palletQueryParams.pageNo = 1
  getPalletDialogList()
}

const handlePalletDialogRowClick = (row: PalletVO) => {
  palletTableRef.value?.toggleRowSelection(row)
}

const handlePalletDialogSelectionChange = (rows: PalletVO[]) => {
  selectedPalletRows.value = rows
}

const confirmPalletSelect = () => {
  if (props.disabled) return
  if (!currentSelectRow.value) return
  const row = currentSelectRow.value
  row.pallets = selectedPalletRows.value.map((pallet: any) => ({
    palletId: pallet.id,
    palletCode: pallet.code,
    packageCount: getPalletPackageCount(row, pallet),
    warehouseId: pallet.warehouseId,
    areaId: pallet.areaId,
    count: getSelectedPalletOutCountValue(pallet)
  }))
  row.palletCode = selectedPalletRows.value.map((pallet) => pallet.code).filter(Boolean).join(', ')
  syncInputCountByPallets(row)
  palletDialogVisible.value = false
}

const clearPallet = (row: any) => {
  if (props.disabled) return
  if (!row) return
  row.pallets = []
  row.palletCode = undefined
  row.palletCount = isProductStockOut.value ? undefined : row.palletCount
  row.packageCount = isProductStockOut.value ? undefined : row.packageCount
  row.pieceCount = isProductStockOut.value ? undefined : row.pieceCount
  row.inputCount = isProductStockOut.value ? undefined : row.inputCount
  row.count = isProductStockOut.value ? undefined : row.count
}

const getInitialSelectedPalletRows = (row: any) => {
  const palletCodes = String(row?.palletCode || '')
    .split(',')
    .map((item) => item.trim())
    .filter(Boolean)
  const packageQuantity = Number(row?.packageQuantity)
  return (row?.pallets || []).map((item: any, index: number) => ({
    id: item.palletId,
    code: item.palletCode || item.code || palletCodes[index] || String(item.palletId),
    packageCount:
      item.packageCount ??
      (Number.isFinite(packageQuantity) && Number.isFinite(Number(item.count))
        ? Number(item.count) / packageQuantity
        : undefined),
    warehouseId: item.warehouseId,
    areaId: item.areaId,
    count: item.count
  }))
}

const syncPalletDialogSelection = () => {
  const row = currentSelectRow.value
  if (!row || !palletTableRef.value) return
  const selectedIds = new Set((row.pallets || []).map((item: any) => item.palletId))
  palletTableRef.value.clearSelection()
  palletDialogList.value.forEach((pallet: any) => {
    if (selectedIds.has(pallet.id)) {
      palletTableRef.value.toggleRowSelection(pallet, true)
    }
  })
}

const getPalletAvailablePackageCount = (pallet: PalletVO) => {
  const packageCount = Number(pallet?.productCount)
  return Number.isFinite(packageCount) ? packageCount : 0
}

const handlePalletPackageCountChange = (value: number | undefined, pallet: any) => {
  const availablePackageCount = getPalletAvailablePackageCount(pallet)
  const packageCount = Number(value)
  if (!Number.isFinite(packageCount) || packageCount <= availablePackageCount) return
  pallet.packageCount = availablePackageCount
  message.warning(`出库包数不能大于包数，已自动调整为${availablePackageCount}`)
}

const getPalletOutCount = (pallet: any) => {
  const packageQuantity = Number(currentSelectRow.value?.packageQuantity)
  if (!Number.isFinite(packageQuantity)) return undefined
  const packageCount = getPalletPackageCount(currentSelectRow.value, pallet)
  return Number.isFinite(packageCount) ? packageQuantity * packageCount : undefined
}

const getSelectedPalletOutCountValue = (pallet: any) => {
  const packageQuantity = Number(currentSelectRow.value?.packageQuantity)
  const packageCount = Number(pallet?.packageCount)
  if (Number.isFinite(packageQuantity) && Number.isFinite(packageCount)) {
    return packageQuantity * packageCount
  }
  const currentCount = Number(pallet?.count)
  return Number.isFinite(currentCount) ? currentCount : undefined
}

const getSelectedPalletOutCount = (pallet: any) => {
  return getSelectedPalletOutCountValue(pallet) ?? '-'
}

const getPalletPackageCount = (row: any, pallet: any) => {
  const availablePackageCount = getPalletAvailablePackageCount(pallet)
  if (Number(row.outMode) === 1) {
    return availablePackageCount
  }
  const packageCount = Number(pallet.packageCount)
  if (!Number.isFinite(packageCount)) return 0
  return Math.min(Math.max(packageCount, 0), availablePackageCount)
}

const syncPalletPackageCounts = (row: any) => {
  if (!Array.isArray(row?.pallets)) return
  row.pallets = row.pallets.map((item: any) => {
    const pallet = currentSelectRow.value === row ? palletDialogList.value.find((p) => p.id === item.palletId) : undefined
    const packageCount = pallet ? getPalletPackageCount(row, pallet) : Number(item.packageCount ?? 0)
    return {
      ...item,
      packageCount
    }
  })
}

const syncInputCountByPallets = (row: any) => {
  if (!isProductStockOut.value || !Array.isArray(row?.pallets)) return
  const packageQuantity = Number(row.packageQuantity)
  if (!Number.isFinite(packageQuantity)) {
    row.packageCount = undefined
    row.pieceCount = undefined
    row.inputCount = undefined
    row.count = undefined
    return
  }
  const totalPackageCount = getSumValue(row.pallets.map((item: any) => Number(item.packageCount)))
  const pieceCount = totalPackageCount > 0 ? packageQuantity * totalPackageCount : undefined
  row.palletCount = row.pallets.length || undefined
  row.packageCount = totalPackageCount > 0 ? totalPackageCount : undefined
  row.pieceCount = pieceCount
  row.inputCount = pieceCount
  syncCountByInputCount(row)
}

const isRepairPurpose = (purpose: any) => String(purpose ?? '') === RELATED_PURPOSE_REPAIR
const isMaintainPurpose = (purpose: any) => String(purpose ?? '') === RELATED_PURPOSE_MAINTAIN

const isRelatedPurpose = (purpose: any) => {
  const value = String(purpose ?? '')
  return value === RELATED_PURPOSE_REPAIR || value === RELATED_PURPOSE_MAINTAIN
}

const clearRelatedOrder = (row: any) => {
  row.repairId = undefined
  row.repairDeviceId = undefined
  row.maintenanceId = undefined
  row.relatedOrderNo = undefined
  row.relatedOrderName = undefined
  row.relatedMaintenanceNo = undefined
  row.relatedMaintenanceName = undefined
  row.relatedOrderType = undefined
}

const handleOutboundPurposeChange = (row: any) => {
  if (props.disabled) return
  clearRelatedOrder(row)
}

const getOutboundPurposeLabel = (value: any) => {
  const currentValue = String(value ?? '')
  return outboundPurposeOptions.value.find((item) => String(item.value) === currentValue)?.label ?? '-'
}

const getOutModeLabel = (value: any) => {
  if (Number(value) === 1) return t('ErpStock.Item.outModeWholePallet')
  if (Number(value) === 2) return t('ErpStock.Item.outModeSplitPallet')
  return '-'
}

const getRelatedOrderPlaceholder = (purpose: any) => {
  return String(purpose ?? '') === RELATED_PURPOSE_REPAIR
    ? t('ErpStock.Item.placeholderRelatedRepairOrder')
    : t('ErpStock.Item.placeholderRelatedMaintainRecord')
}

const openRelatedOrderDialog = async (row: any) => {
  if (props.disabled) return
  const purpose = String(row.outUsageType ?? '')
  if (!isRelatedPurpose(purpose)) return
  currentRelatedRow.value = row
  relatedOrderType.value = purpose === RELATED_PURPOSE_REPAIR ? 'repair' : 'maintain'
  selectedRelatedOrderId.value =
    relatedOrderType.value === 'repair' ? row.repairId : row.maintenanceId
  relatedOrderQueryParams.pageNo = 1
  relatedOrderDialogVisible.value = true
  await getRelatedOrderList()
}

const getRelatedOrderList = async () => {
  relatedOrderLoading.value = true
  try {
    if (relatedOrderType.value === 'repair') {
      const data = await DvRepairApi.getDvRepairPage(relatedOrderQueryParams)
      relatedOrderList.value = data?.list || []
      relatedOrderTotal.value = data?.total || 0
      return
    }
    const data = await TicketManagementApi.getTicketManagementPage({
      ...relatedOrderQueryParams,
      planType: 2
    })
    relatedOrderList.value = data?.list || []
    relatedOrderTotal.value = data?.total || 0
  } finally {
    relatedOrderLoading.value = false
  }
}

const handleRelatedOrderRowClick = (row: any) => {
  selectedRelatedOrderId.value = row.id
}

const confirmRelatedOrderSelect = () => {
  const selected = relatedOrderList.value.find((item) => item.id === selectedRelatedOrderId.value)
  if (!selected || !currentRelatedRow.value) return
  if (relatedOrderType.value === 'repair') {
    currentRelatedRow.value.repairId = selected.id
    currentRelatedRow.value.repairDeviceId = selected.machineryId
    currentRelatedRow.value.relatedOrderNo = selected.repairCode
    currentRelatedRow.value.relatedOrderName = selected.repairName
  } else {
    currentRelatedRow.value.maintenanceId = selected.id
    currentRelatedRow.value.relatedMaintenanceNo = selected.planNo
    currentRelatedRow.value.relatedMaintenanceName = selected.configName
  }
  currentRelatedRow.value.relatedOrderType = relatedOrderType.value
  relatedOrderDialogVisible.value = false
}

const getRepairStatusLabel = (value: any) => {
  const v = value === '' || value === null || value === undefined ? undefined : String(value)
  if (v === '0') return t('EquipmentManagement.DvRepair.statusPending')
  if (v === '1') return t('EquipmentManagement.DvRepair.statusFinished')
  return '-'
}

const getRepairStatusTagType = (value: any) => {
  const v = value === '' || value === null || value === undefined ? undefined : String(value)
  if (v === '1') return 'success'
  if (v === '0') return 'warning'
  return 'info'
}

const getRepairResultLabel = (value: any) => {
  const v = value === '' || value === null || value === undefined ? undefined : String(value)
  if (v == '0') return t('EquipmentManagement.DvRepair.repairResultPending')
  if (v == '1') return t('EquipmentManagement.DvRepair.repairResultOk')
  if (v == '2') return t('EquipmentManagement.DvRepair.repairResultNg')
  return '-'
}

const getRepairResultTagType = (value: any) => {
  const v = value === '' || value === null || value === undefined ? undefined : String(value)
  if (v == '1') return 'success'
  if (v == '2') return 'danger'
  if (v == '0') return 'info'
  return 'info'
}

watch(
  () => formData.value.map((row) => row.inputCount),
  () => {
    if (!isProductMaterialStockOut.value) return
    formData.value.forEach((row) => {
      syncCountByInputCount(row)
      if (isProductStockOut.value && Number(row.outMode) === 2) {
        syncPalletPackageCounts(row)
      }
    })
  },
  { deep: true }
)

const toIntegerCount = (value: any) => {
  const count = Number(value)
  return Number.isFinite(count) ? Math.trunc(count) : undefined
}

const syncCountByInputCount = (row: any) => {
  if (!isProductMaterialStockOut.value) return
  const inputCount = toIntegerCount(row.inputCount)
  if (inputCount === undefined) {
    row.count = undefined
    return
  }
  row.inputCount = inputCount
  row.count = inputCount
}

const handleInputCountBlur = (row: any) => {
  if (!isProductMaterialStockOut.value) return
  const inputCount = toIntegerCount(row.inputCount)
  const stockCount = Number(row.stockCount)
  if (inputCount === undefined || !Number.isFinite(stockCount)) return
  row.inputCount = inputCount
  if (inputCount <= stockCount) {
    syncCountByInputCount(row)
    syncPalletPackageCounts(row)
    return
  }
  row.inputCount = Math.trunc(stockCount)
  syncCountByInputCount(row)
  syncPalletPackageCounts(row)
  message.warning(t('ErpStock.Item.stockCountExceededWarning'))
}

const loadWarehouseAreas = async (warehouseId: number) => {
  if (!warehouseId || warehouseAreaMap.value[warehouseId]) return
  const data = await WarehouseAreaApi.getWarehouseAreaPage({
    pageNo: 1,
    pageSize: 100,
    warehouseId
  })
  warehouseAreaMap.value = {
    ...warehouseAreaMap.value,
    [warehouseId]: data?.list || []
  }
}

const loadRowsWarehouseAreas = async (rows: any[]) => {
  const warehouseIds = Array.from(new Set((rows || []).map((row) => row.warehouseId).filter(Boolean)))
  await Promise.all(warehouseIds.map((warehouseId) => loadWarehouseAreas(warehouseId)))
}

const getAreaOptions = (warehouseId: number) => {
  return warehouseId ? warehouseAreaMap.value[warehouseId] || [] : []
}

const getAreaLabel = (item: WarehouseAreaVO) => {
  return item.areaCode ? `${item.areaCode} - ${item.areaName}` : item.areaName
}

const getWarehouseName = (warehouseId: number | string | undefined) => {
  return warehouseList.value.find((item) => String(item.id) === String(warehouseId))?.name ?? warehouseId ?? '-'
}

const getAreaName = (areaId: number | string | undefined) => {
  const areaList = Object.values(warehouseAreaMap.value).flat()
  return areaList.find((item) => String(item.id) === String(areaId))?.areaName ?? areaId ?? '-'
}

const fillProductNames = (rows: any[]) => {
  if (!productList.value.length) return
  rows.forEach((row) => {
    const product = productList.value.find((item) => item.id === row.productId || item.barCode === row.productBarCode)
    if (!product) return
    row.productId = row.productId || product.id
    row.productBarCode = row.productBarCode || product.barCode
    row.productName = row.productName || product.name
    row.productUnitName = row.productUnitName || product.unitName
    row.productPrice = row.productPrice ?? product.minPrice
    row.purchaseUnitId = row.purchaseUnitId ?? (product as any).purchaseUnitId
    row.purchaseUnitName = row.purchaseUnitName ?? (product as any).purchaseUnitName
    row.supplierName = row.supplierName ?? getDefaultSupplierName(product)
    row.purchaseUnitConvertQuantity = row.purchaseUnitConvertQuantity ?? (product as any).purchaseUnitConvertQuantity
    if (row.packageQuantity == null) {
      fillPackagingSchemeByProduct(row, product)
    }
    syncCountByInputCount(row)
  })
}

/** 加载库存 */
const setStockCount = async (row) => {
  if (!row.productId || !row.warehouseId) {
    return
  }
  const stock = await StockApi.getStock2(row.productId, row.warehouseId, row.areaId)
  row.stockCount = stock ? stock.count : 0
}

/** 表单校验 */
const validate = () => {
  formData.value.forEach((row) => {
    syncPalletPackageCounts(row)
    syncInputCountByPallets(row)
    syncCountByInputCount(row)
  })
  return formRef.value.validate()
}

const resetItems = () => {
  formData.value.splice(0, formData.value.length)
  if (!props.disabled) {
    handleAdd()
  }
}

defineExpose({ validate, resetItems })


/** 初始化 */
onMounted(async () => {
  productList.value = await ProductApi.getProductSimpleList()
  await loadWarehouseList()
  fillProductNames(formData.value)
  if (isProductMaterialStockOut.value) {
    await loadRowsWarehouseAreas(formData.value)
  }
  // 默认添加一个
  if (formData.value.length === 0) {
    handleAdd()
  }
})


</script>
<style scoped lang="scss">
.product-code-select {
  width: 100%;

  :deep(.el-input__wrapper) {
    cursor: pointer;
  }
}

.out-mode-radio-group {
  width: 100%;
  justify-content: space-around;
}

.product-dialog-pagination {
  display: flex;
  justify-content: flex-end;
  padding: 12px 0 0;
}
</style>
