"use client";

import {
  Box,
  Button,
  Stack,
  TextField,
  Typography,
  Alert,
  CircularProgress,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
  Checkbox,
  TablePagination,
  Modal,
  Chip,
} from "@mui/material";
import dayjs from 'dayjs';
import TestQrCodeProvider from '../QrCodeScannerProvider/TestQrCodeProvider';
import { fetchLotDetail } from "@/app/api/inventory/actions";
import { useCallback, useEffect, useState, useRef, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { useRouter } from "next/navigation";
import {
  updateStockOutLineStatus,
  createStockOutLine,
  updateStockOutLine,
  recordPickExecutionIssue,
  fetchFGPickOrders, //  Add this import
  FGPickOrderResponse, 
  stockReponse,
  PickExecutionIssueData,
  checkPickOrderCompletion,
  fetchAllPickOrderLotsHierarchical,
  PickOrderCompletionResponse,
  checkAndCompletePickOrderByConsoCode,
  updateSuggestedLotLineId,
  updateStockOutLineStatusByQRCodeAndLotNo,
  confirmLotSubstitution,
  fetchDoPickOrderDetail,  //  必须添加
  DoPickOrderDetail,  //  必须添加
  fetchFGPickOrdersByUserId ,
  batchQrSubmit,
  batchSubmitList,  // 添加：导入 batchSubmitList
  batchSubmitListRequest,  // 添加：导入类型
  batchSubmitListLineRequest

} from "@/app/api/pickOrder/actions";

import FGPickOrderInfoCard from "./FGPickOrderInfoCard";
import LotConfirmationModal from "./LotConfirmationModal";
//import { fetchItem } from "@/app/api/settings/item";
import { updateInventoryLotLineStatus, analyzeQrCode } from "@/app/api/inventory/actions";
import { fetchNameList, NameList } from "@/app/api/user/actions";
import {
  FormProvider,
  useForm,
} from "react-hook-form";
import SearchBox, { Criterion } from "../SearchBox";
import { CreateStockOutLine } from "@/app/api/pickOrder/actions";
import { updateInventoryLotLineQuantities } from "@/app/api/inventory/actions";
import QrCodeIcon from '@mui/icons-material/QrCode';
import { useQrCodeScannerContext } from '../QrCodeScannerProvider/QrCodeScannerProvider';
import { useSession } from "next-auth/react";
import { SessionWithTokens } from "@/config/authConfig";
import { fetchStockInLineInfo } from "@/app/api/po/actions";
import GoodPickExecutionForm from "./GoodPickExecutionForm";
import FGPickOrderCard from "./FGPickOrderCard"; 
interface Props {
  filterArgs: Record<string, any>;
  onSwitchToRecordTab?: () => void;
  onRefreshReleasedOrderCount?: () => void;
}

//  QR Code Modal Component (from LotTable)
const QrCodeModal: React.FC<{
  open: boolean;
  onClose: () => void;
  lot: any | null;
  onQrCodeSubmit: (lotNo: string) => void;
  combinedLotData: any[]; //  Add this prop
}> = ({ open, onClose, lot, onQrCodeSubmit, combinedLotData }) => {
  const { t } = useTranslation("pickOrder");
  const { values: qrValues, isScanning, startScan, stopScan, resetScan } = useQrCodeScannerContext();
  const [manualInput, setManualInput] = useState<string>('');

  const [manualInputSubmitted, setManualInputSubmitted] = useState<boolean>(false);
  const [manualInputError, setManualInputError] = useState<boolean>(false);
  const [isProcessingQr, setIsProcessingQr] = useState<boolean>(false);
  const [qrScanFailed, setQrScanFailed] = useState<boolean>(false);
  const [qrScanSuccess, setQrScanSuccess] = useState<boolean>(false);
  
  const [processedQrCodes, setProcessedQrCodes] = useState<Set<string>>(new Set());
  const [scannedQrResult, setScannedQrResult] = useState<string>('');
  const [fgPickOrder, setFgPickOrder] = useState<FGPickOrderResponse | null>(null);
  // Process scanned QR codes
  useEffect(() => {
    if (qrValues.length > 0 && lot && !isProcessingQr && !qrScanSuccess) {
      const latestQr = qrValues[qrValues.length - 1];
      
      if (processedQrCodes.has(latestQr)) {
        console.log("QR code already processed, skipping...");
        return;
      }
      
      setProcessedQrCodes(prev => new Set(prev).add(latestQr));
      
      try {
        const qrData = JSON.parse(latestQr);
        
        if (qrData.stockInLineId && qrData.itemId) {
          setIsProcessingQr(true);
          setQrScanFailed(false);
          
          fetchStockInLineInfo(qrData.stockInLineId)
            .then((stockInLineInfo) => {
              console.log("Stock in line info:", stockInLineInfo);
              setScannedQrResult(stockInLineInfo.lotNo || 'Unknown lot number');
              
              if (stockInLineInfo.lotNo === lot.lotNo) {
                console.log(` QR Code verified for lot: ${lot.lotNo}`);
                setQrScanSuccess(true);
                onQrCodeSubmit(lot.lotNo);
                onClose();
                resetScan();
              } else {
                console.log(`  QR Code mismatch. Expected: ${lot.lotNo}, Got: ${stockInLineInfo.lotNo}`);
                setQrScanFailed(true);
                setManualInputError(true);
                setManualInputSubmitted(true);
              }
            })
            .catch((error) => {
              console.error("Error fetching stock in line info:", error);
              setScannedQrResult('Error fetching data');
              setQrScanFailed(true);
              setManualInputError(true);
              setManualInputSubmitted(true);
            })
            .finally(() => {
              setIsProcessingQr(false);
            });
        } else {
          const qrContent = latestQr.replace(/[{}]/g, '');
          setScannedQrResult(qrContent);
          
          if (qrContent === lot.lotNo) {
            setQrScanSuccess(true);
            onQrCodeSubmit(lot.lotNo);
            onClose();
            resetScan();
          } else {
            setQrScanFailed(true);
            setManualInputError(true);
            setManualInputSubmitted(true);
          }
        }
      } catch (error) {
        console.log("QR code is not JSON format, trying direct comparison");
        const qrContent = latestQr.replace(/[{}]/g, '');
        setScannedQrResult(qrContent);
        
        if (qrContent === lot.lotNo) {
          setQrScanSuccess(true);
          onQrCodeSubmit(lot.lotNo);
          onClose();
          resetScan();
        } else {
          setQrScanFailed(true);
          setManualInputError(true);
          setManualInputSubmitted(true);
        }
      }
    }
  }, [qrValues, lot, onQrCodeSubmit, onClose, resetScan, isProcessingQr, qrScanSuccess, processedQrCodes]);

  // Clear states when modal opens
  useEffect(() => {
    if (open) {
      setManualInput('');
      setManualInputSubmitted(false);
      setManualInputError(false);
      setIsProcessingQr(false);
      setQrScanFailed(false);
      setQrScanSuccess(false);
      setScannedQrResult('');
      setProcessedQrCodes(new Set());
    }
  }, [open]);

  useEffect(() => {
    if (lot) {
      setManualInput('');
      setManualInputSubmitted(false);
      setManualInputError(false);
      setIsProcessingQr(false);
      setQrScanFailed(false);
      setQrScanSuccess(false);
      setScannedQrResult('');
      setProcessedQrCodes(new Set());
    }
  }, [lot]);

  // Auto-submit manual input when it matches
  useEffect(() => {
    if (manualInput.trim() === lot?.lotNo && manualInput.trim() !== '' && !qrScanFailed && !qrScanSuccess) {
      console.log(' Auto-submitting manual input:', manualInput.trim());
      
      const timer = setTimeout(() => {
        setQrScanSuccess(true);
        onQrCodeSubmit(lot.lotNo);
        onClose();
        setManualInput('');
        setManualInputError(false);
        setManualInputSubmitted(false);
      }, 200);
      
      return () => clearTimeout(timer);
    }
  }, [manualInput, lot, onQrCodeSubmit, onClose, qrScanFailed, qrScanSuccess]);

  const handleManualSubmit = () => {
    if (manualInput.trim() === lot?.lotNo) {
      setQrScanSuccess(true);
      onQrCodeSubmit(lot.lotNo);
      onClose();
      setManualInput('');
    } else {
      setQrScanFailed(true);
      setManualInputError(true);
      setManualInputSubmitted(true);
    }
  };

  useEffect(() => {
    if (open) {
      startScan();
    }
  }, [open, startScan]);

  return (
    <Modal open={open} onClose={onClose}>
      <Box sx={{
        position: 'absolute',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        bgcolor: 'background.paper',
        p: 3,
        borderRadius: 2,
        minWidth: 400,
      }}>
        <Typography variant="h6" gutterBottom>
          {t("QR Code Scan for Lot")}: {lot?.lotNo}
        </Typography>
        
        {isProcessingQr && (
          <Box sx={{ mb: 2, p: 2, backgroundColor: '#e3f2fd', borderRadius: 1 }}>
            <Typography variant="body2" color="primary">
               {t("Processing QR code...")}
            </Typography>
          </Box>
        )}
        
        <Box sx={{ mb: 2 }}>
          <Typography variant="body2" gutterBottom>
            <strong>{t("Manual Input")}:</strong>
          </Typography>
          <TextField
            fullWidth
            size="small"
            value={manualInput}
            onChange={(e) => {
              setManualInput(e.target.value);
              if (qrScanFailed || manualInputError) {
                setQrScanFailed(false);
                setManualInputError(false);
                setManualInputSubmitted(false);
              }
            }}
            sx={{ mb: 1 }}
            error={manualInputSubmitted && manualInputError}
            helperText={
              manualInputSubmitted && manualInputError
                ? `${t("The input is not the same as the expected lot number.")}`
                : ''
            }
          />
          <Button
            variant="contained"
            onClick={handleManualSubmit}
            disabled={!manualInput.trim()}
            size="small"
            color="primary"
          >
            {t("Submit")}
          </Button>
        </Box>

        {qrValues.length > 0 && (
          <Box sx={{ 
            mb: 2, 
            p: 2, 
            backgroundColor: qrScanFailed ? '#ffebee' : qrScanSuccess ? '#e8f5e8' : '#f5f5f5', 
            borderRadius: 1 
          }}>
            <Typography variant="body2" color={qrScanFailed ? 'error' : qrScanSuccess ? 'success' : 'text.secondary'}>
              <strong>{t("QR Scan Result:")}</strong> {scannedQrResult}
            </Typography>

            {qrScanSuccess && (
              <Typography variant="caption" color="success" display="block">
                 {t("Verified successfully!")}
              </Typography>
            )}
          </Box>
        )}

        <Box sx={{ mt: 2, textAlign: 'right' }}>
          <Button onClick={onClose} variant="outlined">
            {t("Cancel")}
          </Button>
        </Box>
      </Box>
    </Modal>
  );
};
const ManualLotConfirmationModal: React.FC<{
  open: boolean;
  onClose: () => void;
  onConfirm: (expectedLotNo: string, scannedLotNo: string) => void;
  expectedLot: {
    lotNo: string;
    itemCode: string;
    itemName: string;
  } | null;
  scannedLot: {
    lotNo: string;
    itemCode: string;
    itemName: string;
  } | null;
  isLoading?: boolean;
}> = ({ open, onClose, onConfirm, expectedLot, scannedLot, isLoading = false }) => {
  const { t } = useTranslation("pickOrder");
  const [expectedLotInput, setExpectedLotInput] = useState<string>('');
  const [scannedLotInput, setScannedLotInput] = useState<string>('');
  const [error, setError] = useState<string>('');

  // 当模态框打开时，预填充输入框
  useEffect(() => {
    if (open) {
      setExpectedLotInput(expectedLot?.lotNo || '');
      setScannedLotInput(scannedLot?.lotNo || '');
      setError('');
    }
  }, [open, expectedLot, scannedLot]);

  const handleConfirm = () => {
    if (!expectedLotInput.trim() || !scannedLotInput.trim()) {
      setError(t("Please enter both expected and scanned lot numbers."));
      return;
    }
    
    if (expectedLotInput.trim() === scannedLotInput.trim()) {
      setError(t("Expected and scanned lot numbers cannot be the same."));
      return;
    }

    onConfirm(expectedLotInput.trim(), scannedLotInput.trim());
  };

  return (
    <Modal open={open} onClose={onClose}>
      <Box sx={{
        position: 'absolute',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        bgcolor: 'background.paper',
        p: 3,
        borderRadius: 2,
        minWidth: 500,
      }}>
        <Typography variant="h6" gutterBottom color="warning.main">
          {t("Manual Lot Confirmation")}
        </Typography>
        
        <Box sx={{ mb: 2 }}>
          <Typography variant="body2" gutterBottom>
            <strong>{t("Expected Lot Number")}:</strong>
          </Typography>
          <TextField
            fullWidth
            size="small"
            value={expectedLotInput}
            onChange={(e) => {
              setExpectedLotInput(e.target.value);
              setError('');
            }}
            placeholder={expectedLot?.lotNo || t("Enter expected lot number")}
            sx={{ mb: 2 }}
            error={!!error && !expectedLotInput.trim()}
          />
        </Box>

        <Box sx={{ mb: 2 }}>
          <Typography variant="body2" gutterBottom>
            <strong>{t("Scanned Lot Number")}:</strong>
          </Typography>
          <TextField
            fullWidth
            size="small"
            value={scannedLotInput}
            onChange={(e) => {
              setScannedLotInput(e.target.value);
              setError('');
            }}
            placeholder={scannedLot?.lotNo || t("Enter scanned lot number")}
            sx={{ mb: 2 }}
            error={!!error && !scannedLotInput.trim()}
          />
        </Box>

        {error && (
          <Box sx={{ mb: 2, p: 1, backgroundColor: '#ffebee', borderRadius: 1 }}>
            <Typography variant="body2" color="error">
              {error}
            </Typography>
          </Box>
        )}

        <Box sx={{ mt: 2, display: 'flex', justifyContent: 'flex-end', gap: 2 }}>
          <Button onClick={onClose} variant="outlined" disabled={isLoading}>
            {t("Cancel")}
          </Button>
          <Button 
            onClick={handleConfirm} 
            variant="contained" 
            color="warning"
            disabled={isLoading || !expectedLotInput.trim() || !scannedLotInput.trim()}
          >
            {isLoading ? t("Processing...") : t("Confirm")}
          </Button>
        </Box>
      </Box>
    </Modal>
  );
};
const PickExecution: React.FC<Props> = ({ filterArgs, onSwitchToRecordTab, onRefreshReleasedOrderCount }) => {
  const { t } = useTranslation("pickOrder");
  const router = useRouter();
  const { data: session } = useSession() as { data: SessionWithTokens | null };
  const [doPickOrderDetail, setDoPickOrderDetail] = useState<DoPickOrderDetail | null>(null);
const [selectedPickOrderId, setSelectedPickOrderId] = useState<number | null>(null);
const [pickOrderSwitching, setPickOrderSwitching] = useState(false);
  const currentUserId = session?.id ? parseInt(session.id) : undefined;
  const [allLotsCompleted, setAllLotsCompleted] = useState(false);
  const [combinedLotData, setCombinedLotData] = useState<any[]>([]);
  const [combinedDataLoading, setCombinedDataLoading] = useState(false);
  const [originalCombinedData, setOriginalCombinedData] = useState<any[]>([]);
  
  const { values: qrValues, isScanning, startScan, stopScan, resetScan } = useQrCodeScannerContext();
  
  const [qrScanInput, setQrScanInput] = useState<string>('');
  const [qrScanError, setQrScanError] = useState<boolean>(false);
  const [qrScanSuccess, setQrScanSuccess] = useState<boolean>(false);
  const [manualLotConfirmationOpen, setManualLotConfirmationOpen] = useState(false);
  const [pickQtyData, setPickQtyData] = useState<Record<string, number>>({});
  const [searchQuery, setSearchQuery] = useState<Record<string, any>>({});

  const [paginationController, setPaginationController] = useState({
    pageNum: 0,
    pageSize: 10,
  });

  const [usernameList, setUsernameList] = useState<NameList[]>([]);

  const initializationRef = useRef(false);
  const autoAssignRef = useRef(false);

  const formProps = useForm();
  const errors = formProps.formState.errors;

  //  Add QR modal states
  const [qrModalOpen, setQrModalOpen] = useState(false);
  const [selectedLotForQr, setSelectedLotForQr] = useState<any | null>(null);
  const [lotConfirmationOpen, setLotConfirmationOpen] = useState(false);
const [expectedLotData, setExpectedLotData] = useState<any>(null);
const [scannedLotData, setScannedLotData] = useState<any>(null);
const [isConfirmingLot, setIsConfirmingLot] = useState(false);
  //  Add GoodPickExecutionForm states
  const [pickExecutionFormOpen, setPickExecutionFormOpen] = useState(false);
  const [selectedLotForExecutionForm, setSelectedLotForExecutionForm] = useState<any | null>(null);
  const [fgPickOrders, setFgPickOrders] = useState<FGPickOrderResponse[]>([]);

  const [fgPickOrdersLoading, setFgPickOrdersLoading] = useState(false);
    //  Add these missing state variables after line 352
    const [isManualScanning, setIsManualScanning] = useState<boolean>(false);
    const [processedQrCodes, setProcessedQrCodes] = useState<Set<string>>(new Set());
    const [lastProcessedQr, setLastProcessedQr] = useState<string>('');
    const [isRefreshingData, setIsRefreshingData] = useState<boolean>(false);
    const [isSubmittingAll, setIsSubmittingAll] = useState<boolean>(false);
    
 
  
  //  Handle QR code button click
  const handleQrCodeClick = (pickOrderId: number) => {
    console.log(`QR Code clicked for pick order ID: ${pickOrderId}`);
    // TODO: Implement QR code functionality
  };

  const handleLotMismatch = useCallback((expectedLot: any, scannedLot: any) => {
    console.log("Lot mismatch detected:", { expectedLot, scannedLot });
    setExpectedLotData(expectedLot);
    setScannedLotData(scannedLot);
    setLotConfirmationOpen(true);
  }, []);
  const checkAllLotsCompleted = useCallback((lotData: any[]) => {
    if (lotData.length === 0) {
      setAllLotsCompleted(false);
      return false;
    }

    // Filter out rejected lots
    const nonRejectedLots = lotData.filter(lot => 
      lot.lotAvailability !== 'rejected' && 
      lot.stockOutLineStatus !== 'rejected'
    );

    if (nonRejectedLots.length === 0) {
      setAllLotsCompleted(false);
      return false;
    }

    // Check if all non-rejected lots are completed
    const allCompleted = nonRejectedLots.every(lot => 
      lot.stockOutLineStatus === 'completed'
    );

    setAllLotsCompleted(allCompleted);
    return allCompleted;
  }, []);
// 在 fetchAllCombinedLotData 函数中（约 446-684 行）

const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdOverride?: number) => {
  setCombinedDataLoading(true);
  try {
    const userIdToUse = userId || currentUserId;
    
    console.log("🔍 fetchAllCombinedLotData called with userId:", userIdToUse);
    
    if (!userIdToUse) {
      console.warn("⚠️ No userId available, skipping API call");
      setCombinedLotData([]);
      setOriginalCombinedData([]);
      setAllLotsCompleted(false);
      return;
    }
    
    //  获取新结构的层级数据
    const hierarchicalData = await fetchAllPickOrderLotsHierarchical(userIdToUse);
    console.log(" Hierarchical data (new structure):", hierarchicalData);
    
    //  检查数据结构
    if (!hierarchicalData.fgInfo || !hierarchicalData.pickOrders || hierarchicalData.pickOrders.length === 0) {
      console.warn("⚠️ No FG info or pick orders found");
      setCombinedLotData([]);
      setOriginalCombinedData([]);
      setAllLotsCompleted(false);
      return;
    }
    
    //  使用合并后的 pick order 对象（现在只有一个对象，包含所有数据）
    const mergedPickOrder = hierarchicalData.pickOrders[0];
    
    //  设置 FG info 到 fgPickOrders（用于显示 FG 信息卡片）
   // 修改第 478-509 行的 fgOrder 构建逻辑：

const fgOrder: FGPickOrderResponse = {
  doPickOrderId: hierarchicalData.fgInfo.doPickOrderId,
  ticketNo: hierarchicalData.fgInfo.ticketNo,
  storeId: hierarchicalData.fgInfo.storeId,
  shopCode: hierarchicalData.fgInfo.shopCode,
  shopName: hierarchicalData.fgInfo.shopName,
  truckLanceCode: hierarchicalData.fgInfo.truckLanceCode,
  DepartureTime: hierarchicalData.fgInfo.departureTime,
  shopAddress: "",
  pickOrderCode: mergedPickOrder.pickOrderCodes?.[0] || "",
  //  兼容字段
  pickOrderId: mergedPickOrder.pickOrderIds?.[0] || 0,
  pickOrderConsoCode: mergedPickOrder.consoCode || "",
  pickOrderTargetDate: mergedPickOrder.targetDate || "",
  pickOrderStatus: mergedPickOrder.status || "",
  deliveryOrderId: mergedPickOrder.doOrderIds?.[0] || 0,
  deliveryNo: mergedPickOrder.deliveryOrderCodes?.[0] || "",
  deliveryDate: "",
  shopId: 0,
  shopPoNo: "",
  numberOfCartons: mergedPickOrder.pickOrderLines?.length || 0,
  qrCodeData: hierarchicalData.fgInfo.doPickOrderId,
  
  //  新增：多个 pick orders 信息 - 保持数组格式，不要 join
  numberOfPickOrders: mergedPickOrder.pickOrderIds?.length || 0,
  pickOrderIds: mergedPickOrder.pickOrderIds || [],
  pickOrderCodes: Array.isArray(mergedPickOrder.pickOrderCodes) 
    ? mergedPickOrder.pickOrderCodes 
    : [], //  改：保持数组
  deliveryOrderIds: mergedPickOrder.doOrderIds || [],
  deliveryNos: Array.isArray(mergedPickOrder.deliveryOrderCodes) 
    ? mergedPickOrder.deliveryOrderCodes 
    : [], //  改：保持数组
  lineCountsPerPickOrder: Array.isArray(mergedPickOrder.lineCountsPerPickOrder) 
  ? mergedPickOrder.lineCountsPerPickOrder 
  : []
};
    
    setFgPickOrders([fgOrder]);
    console.log("🔍 DEBUG fgOrder.lineCountsPerPickOrder:", fgOrder.lineCountsPerPickOrder);
console.log("🔍 DEBUG fgOrder.pickOrderCodes:", fgOrder.pickOrderCodes);
console.log("🔍 DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
    //   移除：不需要 doPickOrderDetail 和 switcher 逻辑
    // if (hierarchicalData.pickOrders.length > 1) { ... }
    
    //  直接使用合并后的 pickOrderLines
    console.log("🎯 Displaying merged pick order lines");
    
    //  将层级数据转换为平铺格式（用于表格显示）
    const flatLotData: any[] = [];
    
    mergedPickOrder.pickOrderLines.forEach((line: any) => {
      // ✅ FIXED: 处理 lots（如果有）
      if (line.lots && line.lots.length > 0) {
        //  修复：先对 lots 按 lotId 去重并合并 requiredQty
        const lotMap = new Map<number, any>();
        
        line.lots.forEach((lot: any) => {
          const lotId = lot.id;
          if (lotMap.has(lotId)) {
            //  如果已存在，合并 requiredQty
            const existingLot = lotMap.get(lotId);
            existingLot.requiredQty = (existingLot.requiredQty || 0) + (lot.requiredQty || 0);
            //  保留其他字段（使用第一个遇到的 lot 的字段）
          } else {
            //  首次遇到，添加到 map
            lotMap.set(lotId, { ...lot });
          }
        });
        
        //  遍历去重后的 lots
        lotMap.forEach((lot: any) => {
          flatLotData.push({
            //  使用合并后的数据
            pickOrderConsoCode: mergedPickOrder.consoCode,
            pickOrderTargetDate: mergedPickOrder.targetDate,
            pickOrderStatus: mergedPickOrder.status,
            pickOrderId: line.pickOrderId || mergedPickOrder.pickOrderIds?.[0] || 0,   //  使用第一个 pickOrderId
            pickOrderCode: mergedPickOrder.pickOrderCodes?.[0] || "", 
            pickOrderLineId: line.id,
            pickOrderLineRequiredQty: line.requiredQty,
            pickOrderLineStatus: line.status,
            
            itemId: line.item.id,
            itemCode: line.item.code,
            itemName: line.item.name,
            uomDesc: line.item.uomDesc,
            uomShortDesc: line.item.uomShortDesc,
            
            lotId: lot.id,
            lotNo: lot.lotNo,
            expiryDate: lot.expiryDate,
            location: lot.location,
            stockUnit: lot.stockUnit,
            availableQty: lot.availableQty,
            requiredQty: lot.requiredQty, //  使用合并后的 requiredQty
            actualPickQty: lot.actualPickQty,
            inQty: lot.inQty,
            outQty: lot.outQty,
            holdQty: lot.holdQty,
            lotStatus: lot.lotStatus,
            lotAvailability: lot.lotAvailability,
            processingStatus: lot.processingStatus,
            suggestedPickLotId: lot.suggestedPickLotId,
            stockOutLineId: lot.stockOutLineId,
            stockOutLineStatus: lot.stockOutLineStatus,
            stockOutLineQty: lot.stockOutLineQty,
            
            routerId: lot.router?.id,
            routerIndex: lot.router?.index,
            routerRoute: lot.router?.route,
            routerArea: lot.router?.area,
            noLot: false,
          });
        });
      }
      
      // ✅ FIXED: 同时处理 stockouts（无论是否有 lots）
      if (line.stockouts && line.stockouts.length > 0) {
        // ✅ FIXED: 处理所有 stockouts，而不仅仅是第一个
        line.stockouts.forEach((stockout: any) => {
          flatLotData.push({
            pickOrderConsoCode: mergedPickOrder.consoCodes?.[0] || "",
            pickOrderTargetDate: mergedPickOrder.targetDate,
            pickOrderStatus: mergedPickOrder.status,
            pickOrderId: line.pickOrderId || mergedPickOrder.pickOrderIds?.[0] || 0,
            pickOrderCode: mergedPickOrder.pickOrderCodes?.[0] || "", 
            pickOrderLineId: line.id,
            pickOrderLineRequiredQty: line.requiredQty,
            pickOrderLineStatus: line.status,
            
            itemId: line.item.id,
            itemCode: line.item.code,
            itemName: line.item.name,
            uomDesc: line.item.uomDesc,
            uomShortDesc: line.item.uomShortDesc,
            
            //  Null stock 字段 - 从 stockouts 数组中获取
            lotId: stockout.lotId || null,
            lotNo: stockout.lotNo || null,
            expiryDate: null,
            location: stockout.location || null,
            stockUnit: line.item.uomDesc,
            availableQty: stockout.availableQty || 0,
            requiredQty: line.requiredQty,
            actualPickQty: stockout.qty || 0,
            inQty: 0,
            outQty: 0,
            holdQty: 0,
            lotStatus: 'unavailable',
            lotAvailability: 'insufficient_stock',
            processingStatus: stockout.status || 'pending',
            suggestedPickLotId: null,
            stockOutLineId: stockout.id || null,  //  使用 stockouts 数组中的 id
            stockOutLineStatus: stockout.status || null,
            stockOutLineQty: stockout.qty || 0,
            
            routerId: null,
            routerIndex: 999999,
            routerRoute: null,
            routerArea: null,
            noLot: true,
          });
        });
      }
    });

    console.log(" Transformed flat lot data:", flatLotData);
    console.log("🔍 Total items (including null stock):", flatLotData.length);
    
    setCombinedLotData(flatLotData);
    setOriginalCombinedData(flatLotData);
    checkAllLotsCompleted(flatLotData);
    
  } catch (error) {
    console.error("  Error fetching combined lot data:", error);
    setCombinedLotData([]);
    setOriginalCombinedData([]);
    setAllLotsCompleted(false);
  } finally {
    setCombinedDataLoading(false);
  }
}, [currentUserId, checkAllLotsCompleted]); //   移除 selectedPickOrderId 依赖
  //  Add effect to check completion when lot data changes
  const handleManualLotConfirmation = useCallback(async (currentLotNo: string, newLotNo: string) => {
    console.log(`🔍 Manual lot confirmation: Current=${currentLotNo}, New=${newLotNo}`);
    
    // 使用第一个输入框的 lot number 查找当前数据
    const currentLot = combinedLotData.find(lot => 
      lot.lotNo && lot.lotNo === currentLotNo
    );
    
    if (!currentLot) {
      console.error(`❌ Current lot not found: ${currentLotNo}`);
      alert(t("Current lot number not found. Please verify and try again."));
      return;
    }
    
    if (!currentLot.stockOutLineId) {
      console.error("❌ No stockOutLineId found for current lot");
      alert(t("No stock out line found for current lot. Please contact administrator."));
      return;
    }
    
    setIsConfirmingLot(true);
    
    try {
      // 调用 updateStockOutLineStatusByQRCodeAndLotNo API
      // 第一个 lot 用于获取 pickOrderLineId, stockOutLineId, itemId
      // 第二个 lot 作为 inventoryLotNo
      const res = await updateStockOutLineStatusByQRCodeAndLotNo({
        pickOrderLineId: currentLot.pickOrderLineId,
        inventoryLotNo: newLotNo, // 第二个输入框的值
        stockOutLineId: currentLot.stockOutLineId,
        itemId: currentLot.itemId,
        status: "checked",
      });
      
      console.log("📥 updateStockOutLineStatusByQRCodeAndLotNo result:", res);
      
      if (res.code === "checked" || res.code === "SUCCESS") {
        // ✅ 更新本地状态
        const entity = res.entity as any;
        
        setCombinedLotData(prev => prev.map(lot => {
          if (lot.stockOutLineId === currentLot.stockOutLineId &&
              lot.pickOrderLineId === currentLot.pickOrderLineId) {
            return {
              ...lot,
              stockOutLineStatus: 'checked',
              stockOutLineQty: entity?.qty ? Number(entity.qty) : lot.stockOutLineQty,
            };
          }
          return lot;
        }));
    
        setOriginalCombinedData(prev => prev.map(lot => {
          if (lot.stockOutLineId === currentLot.stockOutLineId &&
              lot.pickOrderLineId === currentLot.pickOrderLineId) {
            return {
              ...lot,
              stockOutLineStatus: 'checked',
              stockOutLineQty: entity?.qty ? Number(entity.qty) : lot.stockOutLineQty,
            };
          }
          return lot;
        }));
        
        console.log("✅ Lot substitution completed successfully");
        setQrScanSuccess(true);
        setQrScanError(false);
        
        // 关闭手动输入模态框
        setManualLotConfirmationOpen(false);
        
        // 刷新数据
        await fetchAllCombinedLotData();
      } else if (res.code === "LOT_NUMBER_MISMATCH") {
        console.warn("⚠️ Backend reported LOT_NUMBER_MISMATCH:", res.message);
        
        // ✅ 打开 lot confirmation modal 而不是显示 alert
        // 从响应消息中提取 expected lot number（如果可能）
        // 或者使用 currentLotNo 作为 expected lot
        const expectedLotNo = currentLotNo; // 当前 lot 是期望的
        
        // 查找新 lot 的信息（如果存在于 combinedLotData 中）
        const newLot = combinedLotData.find(lot => 
          lot.lotNo && lot.lotNo === newLotNo
        );
        
        // 设置 expected lot data
        setExpectedLotData({
          lotNo: expectedLotNo,
          itemCode: currentLot.itemCode || '',
          itemName: currentLot.itemName || ''
        });
        
        // 设置 scanned lot data
        setScannedLotData({
          lotNo: newLotNo,
          itemCode: newLot?.itemCode || currentLot.itemCode || '',
          itemName: newLot?.itemName || currentLot.itemName || '',
          inventoryLotLineId: newLot?.lotId || null,
          stockInLineId: null // 手动输入时可能没有 stockInLineId
        });
        
        // 设置 selectedLotForQr 为当前 lot
        setSelectedLotForQr(currentLot);
        
        // 关闭手动输入模态框
        setManualLotConfirmationOpen(false);
        
        // 打开 lot confirmation modal
        setLotConfirmationOpen(true);
        
        setQrScanError(false); // 不显示错误，因为会打开确认模态框
        setQrScanSuccess(false);
      } else if (res.code === "ITEM_MISMATCH") {
        console.warn("⚠️ Backend reported ITEM_MISMATCH:", res.message);
        alert(t("Item mismatch: {message}", { message: res.message || "" }));
        setQrScanError(true);
        setQrScanSuccess(false);
        
        // 关闭手动输入模态框
        setManualLotConfirmationOpen(false);
      } else {
        console.warn("⚠️ Unexpected response code:", res.code);
        alert(t("Failed to update lot status. Response: {code}", { code: res.code }));
        setQrScanError(true);
        setQrScanSuccess(false);
        
        // 关闭手动输入模态框
        setManualLotConfirmationOpen(false);
      }
      
    } catch (error) {
      console.error("❌ Error in manual lot confirmation:", error);
      alert(t("Failed to confirm lot substitution. Please try again."));
      setQrScanError(true);
      setQrScanSuccess(false);
      
      // 关闭手动输入模态框
      setManualLotConfirmationOpen(false);
    } finally {
      setIsConfirmingLot(false);
    }
  }, [combinedLotData, fetchAllCombinedLotData, t]);
  useEffect(() => {
    if (combinedLotData.length > 0) {
      checkAllLotsCompleted(combinedLotData);
    }
  }, [combinedLotData, checkAllLotsCompleted]);

  //  Add function to expose completion status to parent
  const getCompletionStatus = useCallback(() => {
    return allLotsCompleted;
  }, [allLotsCompleted]);

  //  Expose completion status to parent component
  useEffect(() => {
    // Dispatch custom event with completion status
    const event = new CustomEvent('pickOrderCompletionStatus', {
      detail: { 
        allLotsCompleted,
        tabIndex: 1 //  明确指定这是来自标签页 1 的事件
      }
    });
    window.dispatchEvent(event);
  }, [allLotsCompleted]);
  const handleLotConfirmation = useCallback(async () => {
    if (!expectedLotData || !scannedLotData || !selectedLotForQr) return;
    setIsConfirmingLot(true);
    try {
      const newLotNo = scannedLotData?.lotNo;
      if (!newLotNo) {
        console.error("No lot number for scanned lot");
        alert(t("Cannot find lot number for scanned lot. Please verify the lot number is correct."));
        setIsConfirmingLot(false);
        return;
      }
  
      await confirmLotSubstitution({
        pickOrderLineId: selectedLotForQr.pickOrderLineId,
        stockOutLineId: selectedLotForQr.stockOutLineId,
        originalSuggestedPickLotId: selectedLotForQr.suggestedPickLotId,
        newInventoryLotNo: newLotNo
      });
  
      setQrScanError(false);
      setQrScanSuccess(false);
      setQrScanInput('');
      
      // ✅ 修复：在确认后重置扫描状态，避免重复处理
      resetScan();
      
      // ✅ 修复：不要清空 processedQrCodes，而是保留当前 QR code 的标记
      // 或者如果确实需要清空，应该在重置扫描后再清空
      // setProcessedQrCodes(new Set());
      // setLastProcessedQr('');
      
      setQrModalOpen(false);
      setPickExecutionFormOpen(false);
      if(selectedLotForQr?.stockOutLineId){
        const stockOutLineUpdate = await updateStockOutLineStatus({
          id: selectedLotForQr.stockOutLineId,
          status: 'checked',
          qty: 0
        });
      }
      
      // ✅ 修复：先关闭 modal 和清空状态，再刷新数据
      setLotConfirmationOpen(false);
      setExpectedLotData(null);
      setScannedLotData(null);
      setSelectedLotForQr(null);
      
      // ✅ 修复：刷新数据前设置刷新标志，避免在刷新期间处理新的 QR code
      setIsRefreshingData(true);
      await fetchAllCombinedLotData();
      setIsRefreshingData(false);
    } catch (error) {
      console.error("Error confirming lot substitution:", error);
    } finally {
      setIsConfirmingLot(false);
    }
  }, [expectedLotData, scannedLotData, selectedLotForQr, fetchAllCombinedLotData, resetScan]);
  const handleQrCodeSubmit = useCallback(async (lotNo: string) => {
    console.log(` Processing QR Code for lot: ${lotNo}`);
    
    //  检查 lotNo 是否为 null 或 undefined（包括字符串 "null"）
    if (!lotNo || lotNo === 'null' || lotNo.trim() === '') {
      console.error("  Invalid lotNo: null, undefined, or empty");
      return;
    }
    
    //  Use current data without refreshing to avoid infinite loop
    const currentLotData = combinedLotData;
    console.log(` Available lots:`, currentLotData.map(lot => lot.lotNo));
    
    //  修复：在比较前确保 lotNo 不为 null
    const lotNoLower = lotNo.toLowerCase();
    const matchingLots = currentLotData.filter(lot => {
      if (!lot.lotNo) return false; //  跳过 null lotNo
      return lot.lotNo === lotNo || lot.lotNo.toLowerCase() === lotNoLower;
    });
    
    if (matchingLots.length === 0) {
      console.error(`  Lot not found: ${lotNo}`);
      setQrScanError(true);
      setQrScanSuccess(false);
      const availableLotNos = currentLotData.map(lot => lot.lotNo).join(', ');
      console.log(`  QR Code "${lotNo}" does not match any expected lots. Available lots: ${availableLotNos}`);
      return; 
    }
    
    console.log(` Found ${matchingLots.length} matching lots:`, matchingLots);
    setQrScanError(false);
    
    try {
      let successCount = 0;
      let errorCount = 0;
      
      for (const matchingLot of matchingLots) {
        console.log(`🔄 Processing pick order line ${matchingLot.pickOrderLineId} for lot ${lotNo}`);
        
        if (matchingLot.stockOutLineId) {
          const stockOutLineUpdate = await updateStockOutLineStatus({
            id: matchingLot.stockOutLineId,
            status: 'checked',
            qty: 0
          });
          console.log(`Update stock out line result for line ${matchingLot.pickOrderLineId}:`, stockOutLineUpdate);

          // Treat multiple backend shapes as success (type-safe via any)
          const r: any = stockOutLineUpdate as any;
          const updateOk =
            r?.code === 'SUCCESS' ||
            typeof r?.id === 'number' ||
            r?.type === 'checked' ||
            r?.status === 'checked' ||
            typeof r?.entity?.id === 'number' ||
            r?.entity?.status === 'checked';

          if (updateOk) {
            successCount++;
          } else {
            errorCount++;
          }
        } else {
          const createStockOutLineData = {
            consoCode: matchingLot.pickOrderConsoCode,
            pickOrderLineId: matchingLot.pickOrderLineId,
            inventoryLotLineId: matchingLot.lotId,
            qty: 0
          };
          
          const createResult = await createStockOutLine(createStockOutLineData);
          console.log(`Create stock out line result for line ${matchingLot.pickOrderLineId}:`, createResult);
          
          if (createResult && createResult.code === "SUCCESS") {
            // Immediately set status to checked for new line
            let newSolId: number | undefined;
            const anyRes: any = createResult as any;
            if (typeof anyRes?.id === 'number') {
              newSolId = anyRes.id;
            } else if (anyRes?.entity) {
              newSolId = Array.isArray(anyRes.entity) ? anyRes.entity[0]?.id : anyRes.entity?.id;
            }

            if (newSolId) {
              const setChecked = await updateStockOutLineStatus({
                id: newSolId,
                status: 'checked',
                qty: 0
              });
              if (setChecked && setChecked.code === "SUCCESS") {
                successCount++;
              } else {
                errorCount++;
              }
            } else {
              console.warn("Created stock out line but no ID returned; cannot set to checked");
              errorCount++;
            }
          } else {
            errorCount++;
          }
        }
      }
      
      //  FIXED: Set refresh flag before refreshing data
      setIsRefreshingData(true);
      console.log("🔄 Refreshing data after QR code processing...");
      await fetchAllCombinedLotData();
      
      if (successCount > 0) {
        console.log(` QR Code processing completed: ${successCount} updated/created`);
        setQrScanSuccess(true);
        setQrScanError(false);
        setQrScanInput(''); // Clear input after successful processing
        //setIsManualScanning(false);
       // stopScan();
       // resetScan();
        //  Clear success state after a delay
        
        //setTimeout(() => {
          //setQrScanSuccess(false);
        //}, 2000);
      } else {
        console.error(`  QR Code processing failed: ${errorCount} errors`);
        setQrScanError(true);
        setQrScanSuccess(false);
        
        //  Clear error state after a delay
       // setTimeout(() => {
         // setQrScanError(false);
        //}, 3000);
      }
    } catch (error) {
      console.error("  Error processing QR code:", error);
      setQrScanError(true);
      setQrScanSuccess(false);
      
    
      //  Clear error state after a delay
      setTimeout(() => {
        setQrScanError(false);
      }, 3000);
    } finally {
      //  Clear refresh flag after a short delay
      setTimeout(() => {
        setIsRefreshingData(false);
      }, 1000);
    }
  }, [combinedLotData]);
  const handleFastQrScan = useCallback(async (lotNo: string) => {
    const startTime = performance.now();
    console.log(`⏱️ [FAST SCAN START] Lot: ${lotNo}`);
    console.log(`⏰ Start time: ${new Date().toISOString()}`);
    
    // 从 combinedLotData 中找到对应的 lot
    const findStartTime = performance.now();
    const matchingLot = combinedLotData.find(lot => 
      lot.lotNo && lot.lotNo === lotNo
    );
    const findTime = performance.now() - findStartTime;
    console.log(`⏱️ Find lot time: ${findTime.toFixed(2)}ms`);
  
    if (!matchingLot || !matchingLot.stockOutLineId) {
      const totalTime = performance.now() - startTime;
      console.warn(`⚠️ Fast scan: Lot ${lotNo} not found or no stockOutLineId`);
      console.log(`⏱️ Total time: ${totalTime.toFixed(2)}ms`);
      return;
    }
  
    try {
      // ✅ 使用快速 API
      const apiStartTime = performance.now();
      const res = await updateStockOutLineStatusByQRCodeAndLotNo({
        pickOrderLineId: matchingLot.pickOrderLineId,
        inventoryLotNo: lotNo,
        stockOutLineId: matchingLot.stockOutLineId,
        itemId: matchingLot.itemId,
        status: "checked",
      });
      const apiTime = performance.now() - apiStartTime;
      console.log(`⏱️ API call time: ${apiTime.toFixed(2)}ms`);
  
      if (res.code === "checked" || res.code === "SUCCESS") {
        // ✅ 只更新本地状态，不调用 fetchAllCombinedLotData
        const updateStartTime = performance.now();
        const entity = res.entity as any;
        
        setCombinedLotData(prev => prev.map(lot => {
          if (lot.stockOutLineId === matchingLot.stockOutLineId &&
              lot.pickOrderLineId === matchingLot.pickOrderLineId) {
            return {
              ...lot,
              stockOutLineStatus: 'checked',
              stockOutLineQty: entity?.qty ? Number(entity.qty) : lot.stockOutLineQty,
            };
          }
          return lot;
        }));
  
        setOriginalCombinedData(prev => prev.map(lot => {
          if (lot.stockOutLineId === matchingLot.stockOutLineId &&
              lot.pickOrderLineId === matchingLot.pickOrderLineId) {
            return {
              ...lot,
              stockOutLineStatus: 'checked',
              stockOutLineQty: entity?.qty ? Number(entity.qty) : lot.stockOutLineQty,
            };
          }
          return lot;
        }));
        const updateTime = performance.now() - updateStartTime;
        console.log(`⏱️ State update time: ${updateTime.toFixed(2)}ms`);
  
        const totalTime = performance.now() - startTime;
        console.log(`✅ [FAST SCAN END] Lot: ${lotNo}`);
        console.log(`⏱️ Total time: ${totalTime.toFixed(2)}ms (${(totalTime / 1000).toFixed(3)}s)`);
        console.log(`⏰ End time: ${new Date().toISOString()}`);
      } else {
        const totalTime = performance.now() - startTime;
        console.warn(`⚠️ Fast scan failed for ${lotNo}:`, res.code);
        console.log(`⏱️ Total time: ${totalTime.toFixed(2)}ms`);
      }
    } catch (error) {
      const totalTime = performance.now() - startTime;
      console.error(`  Fast scan error for ${lotNo}:`, error);
      console.log(`⏱️ Total time: ${totalTime.toFixed(2)}ms`);
    }
  }, [combinedLotData, updateStockOutLineStatusByQRCodeAndLotNo]);


  const processOutsideQrCode = useCallback(async (latestQr: string) => {
    // 1) Parse JSON safely
    let qrData: any = null;
    try {
      qrData = JSON.parse(latestQr);
    } catch {
      console.log("QR content is not JSON; skipping lotNo direct submit to avoid false matches.");
      setQrScanError(true);
      setQrScanSuccess(false);
      return;
    }
  
    try {
      // Only use the new API when we have JSON with stockInLineId + itemId
      if (!(qrData?.stockInLineId && qrData?.itemId)) {
        console.log("QR JSON missing required fields (itemId, stockInLineId).");
        setQrScanError(true);
        setQrScanSuccess(false);
        return;
      }
  
      // Call new analyze-qr-code API
      const analysis = await analyzeQrCode({
        itemId: qrData.itemId,
        stockInLineId: qrData.stockInLineId
      });
  
      if (!analysis) {
        console.error("analyzeQrCode returned no data");
        setQrScanError(true);
        setQrScanSuccess(false);
        return;
      }
  
      const {
        itemId: analyzedItemId,
        itemCode: analyzedItemCode,
        itemName: analyzedItemName,
        scanned,
      } = analysis || {};
  
      // 1) Find all lots for the same item from current expected list
      const sameItemLotsInExpected = combinedLotData.filter(l =>
        (l.itemId && analyzedItemId && l.itemId === analyzedItemId) ||
        (l.itemCode && analyzedItemCode && l.itemCode === analyzedItemCode)
      );
  
      if (!sameItemLotsInExpected || sameItemLotsInExpected.length === 0) {
        // Case 3: No item code match
        console.error("No item match in expected lots for scanned code");
        setQrScanError(true);
        setQrScanSuccess(false);
        return;
      }
      
      // FIXED: Find the ACTIVE suggested lot (not rejected lots)
      const activeSuggestedLots = sameItemLotsInExpected.filter(lot => 
        lot.lotAvailability !== 'rejected' && 
        lot.stockOutLineStatus !== 'rejected' &&
        lot.processingStatus !== 'rejected'
      );
      
      if (activeSuggestedLots.length === 0) {
        console.error("No active suggested lots found for this item");
        setQrScanError(true);
        setQrScanSuccess(false);
        return;
      }
      
      // 2) Check if scanned lot is exactly in active suggested lots
      const exactLotMatch = activeSuggestedLots.find(l =>
        (scanned?.inventoryLotLineId && l.lotId === scanned.inventoryLotLineId) ||
        (scanned?.lotNo && l.lotNo === scanned.lotNo)
      );
  
      if (exactLotMatch && scanned?.lotNo) {
        // ✅ Case 1: 使用 updateStockOutLineStatusByQRCodeAndLotNo API（更快）
        console.log(`✅ Exact lot match found for ${scanned.lotNo}, using fast API`);
        
        if (!exactLotMatch.stockOutLineId) {
          console.warn("No stockOutLineId on exactLotMatch, cannot update status by QR.");
          setQrScanError(true);
          setQrScanSuccess(false);
          return;
        }
  
        try {
          // ✅ 直接调用后端 API，后端会处理所有匹配逻辑
          const res = await updateStockOutLineStatusByQRCodeAndLotNo({
            pickOrderLineId: exactLotMatch.pickOrderLineId,
            inventoryLotNo: scanned.lotNo,
            stockOutLineId: exactLotMatch.stockOutLineId,
            itemId: exactLotMatch.itemId,
            status: "checked",
          });
  
          console.log("updateStockOutLineStatusByQRCodeAndLotNo result:", res);
  
          // 后端返回三种 code：checked / LOT_NUMBER_MISMATCH / ITEM_MISMATCH
          if (res.code === "checked" || res.code === "SUCCESS") {
            // ✅ 完全匹配 - 只更新本地状态，不调用 fetchAllCombinedLotData
            setQrScanError(false);
            setQrScanSuccess(true);
  
            // ✅ 更新本地状态
            const entity = res.entity as any;
            
            setCombinedLotData(prev => prev.map(lot => {
              if (lot.stockOutLineId === exactLotMatch.stockOutLineId &&
                  lot.pickOrderLineId === exactLotMatch.pickOrderLineId) {
                return {
                  ...lot,
                  stockOutLineStatus: 'checked',
                  stockOutLineQty: entity?.qty ? Number(entity.qty) : lot.stockOutLineQty,
                };
              }
              return lot;
            }));
  
            setOriginalCombinedData(prev => prev.map(lot => {
              if (lot.stockOutLineId === exactLotMatch.stockOutLineId &&
                  lot.pickOrderLineId === exactLotMatch.pickOrderLineId) {
                return {
                  ...lot,
                  stockOutLineStatus: 'checked',
                  stockOutLineQty: entity?.qty ? Number(entity.qty) : lot.stockOutLineQty,
                };
              }
              return lot;
            }));
  
            console.log("✅ Status updated locally, no full data refresh needed");
          } else if (res.code === "LOT_NUMBER_MISMATCH") {
            console.warn("Backend reported LOT_NUMBER_MISMATCH:", res.message);
            setQrScanError(true);
            setQrScanSuccess(false);
          } else if (res.code === "ITEM_MISMATCH") {
            console.warn("Backend reported ITEM_MISMATCH:", res.message);
            setQrScanError(true);
            setQrScanSuccess(false);
          } else {
            console.warn("Unexpected response code from backend:", res.code);
            setQrScanError(true);
            setQrScanSuccess(false);
          }
        } catch (e) {
          console.error("Error calling updateStockOutLineStatusByQRCodeAndLotNo:", e);
          setQrScanError(true);
          setQrScanSuccess(false);
        }
  
        return; // ✅ 直接返回，不再调用 handleQrCodeSubmit
      }
  
      // Case 2: Item matches but lot number differs -> open confirmation modal
      const expectedLot = activeSuggestedLots[0];
      if (!expectedLot) {
        console.error("Could not determine expected lot for confirmation");
        setQrScanError(true);
        setQrScanSuccess(false);
        return;
      }
  
      // Check if the expected lot is already the scanned lot (after substitution)
      if (expectedLot.lotNo === scanned?.lotNo) {
        console.log(`Lot already substituted, proceeding with ${scanned.lotNo}`);
        handleQrCodeSubmit(scanned.lotNo);
        return;
      }
  
      console.log(`🔍 Lot mismatch: Expected ${expectedLot.lotNo}, Scanned ${scanned?.lotNo}`);
      setSelectedLotForQr(expectedLot);
      handleLotMismatch(
        {
          lotNo: expectedLot.lotNo,
          itemCode: analyzedItemCode || expectedLot.itemCode,
          itemName: analyzedItemName || expectedLot.itemName
        },
        {
          lotNo: scanned?.lotNo || '',
          itemCode: analyzedItemCode || expectedLot.itemCode,
          itemName: analyzedItemName || expectedLot.itemName,
          inventoryLotLineId: scanned?.inventoryLotLineId,
          stockInLineId: qrData.stockInLineId
        }
      );
    } catch (error) {
      console.error("Error during analyzeQrCode flow:", error);
      setQrScanError(true);
      setQrScanSuccess(false);
      return;
    }
  }, [combinedLotData, handleQrCodeSubmit, handleLotMismatch]); 
  //  Update the outside QR scanning effect to use enhanced processing
//  Update the outside QR scanning effect to use enhanced processing
useEffect(() => {
  if (!isManualScanning || qrValues.length === 0 || combinedLotData.length === 0 || isRefreshingData) {
    return;
  }

  const latestQr = qrValues[qrValues.length - 1];
  
  if (processedQrCodes.has(latestQr) || lastProcessedQr === latestQr) {
    console.log("QR code already processed, skipping...");
    return;
  }
  if (latestQr === "{2fic}") {
    console.log("🔍 Detected {2fic} shortcut - opening manual lot confirmation form");
    setManualLotConfirmationOpen(true);
    resetScan();
    setLastProcessedQr(latestQr);
    setProcessedQrCodes(prev => new Set(prev).add(latestQr));
    return; // 直接返回，不继续处理其他逻辑
  }
  if (latestQr && latestQr !== lastProcessedQr) {
    console.log(`🔍 Processing new QR code with enhanced validation: ${latestQr}`);
    setLastProcessedQr(latestQr);
    setProcessedQrCodes(prev => new Set(prev).add(latestQr));
    
    processOutsideQrCode(latestQr);
  }
}, [qrValues, isManualScanning, processedQrCodes, lastProcessedQr, isRefreshingData, processOutsideQrCode, combinedLotData]);
  //  Only fetch existing data when session is ready, no auto-assignment
  useEffect(() => {
    if (session && currentUserId && !initializationRef.current) {
      console.log(" Session loaded, initializing pick order...");
      initializationRef.current = true;
      
      //  Only fetch existing data, no auto-assignment
      fetchAllCombinedLotData();
    }
  }, [session, currentUserId, fetchAllCombinedLotData]);

  //  Add event listener for manual assignment
  useEffect(() => {
    const handlePickOrderAssigned = () => {
      console.log("🔄 Pick order assigned event received, refreshing data...");
      fetchAllCombinedLotData();
    };

    window.addEventListener('pickOrderAssigned', handlePickOrderAssigned);
    
    return () => {
      window.removeEventListener('pickOrderAssigned', handlePickOrderAssigned);
    };
  }, [fetchAllCombinedLotData]);



  const handleManualInputSubmit = useCallback(() => {
    if (qrScanInput.trim() !== '') {
      handleQrCodeSubmit(qrScanInput.trim());
    }
  }, [qrScanInput, handleQrCodeSubmit]);

  //  Handle QR code submission from modal (internal scanning)
  const handleQrCodeSubmitFromModal = useCallback(async (lotNo: string) => {
    if (selectedLotForQr && selectedLotForQr.lotNo === lotNo) {
      console.log(` QR Code verified for lot: ${lotNo}`);
      
      const requiredQty = selectedLotForQr.requiredQty;
      const lotId = selectedLotForQr.lotId;
      
      // Create stock out line

      
      try {
        const stockOutLineUpdate = await updateStockOutLineStatus({
          id: selectedLotForQr.stockOutLineId,
          status: 'checked',
          qty: selectedLotForQr.stockOutLineQty || 0
        });
        console.log("Stock out line updated successfully!");
        setQrScanSuccess(true);
        setQrScanError(false);

        // Close modal
        setQrModalOpen(false);
        setSelectedLotForQr(null);
        
        // Set pick quantity
        const lotKey = `${selectedLotForQr.pickOrderLineId}-${lotId}`;
        setTimeout(() => {
          setPickQtyData(prev => ({
            ...prev,
            [lotKey]: requiredQty
          }));
          console.log(` Auto-set pick quantity to ${requiredQty} for lot ${lotNo}`);
        }, 500);
        
      
      } catch (error) {
        console.error("Error creating stock out line:", error);
      }
    }
  }, [selectedLotForQr]);


  const handlePickQtyChange = useCallback((lotKey: string, value: number | string) => {
    if (value === '' || value === null || value === undefined) {
      setPickQtyData(prev => ({
        ...prev,
        [lotKey]: 0
      }));
      return;
    }
    
    const numericValue = typeof value === 'string' ? parseFloat(value) : value;
    
    if (isNaN(numericValue)) {
      setPickQtyData(prev => ({
        ...prev,
        [lotKey]: 0
      }));
      return;
    }
    
    setPickQtyData(prev => ({
      ...prev,
      [lotKey]: numericValue
    }));
  }, []);

  const [autoAssignStatus, setAutoAssignStatus] = useState<'idle' | 'checking' | 'assigned' | 'no_orders'>('idle');
  const [autoAssignMessage, setAutoAssignMessage] = useState<string>('');
  const [completionStatus, setCompletionStatus] = useState<PickOrderCompletionResponse | null>(null);

  const checkAndAutoAssignNext = useCallback(async () => {
    if (!currentUserId) return;
    
    try {
      const completionResponse = await checkPickOrderCompletion(currentUserId);
      
      if (completionResponse.code === "SUCCESS" && completionResponse.entity?.hasCompletedOrders) {
        console.log("Found completed pick orders, auto-assigning next...");
        //  移除前端的自动分配逻辑，因为后端已经处理了
        // await handleAutoAssignAndRelease(); // 删除这个函数
      }
    } catch (error) {
      console.error("Error checking pick order completion:", error);
    }
  }, [currentUserId]);

  //  Handle submit pick quantity
  const handleSubmitPickQty = useCallback(async (lot: any) => {
    const lotKey = `${lot.pickOrderLineId}-${lot.lotId}`;
    const newQty = pickQtyData[lotKey] || 0;
    
    if (!lot.stockOutLineId) {
      console.error("No stock out line found for this lot");
      return;
    }
    
    try {
      //  FIXED: Calculate cumulative quantity correctly
      const currentActualPickQty = lot.actualPickQty || 0;
      const cumulativeQty = currentActualPickQty + newQty;
      
      //  FIXED: Determine status based on cumulative quantity vs required quantity
      let newStatus = 'partially_completed';
      
      if (cumulativeQty >= lot.requiredQty) {
        newStatus = 'completed';
      } else if (cumulativeQty > 0) {
        newStatus = 'partially_completed';
      } else {
        newStatus = 'checked'; // QR scanned but no quantity submitted yet
      }
      
      console.log(`=== PICK QUANTITY SUBMISSION DEBUG ===`);
      console.log(`Lot: ${lot.lotNo}`);
      console.log(`Required Qty: ${lot.requiredQty}`);
      console.log(`Current Actual Pick Qty: ${currentActualPickQty}`);
      console.log(`New Submitted Qty: ${newQty}`);
      console.log(`Cumulative Qty: ${cumulativeQty}`);
      console.log(`New Status: ${newStatus}`);
      console.log(`=====================================`);
      
      await updateStockOutLineStatus({
        id: lot.stockOutLineId,
        status: newStatus,
        qty: cumulativeQty //  Use cumulative quantity
      });
      
      if (newQty > 0) {
        await updateInventoryLotLineQuantities({
          inventoryLotLineId: lot.lotId,
          qty: newQty,
          status: 'available',
          operation: 'pick'
        });
      }
      
      //  Check if pick order is completed when lot status becomes 'completed'
      if (newStatus === 'completed' && lot.pickOrderConsoCode) {
        console.log(` Lot ${lot.lotNo} completed, checking if pick order ${lot.pickOrderConsoCode} is complete...`);
        
        try {
          const completionResponse = await checkAndCompletePickOrderByConsoCode(lot.pickOrderConsoCode);
          console.log(` Pick order completion check result:`, completionResponse);
          
          if (completionResponse.code === "SUCCESS") {
            console.log(`�� Pick order ${lot.pickOrderConsoCode} completed successfully!`);
          } else if (completionResponse.message === "not completed") {
            console.log(`⏳ Pick order not completed yet, more lines remaining`);
          } else {
            console.error(`  Error checking completion: ${completionResponse.message}`);
          }
        } catch (error) {
          console.error("Error checking pick order completion:", error);
        }
      }
      
      await fetchAllCombinedLotData();
      console.log("Pick quantity submitted successfully!");
      
      setTimeout(() => {
        checkAndAutoAssignNext();
      }, 1000);
      
    } catch (error) {
      console.error("Error submitting pick quantity:", error);
    }
  }, [pickQtyData, fetchAllCombinedLotData, checkAndAutoAssignNext]);

  //  Handle reject lot
  const handleRejectLot = useCallback(async (lot: any) => {
    if (!lot.stockOutLineId) {
      console.error("No stock out line found for this lot");
      return;
    }
  
    try {
      await updateStockOutLineStatus({
        id: lot.stockOutLineId,
        status: 'rejected',
        qty: 0
      });
      
      await fetchAllCombinedLotData();
      console.log("Lot rejected successfully!");
      
      setTimeout(() => {
        checkAndAutoAssignNext();
      }, 1000);
      
    } catch (error) {
      console.error("Error rejecting lot:", error);
    }
  }, [fetchAllCombinedLotData, checkAndAutoAssignNext]);

  //  Handle pick execution form
  const handlePickExecutionForm = useCallback((lot: any) => {
    console.log("=== Pick Execution Form ===");
    console.log("Lot data:", lot);
    
    if (!lot) {
      console.warn("No lot data provided for pick execution form");
      return;
    }
    
    console.log("Opening pick execution form for lot:", lot.lotNo);
    
    setSelectedLotForExecutionForm(lot);
    setPickExecutionFormOpen(true);
    
    console.log("Pick execution form opened for lot ID:", lot.lotId);
  }, []);

  const handlePickExecutionFormSubmit = useCallback(async (data: any) => {
    try {
      console.log("Pick execution form submitted:", data);
      const issueData = {
        ...data,
        type: "Do",  // Delivery Order Record 类型
        pickerName: session?.user?.name || '',
      };
      
      const result = await recordPickExecutionIssue(issueData);
      console.log("Pick execution issue recorded:", result);
      
      if (result && result.code === "SUCCESS") {
        console.log(" Pick execution issue recorded successfully");
      } else {
        console.error("  Failed to record pick execution issue:", result);
      }
      
      setPickExecutionFormOpen(false);
      setSelectedLotForExecutionForm(null);
      setQrScanError(false);
      setQrScanSuccess(false);
      setQrScanInput('');
      setIsManualScanning(false);
      stopScan();
      resetScan();
      setProcessedQrCodes(new Set());
      setLastProcessedQr('');
      await fetchAllCombinedLotData();
    } catch (error) {
      console.error("Error submitting pick execution form:", error);
    }
  }, [fetchAllCombinedLotData]);

  //  Calculate remaining required quantity
  const calculateRemainingRequiredQty = useCallback((lot: any) => {
    const requiredQty = lot.requiredQty || 0;
    const stockOutLineQty = lot.stockOutLineQty || 0;
    return Math.max(0, requiredQty - stockOutLineQty);
  }, []);

  // Search criteria
  const searchCriteria: Criterion<any>[] = [
    {
      label: t("Pick Order Code"),
      paramName: "pickOrderCode",
      type: "text",
    },
      {
        label: t("Item Code"),
        paramName: "itemCode",
        type: "text",
      },
      {
        label: t("Item Name"),
        paramName: "itemName",
        type: "text",
      },
      {
      label: t("Lot No"),
      paramName: "lotNo",
      type: "text",
    },
  ];

  const handleSearch = useCallback((query: Record<string, any>) => {
    setSearchQuery({ ...query });
    console.log("Search query:", query);

    if (!originalCombinedData) return;

    const filtered = originalCombinedData.filter((lot: any) => {
      const pickOrderCodeMatch = !query.pickOrderCode || 
        lot.pickOrderCode?.toLowerCase().includes((query.pickOrderCode || "").toLowerCase());
      
        const itemCodeMatch = !query.itemCode || 
        lot.itemCode?.toLowerCase().includes((query.itemCode || "").toLowerCase());
        
        const itemNameMatch = !query.itemName || 
        lot.itemName?.toLowerCase().includes((query.itemName || "").toLowerCase());
      
      const lotNoMatch = !query.lotNo || 
        lot.lotNo?.toLowerCase().includes((query.lotNo || "").toLowerCase());
      
      return pickOrderCodeMatch && itemCodeMatch && itemNameMatch && lotNoMatch;
    });
    
    setCombinedLotData(filtered);
    console.log("Filtered lots count:", filtered.length);
  }, [originalCombinedData]);

  const handleReset = useCallback(() => {
    setSearchQuery({});
    if (originalCombinedData) {
      setCombinedLotData(originalCombinedData);
    }
  }, [originalCombinedData]);

  const handlePageChange = useCallback((event: unknown, newPage: number) => {
    setPaginationController(prev => ({
      ...prev,
      pageNum: newPage,
    }));
  }, []);

  const handlePageSizeChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
    const newPageSize = parseInt(event.target.value, 10);
    setPaginationController({
      pageNum: 0,
      pageSize: newPageSize,
    });
  }, []);

  // Pagination data with sorting by routerIndex
 // Remove the sorting logic and just do pagination
const paginatedData = useMemo(() => {
  const startIndex = paginationController.pageNum * paginationController.pageSize;
  const endIndex = startIndex + paginationController.pageSize;
  return combinedLotData.slice(startIndex, endIndex); //  No sorting needed
}, [combinedLotData, paginationController]);
const allItemsReady = useMemo(() => {
  if (combinedLotData.length === 0) return false;

  return combinedLotData.every((lot: any) => {
    const status = lot.stockOutLineStatus?.toLowerCase();
    const isRejected =
      status === 'rejected' || lot.lotAvailability === 'rejected';
    const isCompleted =
      status === 'completed' || status === 'partially_completed' || status === 'partially_complete';
    const isChecked = status === 'checked';
    const isPending = status === 'pending';

    // ✅ FIXED: 无库存（noLot）行：pending 状态也应该被视为 ready（可以提交）
    if (lot.noLot === true) {
      return isChecked || isCompleted || isRejected || isPending;
    }

    // 正常 lot：必须已扫描/提交或者被拒收
    return isChecked || isCompleted || isRejected;
  });
}, [combinedLotData]);
const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: number) => {
  if (!lot.stockOutLineId) {
    console.error("No stock out line found for this lot");
    return;
  }
  
  try {
    //  FIXED: Calculate cumulative quantity correctly
    const currentActualPickQty = lot.actualPickQty || 0;
    const cumulativeQty = currentActualPickQty + submitQty;
    
    //  FIXED: Determine status based on cumulative quantity vs required quantity
    let newStatus = 'partially_completed';
    
    if (cumulativeQty >= lot.requiredQty) {
      newStatus = 'completed';
    } else if (cumulativeQty > 0) {
      newStatus = 'partially_completed';
    } else {
      newStatus = 'checked'; // QR scanned but no quantity submitted yet
    }
    
    console.log(`=== PICK QUANTITY SUBMISSION DEBUG ===`);
    console.log(`Lot: ${lot.lotNo}`);
    console.log(`Required Qty: ${lot.requiredQty}`);
    console.log(`Current Actual Pick Qty: ${currentActualPickQty}`);
    console.log(`New Submitted Qty: ${submitQty}`);
    console.log(`Cumulative Qty: ${cumulativeQty}`);
    console.log(`New Status: ${newStatus}`);
    console.log(`=====================================`);
    
    await updateStockOutLineStatus({
      id: lot.stockOutLineId,
      status: newStatus,
      qty: cumulativeQty //  Use cumulative quantity
    });
    
    if (submitQty > 0) {
      await updateInventoryLotLineQuantities({
        inventoryLotLineId: lot.lotId,
        qty: submitQty,
        status: 'available',
        operation: 'pick'
      });
    }
    
    //  Check if pick order is completed when lot status becomes 'completed'
    if (newStatus === 'completed' && lot.pickOrderConsoCode) {
      console.log(` Lot ${lot.lotNo} completed, checking if pick order ${lot.pickOrderConsoCode} is complete...`);
      
      try {
        const completionResponse = await checkAndCompletePickOrderByConsoCode(lot.pickOrderConsoCode);
        console.log(` Pick order completion check result:`, completionResponse);
        
        if (completionResponse.code === "SUCCESS") {
          console.log(`�� Pick order ${lot.pickOrderConsoCode} completed successfully!`);
        } else if (completionResponse.message === "not completed") {
          console.log(`⏳ Pick order not completed yet, more lines remaining`);
        } else {
          console.error(`  Error checking completion: ${completionResponse.message}`);
        }
      } catch (error) {
        console.error("Error checking pick order completion:", error);
      }
    }
    
    await fetchAllCombinedLotData();
    console.log("Pick quantity submitted successfully!");
    
    setTimeout(() => {
      checkAndAutoAssignNext();
    }, 1000);
    
  } catch (error) {
    console.error("Error submitting pick quantity:", error);
  }
}, [fetchAllCombinedLotData, checkAndAutoAssignNext]);


  //  Add these functions after line 395
  const handleStartScan = useCallback(() => {
    console.log(" Starting manual QR scan...");
    setIsManualScanning(true);
    setProcessedQrCodes(new Set());
    setLastProcessedQr('');
    setQrScanError(false);
    setQrScanSuccess(false);
    startScan();
  }, [startScan]);
  const handlePickOrderSwitch = useCallback(async (pickOrderId: number) => {
    if (pickOrderSwitching) return;
    
    setPickOrderSwitching(true);
    try {
      console.log("🔍 Switching to pick order:", pickOrderId);
      setSelectedPickOrderId(pickOrderId);
      
      //  强制刷新数据，确保显示正确的 pick order 数据
      await fetchAllCombinedLotData(currentUserId, pickOrderId);
    } catch (error) {
      console.error("Error switching pick order:", error);
    } finally {
      setPickOrderSwitching(false);
      }
    }, [pickOrderSwitching, currentUserId, fetchAllCombinedLotData]);
 
  const handleStopScan = useCallback(() => {
    console.log("⏹️ Stopping manual QR scan...");
    setIsManualScanning(false);
    setQrScanError(false);
    setQrScanSuccess(false);
    stopScan();
    resetScan();
  }, [stopScan, resetScan]);
  // ... existing code around line 1469 ...
  const handlelotnull = useCallback(async (lot: any) => {
    //  优先使用 stockouts 中的 id，如果没有则使用 stockOutLineId
    const stockOutLineId = lot.stockOutLineId;
    
    if (!stockOutLineId) {
      console.error("  No stockOutLineId found for lot:", lot);
      return;
    }
    
    try {
      //  Step 1: Update stock out line status
      await updateStockOutLineStatus({
        id: stockOutLineId,
        status: 'completed',
        qty: 0
      });
      
      //  Step 2: Create pick execution issue for no-lot case
      // Get pick order ID from fgPickOrders or use 0 if not available
      const pickOrderId = lot.pickOrderId || fgPickOrders[0]?.pickOrderId || 0;
      const pickOrderCode = lot.pickOrderCode || fgPickOrders[0]?.pickOrderCode || lot.pickOrderConsoCode || '';
      
      const issueData: PickExecutionIssueData = {
        type: "Do",  // Delivery Order type
        pickOrderId: pickOrderId,
        pickOrderCode: pickOrderCode,
        pickOrderCreateDate: dayjs().format('YYYY-MM-DD'), //  Use dayjs format
        pickExecutionDate: dayjs().format('YYYY-MM-DD'),
        pickOrderLineId: lot.pickOrderLineId,
        itemId: lot.itemId,
        itemCode: lot.itemCode || '',
        itemDescription: lot.itemName || '',
        lotId: null, //  No lot available
        lotNo: null, //  No lot number
        storeLocation: lot.location || '',
        requiredQty: lot.requiredQty || lot.pickOrderLineRequiredQty || 0,
        actualPickQty: 0, //  No items picked (no lot available)
        missQty: lot.requiredQty || lot.pickOrderLineRequiredQty || 0, //  All quantity is missing
        badItemQty: 0,
        issueRemark: `No lot available for this item. Handled via handlelotnull.`,
        pickerName: session?.user?.name || '',
        
      };
      
      const result = await recordPickExecutionIssue(issueData);
      console.log(" Pick execution issue created for no-lot item:", result);
      
      if (result && result.code === "SUCCESS") {
        console.log(" No-lot item handled and issue recorded successfully");
      } else {
        console.error("  Failed to record pick execution issue:", result);
      }
      
      //  Step 3: Refresh data
      await fetchAllCombinedLotData();
    } catch (error) {
      console.error("  Error in handlelotnull:", error);
    }
  }, [fetchAllCombinedLotData, session, currentUserId, fgPickOrders]);
// ... existing code ...
const handleSubmitAllScanned = useCallback(async () => {
  const startTime = performance.now();
  console.log(`⏱️ [BATCH SUBMIT START]`);
  console.log(`⏰ Start time: ${new Date().toISOString()}`);
  
  const scannedLots = combinedLotData.filter(lot => {
    // 如果是 noLot 情况，检查状态是否为 pending 或 partially_complete
    if (lot.noLot === true) {
      return lot.stockOutLineStatus === 'checked' || 
             lot.stockOutLineStatus === 'pending' || 
             lot.stockOutLineStatus === 'partially_completed' ||
             lot.stockOutLineStatus === 'PARTIALLY_COMPLETE';
    }
    // 正常情况：只包含 checked 状态
    return lot.stockOutLineStatus === 'checked';
  });
  
  if (scannedLots.length === 0) {
    console.log("No scanned items to submit");
    return;
  }
  
  setIsSubmittingAll(true);
  console.log(`📦 Submitting ${scannedLots.length} scanned items using batchSubmitList...`);
  
  try {
    // 转换为 batchSubmitList 所需的格式（与后端 QrPickBatchSubmitRequest 匹配）
    const lines: batchSubmitListLineRequest[] = scannedLots.map((lot) => {
      const submitQty = lot.requiredQty || lot.pickOrderLineRequiredQty || 0;
      const currentActualPickQty = lot.actualPickQty || 0;
      const cumulativeQty = currentActualPickQty + submitQty;
      
      let newStatus = 'partially_completed';
      if (cumulativeQty >= (lot.requiredQty || 0)) {
        newStatus = 'completed';
      }
      
      return {
        stockOutLineId: Number(lot.stockOutLineId) || 0,
        pickOrderLineId: Number(lot.pickOrderLineId),
        inventoryLotLineId: lot.lotId ? Number(lot.lotId) : null,
        requiredQty: Number(lot.requiredQty || lot.pickOrderLineRequiredQty || 0),
        actualPickQty: Number(cumulativeQty),
        stockOutLineStatus: newStatus,
        pickOrderConsoCode: String(lot.pickOrderConsoCode || ''),
        noLot: Boolean(lot.noLot === true)
      };
    });
    
    const request: batchSubmitListRequest = {
      userId: currentUserId || 0,
      lines: lines
    };
    
    console.log(`📤 Sending batch submit request with ${lines.length} lines`);
    console.log(`📋 Request data:`, JSON.stringify(request, null, 2));
    const submitStartTime = performance.now();
    
    // 使用 batchSubmitList API
    const result = await batchSubmitList(request);
    
    const submitTime = performance.now() - submitStartTime;
    console.log(`⏱️ Batch submit API call completed in ${submitTime.toFixed(2)}ms (${(submitTime / 1000).toFixed(3)}s)`);
    console.log(`📥 Batch submit result:`, result);
    
    // Refresh data once after batch submission
    const refreshStartTime = performance.now();
    await fetchAllCombinedLotData();
    const refreshTime = performance.now() - refreshStartTime;
    console.log(`⏱️ Data refresh time: ${refreshTime.toFixed(2)}ms (${(refreshTime / 1000).toFixed(3)}s)`);
    
    const totalTime = performance.now() - startTime;
    console.log(`⏱️ [BATCH SUBMIT END]`);
    console.log(`⏱️ Total time: ${totalTime.toFixed(2)}ms (${(totalTime / 1000).toFixed(3)}s)`);
    console.log(`⏰ End time: ${new Date().toISOString()}`);
    
    if (result && result.code === "SUCCESS") {
      setQrScanSuccess(true);
      setTimeout(() => {
        setQrScanSuccess(false);
        checkAndAutoAssignNext();
        if (onSwitchToRecordTab) {
          onSwitchToRecordTab();
        }
        if (onRefreshReleasedOrderCount) {
          onRefreshReleasedOrderCount();
        }
      }, 2000);
    } else {
      console.error("Batch submit failed:", result);
      setQrScanError(true);
    }
    
  } catch (error) {
    console.error("Error submitting all scanned items:", error);
    setQrScanError(true);
  } finally {
    setIsSubmittingAll(false);
  }
}, [combinedLotData, fetchAllCombinedLotData, checkAndAutoAssignNext, currentUserId, onSwitchToRecordTab, onRefreshReleasedOrderCount]);

  //  Calculate scanned items count
    //  Calculate scanned items count (should match handleSubmitAllScanned filter logic)
    const scannedItemsCount = useMemo(() => {
      const filtered = combinedLotData.filter(lot => {
        // ✅ FIXED: 使用与 handleSubmitAllScanned 相同的过滤逻辑
        if (lot.noLot === true) {
          // ✅ 只包含可以提交的状态（与 handleSubmitAllScanned 保持一致）
          return lot.stockOutLineStatus === 'checked' || 
                 lot.stockOutLineStatus === 'pending' || 
                 lot.stockOutLineStatus === 'partially_completed' ||
                 lot.stockOutLineStatus === 'PARTIALLY_COMPLETE';
        }
        //  正常情况：只包含 checked 状态
        return lot.stockOutLineStatus === 'checked';
      });
      
      //  添加调试日志
      const noLotCount = filtered.filter(l => l.noLot === true).length;
      const normalCount = filtered.filter(l => l.noLot !== true).length;
      console.log(`📊 scannedItemsCount calculation: total=${filtered.length}, noLot=${noLotCount}, normal=${normalCount}`);
      console.log(`📊 All items breakdown:`, {
        total: combinedLotData.length,
        noLot: combinedLotData.filter(l => l.noLot === true).length,
        normal: combinedLotData.filter(l => l.noLot !== true).length
      });
      
      return filtered.length;
    }, [combinedLotData]);

  //  ADD THIS: Auto-stop scan when no data available
  useEffect(() => {
    if (isManualScanning && combinedLotData.length === 0) {
      console.log("⏹️ No data available, auto-stopping QR scan...");
      handleStopScan();
    }
  }, [combinedLotData.length, isManualScanning, handleStopScan]);

  //  Cleanup effect
  useEffect(() => {
    return () => {
      // Cleanup when component unmounts (e.g., when switching tabs)
      if (isManualScanning) {
        console.log("🧹 Pick execution component unmounting, stopping QR scanner...");
        stopScan();
        resetScan();
      }
    };
  }, [isManualScanning, stopScan, resetScan]);

  const getStatusMessage = useCallback((lot: any) => {
    switch (lot.stockOutLineStatus?.toLowerCase()) {
      case 'pending':
        return t("Please finish QR code scan and pick order.");
      case 'checked':
        return t("Please submit the pick order.");
      case 'partially_completed':
        return t("Partial quantity submitted. Please submit more or complete the order.");
      case 'completed':
        return t("Pick order completed successfully!");
      case 'rejected':
        return t("Lot has been rejected and marked as unavailable.");
      case 'unavailable':
        return t("This order is insufficient, please pick another lot.");
      default:
        return t("Please finish QR code scan and pick order.");
    }
  }, [t]);
  return (
    <TestQrCodeProvider
      lotData={combinedLotData}
      onScanLot={handleQrCodeSubmit}
      filterActive={(lot) => (
        lot.lotAvailability !== 'rejected' &&
        lot.stockOutLineStatus !== 'rejected' &&
        lot.stockOutLineStatus !== 'completed'
      )}
    >
      <FormProvider {...formProps}>
        <Stack spacing={2}>
          {/* DO Header */}

  
        
  
  {/*  保留：Combined Lot Table - 包含所有 QR 扫描功能 */}
  <Box>
    <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
      <Typography variant="h6" gutterBottom sx={{ mb: 0 }}>
        {t("All Pick Order Lots")}
      </Typography>
      
      <Box sx={{ display: 'flex', gap: 2, alignItems: 'center' }}>
        {!isManualScanning ? (
          <Button
            variant="contained"
            startIcon={<QrCodeIcon />}
            onClick={handleStartScan}
            color="primary"
            sx={{ minWidth: '120px' }}
          >
            {t("Start QR Scan")}
          </Button>
        ) : (
          <Button
            variant="outlined"
            startIcon={<QrCodeIcon />}
            onClick={handleStopScan}
            color="secondary"
            sx={{ minWidth: '120px' }}
          >
            {t("Stop QR Scan")}
          </Button>
        )}
        
        {/*  保留：Submit All Scanned Button */}
        <Button
          variant="contained"
          color="success"
          onClick={handleSubmitAllScanned}
          disabled={
           // scannedItemsCount === 0 
           !allItemsReady
            || isSubmittingAll}
          sx={{ minWidth: '160px' }}
        >
          {isSubmittingAll ? (
            <>
              <CircularProgress size={16} sx={{ mr: 1, color: 'white' }} />
              {t("Submitting...")}
            </>
          ) : (
            `${t("Submit All Scanned")} (${scannedItemsCount})`
          )}
        </Button>
      </Box>
    </Box>

  
{fgPickOrders.length > 0 && (
  <Paper sx={{ p: 2, mb: 2 }}>
    <Stack spacing={2}>
      {/* 基本信息 */}
      <Stack direction="row" spacing={4} useFlexGap flexWrap="wrap">
        <Typography variant="subtitle1">
          <strong>{t("Shop Name")}:</strong> {fgPickOrders[0].shopName || '-'}
        </Typography>
        <Typography variant="subtitle1">
          <strong>{t("Store ID")}:</strong> {fgPickOrders[0].storeId || '-'}
        </Typography>
        <Typography variant="subtitle1">
          <strong>{t("Ticket No.")}:</strong> {fgPickOrders[0].ticketNo || '-'}
        </Typography>
        <Typography variant="subtitle1">
          <strong>{t("Departure Time")}:</strong> {fgPickOrders[0].DepartureTime || '-'}
        </Typography>
      </Stack>
      
      {/*  改进：三个字段显示在一起，使用表格式布局 */}
    {/*  改进：三个字段合并显示 */}
{/*  改进：表格式显示每个 pick order */}
<Box sx={{ 
  p: 2, 
  backgroundColor: '#f5f5f5', 
  borderRadius: 1 
}}>
  <Typography variant="subtitle2" sx={{ mb: 1, fontWeight: 'bold' }}>
    {t("Pick Orders Details")}:
  </Typography>
  
  {(() => {
    const pickOrderCodes = fgPickOrders[0].pickOrderCodes as string[] | string | undefined;
    const deliveryNos = fgPickOrders[0].deliveryNos as string[] | string | undefined;
    const lineCounts = fgPickOrders[0].lineCountsPerPickOrder;
    
    const pickOrderCodesArray = Array.isArray(pickOrderCodes) 
      ? pickOrderCodes 
      : (typeof pickOrderCodes === 'string' ? pickOrderCodes.split(', ') : []);
    
    const deliveryNosArray = Array.isArray(deliveryNos) 
      ? deliveryNos 
      : (typeof deliveryNos === 'string' ? deliveryNos.split(', ') : []);
    
    const lineCountsArray = Array.isArray(lineCounts) ? lineCounts : [];
    
    const maxLength = Math.max(
      pickOrderCodesArray.length, 
      deliveryNosArray.length, 
      lineCountsArray.length
    );
    
    if (maxLength === 0) {
      return <Typography variant="body2" color="text.secondary">-</Typography>;
    }
    
    //  使用与外部基本信息相同的样式
    return Array.from({ length: maxLength }, (_, idx) => (
      <Stack 
        key={idx} 
        direction="row" 
        spacing={4} 
        useFlexGap 
        flexWrap="wrap"
        sx={{ mb: idx < maxLength - 1 ? 1 : 0 }}  // 除了最后一行，都添加底部间距
      >
        <Typography variant="subtitle1">
          <strong>{t("Delivery Order")}:</strong> {deliveryNosArray[idx] || '-'}
        </Typography>
        <Typography variant="subtitle1">
          <strong>{t("Pick Order")}:</strong> {pickOrderCodesArray[idx] || '-'}
        </Typography>
        <Typography variant="subtitle1">
          <strong>{t("Finsihed good items")}:</strong> {lineCountsArray[idx] || '-'}<strong>{t("kinds")}</strong>
        </Typography>
      </Stack>
    ));
  })()}
</Box>
    </Stack>
  </Paper>
    )}
    

            <TableContainer component={Paper}>
              <Table>
                <TableHead>
                  <TableRow>
                    <TableCell>{t("Index")}</TableCell>
                    <TableCell>{t("Route")}</TableCell>
                    <TableCell>{t("Item Code")}</TableCell>
                    <TableCell>{t("Item Name")}</TableCell>
                    <TableCell>{t("Lot#")}</TableCell>
                    <TableCell align="right">{t("Lot Required Pick Qty")}</TableCell>
                    <TableCell align="center">{t("Scan Result")}</TableCell>
                    <TableCell align="center">{t("Submit Required Pick Qty")}</TableCell>
                  </TableRow>
                </TableHead>
                <TableBody>
                  {paginatedData.length === 0 ? (
                    <TableRow>
                      <TableCell colSpan={11} align="center">
                        <Typography variant="body2" color="text.secondary">
                          {t("No data available")}
                        </Typography>
                      </TableCell>
                    </TableRow>
                  ) : (
// 在第 1797-1938 行之间，将整个 map 函数修改为：
paginatedData.map((lot, index) => {
  //  检查是否是 issue lot
  const isIssueLot = lot.stockOutLineStatus === 'rejected' || !lot.lotNo;
  
  return (
    <TableRow 
      key={`${lot.pickOrderLineId}-${lot.lotId || 'null'}`}
      sx={{
        //backgroundColor: isIssueLot ? '#fff3e0' : 'inherit',
       // opacity: isIssueLot ? 0.6 : 1,
        '& .MuiTableCell-root': {
          //color: isIssueLot ? 'warning.main' : 'inherit'
        }
      }}
    >
      <TableCell>
  <Typography variant="body2" fontWeight="bold">
    {paginationController.pageNum * paginationController.pageSize + index + 1}
  </Typography>
</TableCell>
      <TableCell>
        <Typography variant="body2">
          {lot.routerRoute || '-'}
        </Typography>
      </TableCell>
      <TableCell>{lot.itemCode}</TableCell>
      <TableCell>{lot.itemName + '(' + lot.stockUnit + ')'}</TableCell>
      <TableCell>
        <Box>
          <Typography 
            sx={{ 
             // color: isIssueLot ? 'warning.main' : lot.lotAvailability === 'rejected' ? 'text.disabled' : 'inherit',
            }}
          >
            {lot.lotNo || 
            t('⚠️ No Stock Available')}
          </Typography>
        </Box>
      </TableCell>
      <TableCell align="right">
        {(() => {
          const requiredQty = lot.requiredQty || 0;
          return requiredQty.toLocaleString() + '(' + lot.uomShortDesc + ')';
        })()}
      </TableCell>
      
      <TableCell align="center">
  {(() => {
    const status = lot.stockOutLineStatus?.toLowerCase();
    const isRejected = status === 'rejected' || lot.lotAvailability === 'rejected';
    const isNoLot = !lot.lotNo;
    
    // rejected lot：显示红色勾选（已扫描但被拒绝）
    if (isRejected && !isNoLot) {
      return (
        <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
          <Checkbox
            checked={true}
            disabled={true}
            readOnly={true}
            size="large"
            sx={{
              color: 'error.main',
              '&.Mui-checked': { color: 'error.main' },
              transform: 'scale(1.3)',
            }}
          />
        </Box>
      );
    }
    
    // 正常 lot：已扫描（checked/partially_completed/completed）
    if (!isNoLot && status !== 'pending' && status !== 'rejected') {
      return (
        <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
          <Checkbox
            checked={true}
            disabled={true}
            readOnly={true}
            size="large"
            sx={{
              color: 'success.main',
              '&.Mui-checked': { color: 'success.main' },
              transform: 'scale(1.3)',
            }}
          />
        </Box>
      );
    }
    
    // noLot 且已完成/部分完成：显示红色勾选
    if (isNoLot && (status === 'partially_completed' || status === 'completed')) {
      return (
        <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
          <Checkbox
            checked={true}
            disabled={true}
            readOnly={true}
            size="large"
            sx={{
              color: 'error.main',
              '&.Mui-checked': { color: 'error.main' },
              transform: 'scale(1.3)',
            }}
          />
        </Box>
      );
    }
    
    return null;
  })()}
</TableCell>
<TableCell align="center">
  <Box sx={{ display: 'flex', justifyContent: 'center' }}>
    {(() => {
      const status = lot.stockOutLineStatus?.toLowerCase();
      const isRejected = status === 'rejected' || lot.lotAvailability === 'rejected';
      const isNoLot = !lot.lotNo;
      
      // rejected lot：不显示任何按钮
      if (isRejected && !isNoLot) {
        return null;
      }
      
      // noLot 情况：只显示 Issue 按钮
      if (isNoLot) {
        return (
          <Button
            variant="outlined"
            size="small"
            onClick={() => handlelotnull(lot)}
            disabled={status === 'completed'}
            sx={{ 
              fontSize: '0.7rem',
              py: 0.5,
              minHeight: '28px',
              minWidth: '60px',
              borderColor: 'warning.main',
              color: 'warning.main'
            }}
          >
            {t("Issue")}
          </Button>
        );
      }
      
      // 正常 lot：显示 Submit 和 Issue 按钮
      return (
        <Stack direction="row" spacing={1} alignItems="center">
          <Button
            variant="contained"
            onClick={() => {
              const lotKey = `${lot.pickOrderLineId}-${lot.lotId}`;
              const submitQty = lot.requiredQty || lot.pickOrderLineRequiredQty;
              handlePickQtyChange(lotKey, submitQty);
              handleSubmitPickQtyWithQty(lot, submitQty);
            }}
            disabled={
              lot.lotAvailability === 'expired' || 
              lot.lotAvailability === 'status_unavailable' || 
              lot.lotAvailability === 'rejected' ||
              lot.stockOutLineStatus === 'completed' ||
              lot.stockOutLineStatus === 'pending'
            }
            sx={{ fontSize: '0.75rem', py: 0.5, minHeight: '28px', minWidth: '70px' }}
          >
            {t("Submit")}
          </Button>
          
          <Button
            variant="outlined"
            size="small"
            onClick={() => handlePickExecutionForm(lot)}
            disabled={
              lot.lotAvailability === 'expired' || 
              //lot.lotAvailability === 'status_unavailable' || 
           //   lot.lotAvailability === 'rejected' ||
              lot.stockOutLineStatus === 'completed' 
              //lot.stockOutLineStatus === 'pending'
            }
            sx={{ 
              fontSize: '0.7rem',
              py: 0.5,
              minHeight: '28px',
              minWidth: '60px',
              borderColor: 'warning.main',
              color: 'warning.main'
            }}
            title="Report missing or bad items"
          >
            {t("Issue")}
          </Button>
        </Stack>
      );
    })()}
  </Box>
</TableCell>
    </TableRow>
  );
})
                  )}
                </TableBody>
              </Table>
            </TableContainer>
            
            <TablePagination
              component="div"
              count={combinedLotData.length}
              page={paginationController.pageNum}
              rowsPerPage={paginationController.pageSize}
              onPageChange={handlePageChange}
              onRowsPerPageChange={handlePageSizeChange}
              rowsPerPageOptions={[10, 25, 50]}
              labelRowsPerPage={t("Rows per page")}
              labelDisplayedRows={({ from, to, count }) => 
                `${from}-${to} of ${count !== -1 ? count : `more than ${to}`}`
              }
            />
          </Box>
        </Stack>
  
        {/*  保留：QR Code Modal */}
        <QrCodeModal
          open={qrModalOpen}
          onClose={() => {
            setQrModalOpen(false);
            setSelectedLotForQr(null);
            stopScan();
            resetScan();
          }}
          lot={selectedLotForQr}
          combinedLotData={combinedLotData}
          onQrCodeSubmit={handleQrCodeSubmitFromModal}
        />
        <ManualLotConfirmationModal
          open={manualLotConfirmationOpen}
          onClose={() => {
            setManualLotConfirmationOpen(false);
          }}
          onConfirm={handleManualLotConfirmation}
          expectedLot={expectedLotData}
          scannedLot={scannedLotData}
          isLoading={isConfirmingLot}
        />
        {/*  保留：Lot Confirmation Modal */}
        {lotConfirmationOpen && expectedLotData && scannedLotData && (
          <LotConfirmationModal
            open={lotConfirmationOpen}
            onClose={() => {
              setLotConfirmationOpen(false);
              setExpectedLotData(null);
              setScannedLotData(null);
              if (lastProcessedQr) {
                setProcessedQrCodes(prev => {
                  const newSet = new Set(prev);
                  newSet.delete(lastProcessedQr);
                  return newSet;
                });
                setLastProcessedQr('');
              }
            }}
            onConfirm={handleLotConfirmation}
            expectedLot={expectedLotData}
            scannedLot={scannedLotData}
            isLoading={isConfirmingLot}
          />
        )}
        
        {/*  保留：Good Pick Execution Form Modal */}
        {pickExecutionFormOpen && selectedLotForExecutionForm && (
          <GoodPickExecutionForm
            open={pickExecutionFormOpen}
            onClose={() => {
              setPickExecutionFormOpen(false);
              setSelectedLotForExecutionForm(null);
            }}
            onSubmit={handlePickExecutionFormSubmit}
            selectedLot={selectedLotForExecutionForm}
            selectedPickOrderLine={{
              id: selectedLotForExecutionForm.pickOrderLineId,
              itemId: selectedLotForExecutionForm.itemId,
              itemCode: selectedLotForExecutionForm.itemCode,
              itemName: selectedLotForExecutionForm.itemName,
              pickOrderCode: selectedLotForExecutionForm.pickOrderCode,
              availableQty: selectedLotForExecutionForm.availableQty || 0,
              requiredQty: selectedLotForExecutionForm.requiredQty || 0,
             // uomCode: selectedLotForExecutionForm.uomCode || '',
              uomDesc: selectedLotForExecutionForm.uomDesc || '',
              pickedQty: selectedLotForExecutionForm.actualPickQty || 0,
              uomShortDesc: selectedLotForExecutionForm.uomShortDesc || '',
              suggestedList: [],
              noLotLines: [],
            }}
            pickOrderId={selectedLotForExecutionForm.pickOrderId}
            pickOrderCreateDate={new Date()}
          />
        )}
      </FormProvider>

  
    
      
    </TestQrCodeProvider>
  );
};

export default PickExecution;
