<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" class="-mt-10px">
      <el-table-column :label="t('common.index')" type="index" align="center" width="60" />
      <el-table-column v-if="!isProductStockIn" :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="isProductMaterialStockIn && !isProductStockIn" :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="setStockCount(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 v-if="isProductStockIn" :label="t('ErpStock.Item.relatedTask')" min-width="120">
        <template #default="{ row }">
          <el-input v-if="disabled" :model-value="formatRelatedTask(row)" readonly />
          <el-select v-else v-model="row.relateTask" :placeholder="t('common.selectText')" @change="handleRelatedTaskChange(row)">
            <el-option :label="t('common.yes')" :value="true" />
            <el-option :label="t('common.no')" :value="false" />
          </el-select>
        </template>
      </el-table-column>
      <el-table-column :label="isProductStockIn ? selectorColumnLabel : t('ErpStock.Item.barcode')" min-width="190">
        <!--        <template #default="{ row }">
                  <el-form-item class="mb-0px!">
                    <el-input disabled v-model="row.productBarCode" />
                  </el-form-item>
        </template>-->
        <template #default="{ row, $index }">
          <div v-if="isProductStockIn && isRowRelatedTask(row)" class="task-product-select">
            <el-form-item :prop="`${$index}.taskId`" :rules="formRules.taskId" class="mb-0px!">
              <el-input
                :model-value="formatTaskSelection(row)"
                readonly
                :clearable="!disabled"
                :placeholder="t('ErpStock.Item.placeholderTaskOrder')"
                @click="handleTaskInputClick(row)"
                @clear="clearTask(row)"
              />
            </el-form-item>
          </div>
          <el-form-item v-else :prop="`${$index}.productId`" :rules="formRules.productId" 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 v-if="isProductStockIn" :label="t('ErpStock.Item.productName')" min-width="150">
        <template #default="{ row }">
          <el-input :model-value="row.productName || '-'" readonly />
        </template>
      </el-table-column>
      <el-table-column v-if="isProductStockIn" :label="t('ErpStock.Item.packagingScheme')" min-width="150">
        <template #default="{ row }">
          <el-input :model-value="row.packagingSchemeName || '-'" readonly />
        </template>
      </el-table-column>
      <el-table-column v-if="isProductStockIn" :label="t('ErpStock.PackagingScheme.palletPackageQuantity')" min-width="120">
        <template #default="{ row }">
          <el-input :model-value="row.palletPackageQuantity ?? '-'" readonly />
        </template>
      </el-table-column>
      <el-table-column v-if="isProductStockIn" :label="t('ErpStock.Item.packageItemCount')" min-width="120">
        <template #default="{ row }">
          <el-input :model-value="row.packageQuantity ?? '-'" readonly />
        </template>
      </el-table-column>
      <el-table-column v-if="isProductStockIn" :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="isPurchaseUnitStockIn" :label="t('ErpStock.Item.inventoryUnit')" min-width="80">
        <template #default="{ row }">
          <el-form-item class="mb-0px!">
            <el-input readonly v-model="row.productUnitName" />
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="isPurchaseUnitStockIn" :label="t('ErpStock.Item.purchaseUnit')" min-width="100">
        <template #default="{ row }">
          <el-form-item class="mb-0px!">
            <el-input readonly v-model="row.purchaseUnitName" />
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="isPurchaseUnitStockIn" :label="t('ErpStock.Item.defaultSupplier')" min-width="130">
        <template #default="{ row }">
          <el-form-item class="mb-0px!">
            <el-input readonly v-model="row.supplierName" />
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="isPurchaseUnitStockIn" 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 readonly v-model="row.purchaseUnitConvertQuantity" />
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="isPurchaseUnitStockIn" :label="t('ErpStock.Item.inPackageCount')" prop="packageCount" min-width="140">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${$index}.packageCount`" :rules="formRules.packageCount" class="mb-0px!">
            <el-input v-if="disabled" :model-value="row.packageCount ?? '-'" readonly />
            <el-input-number v-else v-model="row.packageCount" controls-position="right" :min="0.001" :precision="3" class="!w-100%" />
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column v-if="!isProductStockIn" :label="isPurchaseUnitStockIn ? t('ErpStock.Item.inItemCount') : t('ErpStock.Item.count')" prop="count" min-width="140">
        <template #default="{ row, $index }">
          <el-form-item :prop="`${$index}.count`" :rules="formRules.count" class="mb-0px!">
            <el-input v-if="disabled || isPurchaseUnitStockIn" :model-value="row.count ?? '-'" readonly />
            <el-input-number v-else v-model="row.count" controls-position="right" :min="0.001" :precision="3" class="!w-100%" />
          </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.In.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.In.addItem') }}</el-button>
  </el-row>

  <Dialog :title="t('ErpStock.Item.selectProduct')" 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="isPurchaseUnitStockIn" :label="t('ErpStock.Item.purchaseUnit')" prop="purchaseUnitName" min-width="100" />
      <el-table-column v-if="isPurchaseUnitStockIn" :label="t('ErpStock.Item.defaultSupplier')" min-width="130">
        <template #default="{ row }">
          {{ getDefaultSupplierName(row) || '-' }}
        </template>
      </el-table-column>
      <el-table-column v-if="isPurchaseUnitStockIn" :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.selectTaskOrder')" v-model="taskDialogVisible" width="1100px">
    <div class="task-select-dialog">
      <div class="task-select-dialog__section-title">{{ t('ErpStock.Item.selectTaskOrder') }}</div>
    <el-form :model="taskQueryParams" :inline="true" class="-mb-15px">
      <el-form-item :label="t('ProductionPlan.Task.searchCodeLabel')">
        <el-input
          v-model="taskQueryParams.code"
          clearable
          :placeholder="t('ProductionPlan.Task.searchCodePlaceholder')"
          @keyup.enter="handleTaskDialogQuery"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleTaskDialogQuery">
          <Icon icon="ep:search" class="mr-5px" /> {{ t('common.query') }}
        </el-button>
      </el-form-item>
    </el-form>
    <el-table
      v-loading="taskDialogLoading"
      :data="taskDialogList"
      row-key="id"
      :stripe="true"
      :show-overflow-tooltip="true"
      @row-click="handleTaskDialogRowClick"
    >
      <el-table-column width="55" align="center">
        <template #default="{ row }">
          <el-radio v-model="selectedTaskId" :label="row.id">&nbsp;</el-radio>
        </template>
      </el-table-column>
      <el-table-column :label="t('ProductionPlan.Task.tableCodeColumn')" prop="code" min-width="160" />
      <el-table-column :label="t('ProductionPlan.Task.tableOrderDateColumn')" prop="orderDate" :formatter="dateFormatter2" min-width="120" />
      <el-table-column :label="t('ProductionPlan.Task.tableDeliveryDateColumn')" prop="deliveryDate" :formatter="dateFormatter2" min-width="120" />
      <el-table-column :label="t('ProductionPlan.Task.tableStatusColumn')" prop="status" min-width="100">
        <template #default="{ row }">
          <dict-tag :type="DICT_TYPE.MES_TASK_STATUS" :value="row.status" />
        </template>
      </el-table-column>
      <el-table-column :label="t('ProductionPlan.Task.tableRemarkColumn')" prop="remark" min-width="160" />
    </el-table>
    <div class="product-dialog-pagination">
      <Pagination
        :total="taskDialogTotal"
        v-model:page="taskQueryParams.pageNo"
        v-model:limit="taskQueryParams.pageSize"
        @pagination="getTaskDialogList"
      />
    </div>
      <div class="task-select-dialog__section-title mt-12px">{{ t('ErpStock.Item.selectProduct') }}</div>
      <el-table
        v-loading="taskSchemeLoading"
        :data="taskProductDialogList"
        row-key="productId"
        :stripe="true"
        :show-overflow-tooltip="true"
        empty-text="请先选择任务单"
        @row-click="handleTaskProductDialogRowClick"
      >
        <el-table-column width="55" align="center">
          <template #default="{ row }">
            <el-radio v-model="selectedTaskProductId" :label="row.productId">&nbsp;</el-radio>
          </template>
        </el-table-column>
        <el-table-column :label="t('ErpStock.Item.code')" prop="productCode" min-width="180" />
        <el-table-column :label="t('ErpStock.Item.productName')" prop="productName" min-width="160" />
        <el-table-column :label="t('ErpStock.Item.packagingScheme')" min-width="160">
          <template #default="{ row }">
            {{ getDefaultTaskProductScheme(row)?.packagingSchemeName || '-' }}
          </template>
        </el-table-column>
        <el-table-column :label="t('ErpStock.PackagingScheme.palletPackageQuantity')" min-width="120">
          <template #default="{ row }">
            {{ getDefaultTaskProductScheme(row)?.palletPackageQuantity ?? '-' }}
          </template>
        </el-table-column>
        <el-table-column :label="t('ErpStock.Item.packageItemCount')" min-width="120">
          <template #default="{ row }">
            {{ getDefaultTaskProductScheme(row)?.packageQuantity ?? '-' }}
          </template>
        </el-table-column>
      </el-table>
    </div>
    <template #footer>
      <el-button type="primary" :loading="taskSchemeLoading" :disabled="!selectedTaskId || !selectedTaskProductId" @click="confirmTaskSelect">{{ t('common.ok') }}</el-button>
      <el-button @click="taskDialogVisible = false">{{ t('common.cancel') }}</el-button>
    </template>
  </Dialog>

  <Dialog :title="t('ErpStock.Item.selectPalletCode')" v-model="palletDialogVisible" :width="disabled ? '900px' : '1800px'">
    <component :is="palletDialogGuardTag" v-bind="disabled ? formEnabledAttrs : {}">
      <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-button type="primary" plain @click="openPalletCreateForm">
            <Icon icon="ep:plus" class="mr-5px" /> {{ t('action.add') }}
          </el-button>
        </el-form-item>
      </el-form>
      <div class="pallet-transfer" :class="{ 'pallet-transfer--readonly': disabled }">
        <div v-if="!disabled" class="pallet-transfer__panel">
          <div class="pallet-transfer__title">{{ t('ErpStock.Item.availablePallets') }}</div>
          <el-table
            ref="availablePalletTableRef"
            v-loading="palletDialogLoading"
            :data="availablePalletList"
            row-key="id"
            height="340"
            :stripe="true"
            :show-overflow-tooltip="true"
            @selection-change="handleAvailablePalletSelectionChange"
            @row-click="toggleAvailablePallet"
          >
            <el-table-column type="selection" width="55" align="center" />
            <el-table-column :label="t('ErpStock.Pallet.code')" prop="code" min-width="120" />
            <el-table-column :label="t('ErpStock.Pallet.palletType')" prop="palletType" min-width="80">
              <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="80">
              <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.productName')" min-width="130" prop="productName"/>
            <el-table-column :label="t('ErpStock.Item.area')" min-width="130">
              <template #default="{ row }">
                {{ getAreaName(row.areaId) }}
              </template>
            </el-table-column>
          </el-table>
          <div class="product-dialog-pagination">
            <Pagination
              :total="palletDialogTotal"
              v-model:page="palletQueryParams.pageNo"
              v-model:limit="palletQueryParams.pageSize"
              @pagination="getPalletDialogList"
            />
          </div>
        </div>
        <div v-if="!disabled" class="pallet-transfer__actions">
          <el-button type="primary" :disabled="availablePalletSelection.length === 0" @click="addSelectedPallets">
            <Icon icon="ep:arrow-right" />
          </el-button>
          <el-button :disabled="rightPalletSelection.length === 0" @click="removeSelectedPallets">
            <Icon icon="ep:arrow-left" />
          </el-button>
        </div>
        <div class="pallet-transfer__panel">
          <div class="pallet-transfer__title">{{ t('ErpStock.Item.selectedPallets') }}</div>
          <el-table
            ref="rightPalletTableRef"
            :data="selectedPalletRows"
            row-key="id"
            height="340"
            :stripe="true"
            :show-overflow-tooltip="true"
            @selection-change="handleRightPalletSelectionChange"
            @row-click="handleRightPalletRowClick"
          >
            <el-table-column v-if="!disabled" type="selection" width="55" align="center" />
            <el-table-column :label="t('ErpStock.Pallet.code')" prop="code" min-width="150" />
            <el-table-column :label="t('ErpStock.Item.warehouse')" min-width="160">
              <template #default="{ row }">
                <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="handleSelectedPalletWarehouseChange($event, row)"
                  @click.stop
                >
                  <el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column :label="t('ErpStock.Item.area')" min-width="160">
              <template #default="{ row }">
                <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"
                  @click.stop
                >
                  <el-option v-for="item in getAreaOptions(row.warehouseId)" :key="item.id" :label="getAreaLabel(item)" :value="item.id" />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column :label="selectedPalletPackageCountLabel" min-width="160">
              <template #default="{ row }">
                <el-input v-if="disabled" :model-value="row.packageCount ?? '-'" readonly />
                <el-input-number
                  v-else
                  v-model="row.packageCount"
                  controls-position="right"
                  :min="0"
                  :precision="3"
                  class="!w-100%"
                  @click.stop
                />
              </template>
            </el-table-column>
            <el-table-column :label="t('ErpStock.Item.itemCount')" min-width="130">
              <template #default="{ row }">
                <el-input :model-value="getSelectedPalletItemCount(row)" readonly />
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </component>
    <template #footer>
      <component :is="palletDialogGuardTag" v-bind="disabled ? formEnabledAttrs : {}">
        <el-button v-if="!disabled" type="primary" @click="confirmPalletSelect">{{ t('common.ok') }}</el-button>
        <el-button @click="palletDialogVisible = false">{{ t('common.cancel') }}</el-button>
      </component>
    </template>
  </Dialog>

  <PalletForm ref="palletFormRef" @success="handlePalletCreateSuccess" />
</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 { TaskApi, TaskVO } from '@/api/mes/task'
import { PalletApi, PalletVO } from '@/api/erp/stock/pallet'
import PalletForm from '../../pallet/PalletForm.vue'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter2 } from '@/utils/formatTime'
import { erpPriceMultiply } from '@/utils'

const props = defineProps<{
  items: any[] | undefined
  inType?: string
  disabled: boolean
}>()
const formLoading = ref(false) // 表单的加载中
const formData = ref([])
const { t } = useI18n()
const formRules = reactive({
  warehouseId: [{ required: true, message: t('ErpStock.Item.validatorWarehouseRequired'), trigger: 'blur' }],
  areaId: [{ required: true, message: t('ErpStock.Item.placeholderArea'), trigger: 'change' }],
  productId: [{ required: true, message: t('ErpStock.Item.validatorProductRequired'), trigger: 'blur' }],
  taskId: [{ required: true, message: t('ErpStock.Item.validatorTaskRequired'), trigger: 'change' }],
  pallets: [{ validator: validatePallets, trigger: 'change' }],
  packageCount: [{ required: true, message: t('ErpStock.Item.validatorPackageCountRequired'), 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 stockInCategoryTypeMap: Record<string, number> = {
  产品入库: 1,
  物料入库: 2,
  备件入库: 3
}
const activeCategoryType = computed(() => stockInCategoryTypeMap[props.inType || ''])
const isProductMaterialStockIn = computed(() => Boolean(activeCategoryType.value))
const isProductStockIn = computed(() => activeCategoryType.value === 1)
const isPurchaseUnitStockIn = computed(() => activeCategoryType.value === 2 || activeCategoryType.value === 3)
const purchaseUnitConvertTipText = computed(() => t('FactoryModeling.ProductInformation.dialogPurchaseUnitConvertTip'))
const selectorColumnLabel = computed(() => {
  const rows = formData.value || []
  return rows.length > 0 && rows.every((row) => isRowRelatedTask(row))
    ? `${t('ErpStock.Item.taskOrder')}/${t('ErpStock.Item.selectProduct')}`
    : t('ErpStock.Item.selectProduct')
})
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 taskDialogVisible = ref(false)
const taskDialogLoading = ref(false)
const taskSchemeLoading = ref(false)
const taskDialogList = ref<TaskVO[]>([])
const taskDialogTotal = ref(0)
const taskQueryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  code: undefined
})
const selectedTaskId = ref<number>()
const selectedTaskProductId = ref<number>()
const taskProductDialogList = ref<any[]>([])
const selectedTaskData = ref<any>()
const palletDialogVisible = ref(false)
const palletDialogLoading = ref(false)
const palletDialogList = ref<PalletVO[]>([])
const palletDialogTotal = ref(0)
const palletQueryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  code: undefined,
  status: undefined,
  productId: undefined,
  excludeStatus: 3
})
const availablePalletSelection = ref<PalletVO[]>([])
const rightPalletSelection = ref<any[]>([])
const selectedPalletRows = ref<any[]>([])
const availablePalletTableRef = ref()
const rightPalletTableRef = ref()
const palletFormRef = ref()
const palletStatusOptions = computed(() =>
  getIntDictOptions(DICT_TYPE.STORAGE_PALLET_STATUS).filter((dict) => Number(dict.value) !== 3)
)
const availablePalletList = computed(() => {
  const selectedIds = new Set(selectedPalletRows.value.map((item) => item.id))
  return palletDialogList.value.filter((item) => !selectedIds.has(item.id))
})
const selectedPalletPackageCountLabel = computed(() => {
  const packageQuantity = currentSelectRow.value?.packageQuantity ?? '-'
  return t('ErpStock.Item.packageCountWithItems', { count: packageQuantity })
})
const formEnabledAttrs = { disabled: false, labelWidth: '0px' }
const palletDialogGuardTag = computed(() => (props.disabled ? 'el-form' : 'div'))

function validatePallets(_: any, value: any[], callback: (error?: Error) => void) {
  if (!Array.isArray(value) || value.length === 0) {
    callback(new Error(t('ErpStock.Item.validatorPalletRequired')))
    return
  }
  const hasEmptyPackageCount = value.some((item) => !Number.isFinite(Number(item?.packageCount)) || Number(item?.packageCount) <= 0)
  callback(hasEmptyPackageCount ? new Error(t('ErpStock.Item.validatorPackageCountRequired')) : undefined)
}

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)
    fillProductNames(formData.value)
    if (isProductMaterialStockIn.value) {
      await loadRowsWarehouseAreas(formData.value)
    }
  },
  { immediate: true }
)

const normalizeRows = (rows: any[]) => {
  ;(rows || []).forEach((row) => {
    if (row.relateTask === undefined) {
      row.relateTask = row.relatedTask ?? false
    }
    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).filter(Boolean).join(', ')
    }
  })
}

watch(
  () => props.inType,
  async () => {
    await loadWarehouseList()
    if (isProductMaterialStockIn.value) {
      formData.value.forEach((row) => {
        normalizePackageCount(row)
        if (isProductStockIn.value) {
          row.inputUnitType = row.inputUnitType || '个'
        }
        syncCountByPackageCount(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 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,
    relateTask: false,
    taskId: undefined,
    taskCode: undefined,
    taskName: undefined,
    taskDetailIds: undefined,
    packagingSchemeRelationId: undefined,
    packagingSchemeId: undefined,
    packagingSchemeName: undefined,
    packageQuantity: undefined,
    palletPackageQuantity: undefined,
    palletTotalQuantity: undefined,
    pallets: [],
    palletCode: undefined,
    inputUnitType: isProductStockIn.value ? '个' : undefined,
    inputCount: undefined,
    packageCount: isPurchaseUnitStockIn.value ? 1 : undefined,
    stockCount: undefined,
    count: isProductMaterialStockIn.value ? undefined : 1,
    totalPrice: undefined,
    remark: undefined
  }
  syncCountByPackageCount(row)
  formData.value.push(row)
  if (row.warehouseId && isProductMaterialStockIn.value) {
    loadWarehouseAreas(row.warehouseId)
  }
}

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

const isRowRelatedTask = (row: any) => {
  if (row?.relateTask !== undefined) {
    return row.relateTask === true || row.relateTask === 1 || row.relateTask === '1'
  }
  return row?.relatedTask === true || row?.relatedTask === 1 || row?.relatedTask === '1'
}

const formatRelatedTask = (row: any) => {
  return isRowRelatedTask(row) ? t('common.yes') : t('common.no')
}

const handleRelatedTaskChange = (row: any) => {
  row.relatedTask = undefined
  if (isRowRelatedTask(row)) {
    clearProduct(row)
    clearPallet(row)
    row.count = undefined
    row.inputCount = undefined
    return
  }
  clearTask(row)
  clearPallet(row)
  row.count = isProductMaterialStockIn.value ? undefined : 1
  row.inputCount = undefined
  row.packageCount = isPurchaseUnitStockIn.value ? 1 : undefined
  syncCountByPackageCount(row)
}

/** 处理产品变更 */
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
  if (warehouseId && isProductMaterialStockIn.value) {
    loadWarehouseAreas(warehouseId)
  }
  // 加载库存
  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.productCode = 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)
  normalizePackageCount(row)
  syncCountByPackageCount(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
  row.palletPackageQuantity = scheme?.palletPackageQuantity
  row.palletTotalQuantity = scheme?.palletTotalQuantity
}

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 clearProduct = (row: any) => {
  row.productUnitName = undefined
  row.productBarCode = undefined
  row.productCode = 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.inputCount = isProductMaterialStockIn.value ? undefined : row.inputCount
  row.packageCount = isPurchaseUnitStockIn.value ? undefined : row.packageCount
  row.count = isProductMaterialStockIn.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 () => {
  if (props.disabled) return
  const product = productDialogList.value.find((item) => item.id === selectedProductId.value)
  if (!product || !currentSelectRow.value) return
  let finalProduct = product
  if (!Array.isArray(product.packagingSchemes)) {
    finalProduct = await ProductApi.getProduct(product.id)
  }
  fillRowByProduct(currentSelectRow.value, finalProduct)
  clearPallet(currentSelectRow.value)
  setStockCount(currentSelectRow.value)
  productDialogVisible.value = false
}

const openTaskSelectDialog = async (row: any) => {
  currentSelectRow.value = row
  selectedTaskId.value = row.taskId
  selectedTaskProductId.value = row.productId
  selectedTaskData.value = undefined
  taskProductDialogList.value = getTaskProductOptions(row)
  taskQueryParams.pageNo = 1
  taskQueryParams.code = undefined
  taskDialogVisible.value = true
  await getTaskDialogList()
  if (row.taskId) {
    await loadTaskProductDialogList({ id: row.taskId, code: row.taskCode } as TaskVO)
  }
}

const handleTaskInputClick = (row: any) => {
  if (props.disabled) return
  openTaskSelectDialog(row)
}

const getTaskDialogList = async () => {
  taskDialogLoading.value = true
  try {
    const data = await TaskApi.getTaskPage(taskQueryParams)
    taskDialogList.value = data?.list || []
    taskDialogTotal.value = data?.total || 0
  } finally {
    taskDialogLoading.value = false
  }
}

const handleTaskDialogQuery = () => {
  taskQueryParams.pageNo = 1
  selectedTaskId.value = undefined
  selectedTaskProductId.value = undefined
  selectedTaskData.value = undefined
  taskProductDialogList.value = []
  getTaskDialogList()
}

const handleTaskDialogRowClick = async (row: TaskVO) => {
  selectedTaskId.value = row.id
  selectedTaskProductId.value = undefined
  await loadTaskProductDialogList(row)
}

const confirmTaskSelect = async () => {
  if (props.disabled) return
  const task = taskDialogList.value.find((item) => item.id === selectedTaskId.value)
    || ({ id: selectedTaskData.value?.taskId, code: selectedTaskData.value?.taskName } as TaskVO)
  const product = taskProductDialogList.value.find((item) => item.productId === selectedTaskProductId.value)
  const data = selectedTaskData.value
  if (!task || !product || !data || !currentSelectRow.value) return
  fillRowByTask(currentSelectRow.value, task, data)
  fillRowByTaskProduct(currentSelectRow.value, product)
  taskDialogVisible.value = false
}

const loadTaskProductDialogList = async (task: TaskVO) => {
  taskSchemeLoading.value = true
  try {
    const data = await TaskApi.getTaskDefaultPackagingSchemes(task.id)
    selectedTaskData.value = data
    taskProductDialogList.value = Array.isArray(data?.products) ? data.products : []
  } finally {
    taskSchemeLoading.value = false
  }
}

const handleTaskProductDialogRowClick = (row: any) => {
  selectedTaskProductId.value = row.productId
}

const fillRowByTask = (row: any, task: TaskVO, data: any) => {
  const products = Array.isArray(data?.products) ? data.products : []
  row.relateTask = true
  row.relatedTask = undefined
  row.taskId = data?.taskId ?? task.id
  row.taskCode = data?.taskName ?? task.code
  row.taskName = data?.taskName ?? task.code
  setTaskProductOptions(row, products)
  clearTaskProduct(row)
  clearPallet(row)
}

const getTaskProductOptions = (row: any) => {
  return Array.isArray(row?.taskProducts) ? row.taskProducts : []
}

const formatTaskSelection = (row: any) => {
  return [row.taskCode, row.productName].filter(Boolean).join(' / ')
}

const setTaskProductOptions = (row: any, products: any[]) => {
  Object.defineProperty(row, 'taskProducts', {
    value: products,
    writable: true,
    configurable: true,
    enumerable: false
  })
}

const getDefaultTaskProductScheme = (product: any) => {
  const schemes = Array.isArray(product?.packagingSchemes) ? product.packagingSchemes : []
  return schemes.find((item: any) => Number(item?.defaultStatus) === 1) || schemes[0]
}

const fillRowByTaskProduct = (row: any, product: any) => {
  const scheme = getDefaultTaskProductScheme(product)

  row.productId = product?.productId
  row.productCode = product?.productCode
  row.productName = product?.productName
  row.productBarCode = product?.productCode
  row.taskDetailIds = product?.taskDetailIds
  row.packagingSchemeRelationId = scheme?.id
  row.packagingSchemeId = scheme?.packagingSchemeId
  row.packagingSchemeName = scheme?.packagingSchemeName
  row.packageQuantity = scheme?.packageQuantity
  row.palletPackageQuantity = scheme?.palletPackageQuantity
  row.palletTotalQuantity = scheme?.palletTotalQuantity
  row.inputCount = scheme?.palletPackageQuantity
  row.count = scheme?.palletTotalQuantity
  clearPallet(row)
}

const clearTaskProduct = (row: any) => {
  row.productId = undefined
  row.productCode = undefined
  row.productName = undefined
  row.productBarCode = undefined
  row.taskDetailIds = undefined
  row.packagingSchemeRelationId = undefined
  row.packagingSchemeId = undefined
  row.packagingSchemeName = undefined
  row.packageQuantity = undefined
  row.palletPackageQuantity = undefined
  row.palletTotalQuantity = undefined
  row.inputCount = undefined
  row.count = undefined
}

const clearTask = (row: any) => {
  if (props.disabled) return
  row.taskId = undefined
  row.taskCode = undefined
  row.taskName = undefined
  setTaskProductOptions(row, [])
  clearTaskProduct(row)
}

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

const getPalletDialogList = async () => {
  palletDialogLoading.value = true
  try {
    const data = await PalletApi.getPalletPage(palletQueryParams)
    palletDialogList.value = data?.list || []
    palletDialogTotal.value = data?.total || 0
    await loadRowsWarehouseAreas(palletDialogList.value)
    availablePalletSelection.value = []
    availablePalletTableRef.value?.clearSelection()
  } finally {
    palletDialogLoading.value = false
  }
}

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

const openPalletCreateForm = () => {
  if (props.disabled) return
  const row = currentSelectRow.value
  palletFormRef.value?.open('create', undefined, {
    productId: row?.productId,
    productCount: row?.palletPackageQuantity
  })
}

const handlePalletCreateSuccess = async () => {
  palletQueryParams.pageNo = 1
  await getPalletDialogList()
}

const handleAvailablePalletSelectionChange = (rows: PalletVO[]) => {
  availablePalletSelection.value = rows
}

const handleRightPalletSelectionChange = (rows: any[]) => {
  rightPalletSelection.value = rows
}

const toggleAvailablePallet = (row: PalletVO) => {
  if (props.disabled) return
  availablePalletTableRef.value?.toggleRowSelection(row)
}

const toggleRightPallet = (row: any) => {
  if (props.disabled) return
  rightPalletTableRef.value?.toggleRowSelection(row)
}

const handleRightPalletRowClick = (row: any) => {
  if (props.disabled) return
  toggleRightPallet(row)
}

const handleSelectedPalletWarehouseChange = (warehouseId: number, row: any) => {
  if (props.disabled) return
  row.areaId = undefined
  if (warehouseId) {
    loadWarehouseAreas(warehouseId)
  }
}

const addSelectedPallets = () => {
  if (props.disabled) return
  const row = currentSelectRow.value
  const selectedIds = new Set(selectedPalletRows.value.map((item) => item.id))
  const nextRows = availablePalletSelection.value
    .filter((pallet) => !selectedIds.has(pallet.id))
    .map((pallet) => ({
      ...pallet,
      packageCount: getPalletPackageCount(row, pallet)
    }))
  selectedPalletRows.value = [...selectedPalletRows.value, ...nextRows]
  availablePalletSelection.value = []
  availablePalletTableRef.value?.clearSelection()
}

const removeSelectedPallets = () => {
  if (props.disabled) return
  const removeIds = new Set(rightPalletSelection.value.map((item) => item.id))
  selectedPalletRows.value = selectedPalletRows.value.filter((item) => !removeIds.has(item.id))
  rightPalletSelection.value = []
  rightPalletTableRef.value?.clearSelection()
}

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

const clearPallet = (row: any) => {
  if (props.disabled) return
  row.pallets = []
  row.palletCode = undefined
  if (isProductStockIn.value) {
    row.count = undefined
  }
}

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

const getPalletPackageCount = (row: any, pallet: PalletVO) => {
  return pallet.productCount ?? row?.palletPackageQuantity ?? row?.packageQuantity ?? row?.count
}

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

const getSelectedPalletItemCount = (pallet: any) => {
  return getSelectedPalletItemCountValue(pallet) ?? '-'
}

const syncCountByPallets = (row: any) => {
  const packageQuantity = Number(row?.packageQuantity)
  if (!Array.isArray(row?.pallets) || !Number.isFinite(packageQuantity)) {
    row.count = undefined
    return
  }
  const total = row.pallets.reduce((sum: number, pallet: any) => {
    const packageCount = Number(pallet?.packageCount)
    return Number.isFinite(packageCount) ? sum + packageQuantity * packageCount : sum
  }, 0)
  row.count = total || undefined
}

watch(
  () => formData.value.map((row) => [row.packageCount, row.purchaseUnitConvertQuantity]),
  () => {
    if (!isPurchaseUnitStockIn.value) return
    formData.value.forEach(syncCountByPackageCount)
  },
  { deep: true }
)

const normalizePackageCount = (row: any) => {
  if (!isPurchaseUnitStockIn.value || isRowRelatedTask(row)) return
  if (row.packageCount !== undefined && row.packageCount !== null && row.packageCount !== '') return
  if (row.inputCount !== undefined && row.inputCount !== null && row.inputCount !== '') {
    row.packageCount = row.inputCount
    return
  }
  const count = Number(row.count)
  const convertQuantity = Number(row.purchaseUnitConvertQuantity)
  if (Number.isFinite(count) && Number.isFinite(convertQuantity) && convertQuantity > 0) {
    row.packageCount = count / convertQuantity
  }
}

const syncCountByInputCount = (row: any) => {
  if (!isProductMaterialStockIn.value || isPurchaseUnitStockIn.value) return
  if (isRowRelatedTask(row)) return
  const inputCount = Number(row.inputCount)
  if (!Number.isFinite(inputCount)) {
    row.count = undefined
    return
  }
  row.count = inputCount
}

const syncCountByPackageCount = (row: any) => {
  if (!isPurchaseUnitStockIn.value) {
    syncCountByInputCount(row)
    return
  }
  if (isRowRelatedTask(row)) return
  const packageCount = Number(row.packageCount)
  const convertQuantity = Number(row.purchaseUnitConvertQuantity)
  if (!Number.isFinite(packageCount)) {
    row.count = undefined
    return
  }
  if (!row.purchaseUnitId && !row.purchaseUnitName) {
    row.count = packageCount
    return
  }
  row.count = Number.isFinite(convertQuantity) ? packageCount * convertQuantity : packageCount
}

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.productCode = row.productCode || 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
    normalizePackageCount(row)
    syncCountByPackageCount(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 = () => {
  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 (isProductMaterialStockIn.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;
  }
}

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

.task-product-select {
  display: grid;
  gap: 6px;
}

.task-select-dialog {
  display: grid;
  gap: 10px;
}

.task-select-dialog__section-title {
  color: var(--el-text-color-primary);
  font-size: 14px;
  font-weight: 600;
}

.pallet-transfer {
  display: grid;
  grid-template-columns: minmax(420px, 1fr) 72px minmax(420px, 1fr);
  gap: 18px;
  align-items: center;
}

.pallet-transfer--readonly {
  grid-template-columns: 1fr;
}

.pallet-transfer__panel {
  min-width: 0;
}

.pallet-transfer__title {
  margin-bottom: 8px;
  color: var(--el-text-color-primary);
  font-weight: 600;
}

.pallet-transfer__actions {
  display: grid;
  gap: 10px;
  justify-items: center;
  padding-top: 36px;
}

.pallet-transfer__actions :deep(.el-button + .el-button) {
  margin-left: 0;
}

.product-task-info {
  display: grid;
  gap: 2px;
  line-height: 18px;
}

.product-task-info__item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px;
  color: var(--el-text-color-secondary);
  font-size: 12px;
}

.product-task-info__item strong {
  color: var(--el-text-color-secondary);
  font-weight: 400;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>
