"use client";

import {
  Box,
  Button,
  Stack,
  TextField,
  Typography,
  Alert,
  CircularProgress,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
  Checkbox,
  TablePagination,
  Modal,
} from "@mui/material";
import TestQrCodeProvider from '../QrCodeScannerProvider/TestQrCodeProvider';
import { useCallback, useEffect, useState, useRef, useMemo, startTransition } from "react";
import { useTranslation } from "react-i18next";
import { useRouter } from "next/navigation";
import {
  updateStockOutLineStatus,
  createStockOutLine,
  recordPickExecutionIssue,
  fetchFGPickOrders,
  FGPickOrderResponse, 
  autoAssignAndReleasePickOrder, 
  AutoAssignReleaseResponse,
  checkPickOrderCompletion,
  PickOrderCompletionResponse,
  checkAndCompletePickOrderByConsoCode,
  confirmLotSubstitution,
  updateStockOutLineStatusByQRCodeAndLotNo,
  batchSubmitList,
  batchSubmitListRequest,
  batchSubmitListLineRequest,
} from "@/app/api/pickOrder/actions";
//  修改：使用 Job Order API
import { 
  fetchJobOrderLotsHierarchical,
  fetchUnassignedJobOrderPickOrders,
  assignJobOrderPickOrder,
  updateJo,
  JobOrderLotsHierarchicalResponse,
} from "@/app/api/jo/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, analyzeQrCode, fetchLotDetail  } 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 "./JobPickExecutionForm";
import FGPickOrderCard from "./FGPickOrderCard"; 
import LotConfirmationModal from "./LotConfirmationModal";
interface Props {
  filterArgs: Record<string, any>;
}

// Manual Lot Confirmation Modal Component
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("jo");
  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>
  );
};

//  QR Code Modal Component (from GoodPickExecution)
const QrCodeModal: React.FC<{
  open: boolean;
  onClose: () => void;
  lot: any | null;
  onQrCodeSubmit: (lotNo: string) => void;
  combinedLotData: any[];
}> = ({ open, onClose, lot, onQrCodeSubmit, combinedLotData }) => {
  const { t } = useTranslation("jo");
  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>('');
  
  // 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 JobPickExecution: React.FC<Props> = ({ filterArgs }) => {
  const { t } = useTranslation("jo");
  const router = useRouter();
  const { data: session } = useSession() as { data: SessionWithTokens | null };
  
  const currentUserId = session?.id ? parseInt(session.id) : undefined;
  const [jobOrderData, setJobOrderData] = useState<JobOrderLotsHierarchicalResponse | null>(null);
  //  修改：使用 Job Order 数据结构
  const [filteredLotData, setFilteredLotData] = useState<any[]>([]);
  

  const [combinedDataLoading, setCombinedDataLoading] = useState(false);

  const [unassignedOrders, setUnassignedOrders] = useState<any[]>([]);
  const [isLoadingUnassigned, setIsLoadingUnassigned] = useState(false);
  
  const { values: qrValues, isScanning, startScan, stopScan, resetScan } = useQrCodeScannerContext();
  const [lotConfirmationOpen, setLotConfirmationOpen] = useState(false);
  const [expectedLotData, setExpectedLotData] = useState<any>(null);
  const [scannedLotData, setScannedLotData] = useState<any>(null);
  const [isConfirmingLot, setIsConfirmingLot] = useState(false);
  const [qrScanInput, setQrScanInput] = useState<string>('');
  const [qrScanError, setQrScanError] = useState<boolean>(false);
  const [qrScanSuccess, setQrScanSuccess] = useState<boolean>(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;
  const [isSubmittingAll, setIsSubmittingAll] = useState<boolean>(false);

  //  Add QR modal states
  const [qrModalOpen, setQrModalOpen] = useState(false);
  const [selectedLotForQr, setSelectedLotForQr] = useState<any | null>(null);

  //  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
  const [isManualScanning, setIsManualScanning] = useState<boolean>(false);
  // Track processed QR codes by itemId+stockInLineId combination for better lot confirmation handling
  const [processedQrCombinations, setProcessedQrCombinations] = useState<Map<number, Set<number>>>(new Map());
  const [processedQrCodes, setProcessedQrCodes] = useState<Set<string>>(new Set());
  const [lastProcessedQr, setLastProcessedQr] = useState<string>('');
  const [isRefreshingData, setIsRefreshingData] = useState<boolean>(false);
  
  // Cache for fetchStockInLineInfo API calls to avoid redundant requests
  const stockInLineInfoCache = useRef<Map<number, { lotNo: string | null; timestamp: number }>>(new Map());
  const CACHE_TTL = 60000; // 60 seconds cache TTL
  const abortControllerRef = useRef<AbortController | null>(null);
  const qrProcessingTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  
  // Use refs for processed QR tracking to avoid useEffect dependency issues and delays
  const processedQrCodesRef = useRef<Set<string>>(new Set());
  const lastProcessedQrRef = useRef<string>('');
  
  // Store callbacks in refs to avoid useEffect dependency issues
  const processOutsideQrCodeRef = useRef<((latestQr: string) => Promise<void>) | null>(null);
  const resetScanRef = useRef<(() => void) | null>(null);
  
  // Add Manual Lot Confirmation Modal state
  const [manualLotConfirmationOpen, setManualLotConfirmationOpen] = useState(false);



  const getAllLotsFromHierarchical = useCallback((
    data: JobOrderLotsHierarchicalResponse | null
  ): any[] => {
    if (!data || !data.pickOrder || !data.pickOrderLines) {
      return [];
    }

    const allLots: any[] = [];
    
    data.pickOrderLines.forEach((line) => {
      if (line.lots && line.lots.length > 0) {
        line.lots.forEach((lot) => {
          allLots.push({
            ...lot,
            pickOrderLineId: line.id,
            itemId: line.itemId,
            itemCode: line.itemCode,
            itemName: line.itemName,
            uomCode: line.uomCode,
            uomDesc: line.uomDesc,
            pickOrderLineRequiredQty: line.requiredQty,
            pickOrderLineStatus: line.status,
            jobOrderId: data.pickOrder.jobOrder.id,
            jobOrderCode: data.pickOrder.jobOrder.code,
            // 添加 pickOrder 信息（如果需要）
            pickOrderId: data.pickOrder.id,
            pickOrderCode: data.pickOrder.code,
            pickOrderConsoCode: data.pickOrder.consoCode,
            pickOrderTargetDate: data.pickOrder.targetDate,
            pickOrderType: data.pickOrder.type,
            pickOrderStatus: data.pickOrder.status,
            pickOrderAssignTo: data.pickOrder.assignTo,
          });
        });
      }
    });
    
    return allLots;
  }, []);
  const allLotsFromData = useMemo(() => {
    return getAllLotsFromHierarchical(jobOrderData);
  }, [jobOrderData, getAllLotsFromHierarchical]);
  
  // 用于显示的 combinedLotData（支持搜索过滤）
  const combinedLotData = useMemo(() => {
    return filteredLotData.length > 0 ? filteredLotData : allLotsFromData;
  }, [filteredLotData, allLotsFromData]);
  
  // 用于搜索的原始数据
  const originalCombinedData = useMemo(() => {
    return allLotsFromData;
  }, [allLotsFromData]);
  
  // Enhanced lotDataIndexes with cached active lots for better performance
  const lotDataIndexes = useMemo(() => {
    const indexStartTime = performance.now();
    console.log(`⏱️ [PERF] lotDataIndexes calculation START, data length: ${combinedLotData.length}`);
    
    const byItemId = new Map<number, any[]>();
    const byItemCode = new Map<string, any[]>();
    const byLotId = new Map<number, any>();
    const byLotNo = new Map<string, any[]>();
    const byStockInLineId = new Map<number, any[]>();
    // Cache active lots separately to avoid filtering on every scan
    const activeLotsByItemId = new Map<number, any[]>();
    const rejectedStatuses = new Set(['rejected']);
    
    // ✅ Use for loop instead of forEach for better performance on tablets
    for (let i = 0; i < combinedLotData.length; i++) {
      const lot = combinedLotData[i];
      const isActive = !rejectedStatuses.has(lot.lotAvailability) && 
                       !rejectedStatuses.has(lot.stockOutLineStatus) &&
                       !rejectedStatuses.has(lot.processingStatus);
      
      if (lot.itemId) {
        if (!byItemId.has(lot.itemId)) {
          byItemId.set(lot.itemId, []);
          activeLotsByItemId.set(lot.itemId, []);
        }
        byItemId.get(lot.itemId)!.push(lot);
        if (isActive) {
          activeLotsByItemId.get(lot.itemId)!.push(lot);
        }
      }
      
      if (lot.itemCode) {
        if (!byItemCode.has(lot.itemCode)) {
          byItemCode.set(lot.itemCode, []);
        }
        byItemCode.get(lot.itemCode)!.push(lot);
      }
      
      if (lot.lotId) {
        byLotId.set(lot.lotId, lot);
      }
      
      if (lot.lotNo) {
        if (!byLotNo.has(lot.lotNo)) {
          byLotNo.set(lot.lotNo, []);
        }
        byLotNo.get(lot.lotNo)!.push(lot);
      }
      
      if (lot.stockInLineId) {
        if (!byStockInLineId.has(lot.stockInLineId)) {
          byStockInLineId.set(lot.stockInLineId, []);
        }
        byStockInLineId.get(lot.stockInLineId)!.push(lot);
      }
    }
    
    const indexTime = performance.now() - indexStartTime;
    if (indexTime > 10) {
      console.log(`⏱️ [PERF] lotDataIndexes calculation END: ${indexTime.toFixed(2)}ms (${(indexTime / 1000).toFixed(3)}s)`);
    }
    
    return { byItemId, byItemCode, byLotId, byLotNo, byStockInLineId, activeLotsByItemId };
  }, [combinedLotData.length, combinedLotData]);
  
  // Cached version of fetchStockInLineInfo to avoid redundant API calls
  const fetchStockInLineInfoCached = useCallback(async (stockInLineId: number): Promise<{ lotNo: string | null }> => {
    const now = Date.now();
    const cached = stockInLineInfoCache.current.get(stockInLineId);
    
    // Return cached value if still valid
    if (cached && (now - cached.timestamp) < CACHE_TTL) {
      console.log(`✅ [CACHE HIT] Using cached stockInLineInfo for ${stockInLineId}`);
      return { lotNo: cached.lotNo };
    }
    
    // Cancel previous request if exists
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }
    
    // Create new abort controller for this request
    const abortController = new AbortController();
    abortControllerRef.current = abortController;
    
    try {
      console.log(`⏱️ [CACHE MISS] Fetching stockInLineInfo for ${stockInLineId}`);
      const stockInLineInfo = await fetchStockInLineInfo(stockInLineId);
      
      // Store in cache
      stockInLineInfoCache.current.set(stockInLineId, {
        lotNo: stockInLineInfo.lotNo || null,
        timestamp: now
      });
      
      // Limit cache size to prevent memory leaks
      if (stockInLineInfoCache.current.size > 100) {
        const firstKey = stockInLineInfoCache.current.keys().next().value;
        if (firstKey !== undefined) {
          stockInLineInfoCache.current.delete(firstKey);
        }
      }
      
      return { lotNo: stockInLineInfo.lotNo || null };
    } catch (error: any) {
      if (error.name === 'AbortError') {
        console.log(`⏱️ [CACHE] Request aborted for ${stockInLineId}`);
        throw error;
      }
      console.error(`❌ [CACHE] Error fetching stockInLineInfo for ${stockInLineId}:`, error);
      throw error;
    }
  }, []);
  //  修改：加载未分配的 Job Order 订单
  const loadUnassignedOrders = useCallback(async () => {
    setIsLoadingUnassigned(true);
    try {
      const orders = await fetchUnassignedJobOrderPickOrders();
      setUnassignedOrders(orders);
    } catch (error) {
      console.error("Error loading unassigned orders:", error);
    } finally {
      setIsLoadingUnassigned(false);
    }
  }, []);

  //  修改：分配订单给当前用户
  const handleAssignOrder = useCallback(async (pickOrderId: number) => {
    if (!currentUserId) {
      console.error("Missing user id in session");
      return;
    }
    
    try {
      const result = await assignJobOrderPickOrder(pickOrderId, currentUserId);
      if (result.message === "Successfully assigned") {
        console.log(" Successfully assigned pick order");
        // 刷新数据
        window.dispatchEvent(new CustomEvent('pickOrderAssigned'));
        // 重新加载未分配订单列表
        loadUnassignedOrders();
      } else {
        console.warn("⚠️ Assignment failed:", result.message);
        alert(`Assignment failed: ${result.message}`);
      }
    } catch (error) {
      console.error("❌ Error assigning order:", error);
      alert("Error occurred during assignment");
    }
  }, [currentUserId, loadUnassignedOrders]);

  const fetchFgPickOrdersData = useCallback(async () => {
    if (!currentUserId) return;
    
    setFgPickOrdersLoading(true);
    try {
      // Get all pick order IDs from combinedLotData
      const pickOrderIds = Array.from(new Set(combinedLotData.map(lot => lot.pickOrderId)));
      
      if (pickOrderIds.length === 0) {
        setFgPickOrders([]);
        return;
      }
      
      // Fetch FG pick orders for each pick order ID
      const fgPickOrdersPromises = pickOrderIds.map(pickOrderId => 
        fetchFGPickOrders(pickOrderId)
      );
      
      const fgPickOrdersResults = await Promise.all(fgPickOrdersPromises);
      
      // Flatten the results (each fetchFGPickOrders returns an array)
      const allFgPickOrders = fgPickOrdersResults.flat();
      
      setFgPickOrders(allFgPickOrders);
      console.log(" Fetched FG pick orders:", allFgPickOrders);
    } catch (error) {
      console.error("❌ Error fetching FG pick orders:", error);
      setFgPickOrders([]);
    } finally {
      setFgPickOrdersLoading(false);
    }
  }, [currentUserId, combinedLotData]);

  useEffect(() => {
    if (combinedLotData.length > 0) {
      fetchFgPickOrdersData();
    }
  }, [combinedLotData, fetchFgPickOrdersData]);

  //  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 getPickOrderId = useCallback(() => {
    return filterArgs?.pickOrderId ? Number(filterArgs.pickOrderId) : undefined;
  }, [filterArgs?.pickOrderId]);
  //  修改：使用 Job Order API 获取数据
  const fetchJobOrderData = useCallback(async (userId?: number) => {
    setCombinedDataLoading(true);
    try {
      const userIdToUse = userId || currentUserId;
      
      if (!userIdToUse) {
        console.warn("⚠️ No userId available, skipping API call");
        setJobOrderData(null);
        return;
      }
      
      window.dispatchEvent(new CustomEvent('jobOrderDataStatus', {
        detail: { 
          hasData: false,
          tabIndex: 0
        }
      }));
      
      // 直接使用类型化的响应
      const jobOrderData = await fetchJobOrderLotsHierarchical(userIdToUse);
      console.log(" Job Order data (hierarchical):", jobOrderData);
      
      setJobOrderData(jobOrderData);
      
      // 使用辅助函数获取所有 lots（用于计算完成状态等）
      const allLots = getAllLotsFromHierarchical(jobOrderData);
      setFilteredLotData(allLots);
      const hasData = allLots.length > 0;
      
      window.dispatchEvent(new CustomEvent('jobOrderDataStatus', {
        detail: { 
          hasData: hasData,
          tabIndex: 0
        }
      }));
      
      // 计算完成状态
      const allCompleted = allLots.length > 0 && allLots.every((lot) => 
        lot.processingStatus === 'completed'
      );
      
      window.dispatchEvent(new CustomEvent('pickOrderCompletionStatus', {
        detail: { 
          allLotsCompleted: allCompleted,
          tabIndex: 0
        }
      }));
      
    } catch (error) {
      console.error("❌ Error fetching job order data:", error);
      setJobOrderData(null);
      
      window.dispatchEvent(new CustomEvent('pickOrderCompletionStatus', {
        detail: { 
          allLotsCompleted: false,
          tabIndex: 0
        }
      }));
    } finally {
      setCombinedDataLoading(false);
    }
  }, [currentUserId, getAllLotsFromHierarchical]);

  //  修改：初始化时加载数据
  useEffect(() => {
    if (session && currentUserId && !initializationRef.current) {
      console.log(" Session loaded, initializing job order...");
      initializationRef.current = true;
      
      // 加载 Job Order 数据
      fetchJobOrderData();
      // 加载未分配订单
      loadUnassignedOrders();
    }
  }, [session, currentUserId, fetchJobOrderData, loadUnassignedOrders]);
  
  // Auto-start scanner only once on mount
  const scannerInitializedRef = useRef(false);
  
  // Separate effect for auto-starting scanner (only once, prevents multiple resets)
  useEffect(() => {
    if (session && currentUserId && !scannerInitializedRef.current) {
      scannerInitializedRef.current = true;
      // ✅ Auto-start scanner on mount for tablet use (background mode - no modal)
      console.log("✅ Auto-starting QR scanner in background mode");
      setIsManualScanning(true);
      startScan();
    }
  }, [session, currentUserId, startScan]);

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

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

  //  Handle QR code submission for matched lot (external scanning)
  const handleQrCodeSubmit = useCallback(async (lotNo: string) => {
    console.log(` Processing QR Code for lot: ${lotNo}`);
    
    //  Use current data without refreshing to avoid infinite loop
    const currentLotData = combinedLotData;
    console.log(`🔍 Available lots:`, currentLotData.map(lot => lot.lotNo));
    
    const matchingLots = currentLotData.filter(lot => 
      lot.lotNo === lotNo || 
      lot.lotNo?.toLowerCase() === lotNo.toLowerCase()
    );
    
    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 fetchJobOrderData();
      
      if (successCount > 0) {
        console.log(` QR Code processing completed: ${successCount} updated/created`);
    setQrScanSuccess(true);
    setQrScanError(false);
        setQrScanInput(''); // Clear input after successful processing
   
      } else {
        console.error(`❌ QR Code processing failed: ${errorCount} errors`);
        setQrScanError(true);
        setQrScanSuccess(false);
      }
    } catch (error) {
      console.error("❌ Error processing QR code:", error);
      setQrScanError(true);
      setQrScanSuccess(false);
      
      //  Still refresh data even on error
      setIsRefreshingData(true);
      await fetchJobOrderData();
    } finally {
      //  Clear refresh flag after a short delay
      setTimeout(() => {
        setIsRefreshingData(false);
      }, 1000);
    }
  }, [combinedLotData, fetchJobOrderData]);
  const handleLotMismatch = useCallback((expectedLot: any, scannedLot: any) => {
    const mismatchStartTime = performance.now();
    console.log(`⏱️ [HANDLE LOT MISMATCH START]`);
    console.log(`⏰ Start time: ${new Date().toISOString()}`);
    console.log("Lot mismatch detected:", { expectedLot, scannedLot });
    
    // ✅ Use setTimeout to avoid flushSync warning - schedule modal update in next tick
    const setTimeoutStartTime = performance.now();
    console.time('setLotConfirmationOpen');
    setTimeout(() => {
      const setStateStartTime = performance.now();
      setExpectedLotData(expectedLot);
      setScannedLotData({
        ...scannedLot,
        lotNo: scannedLot.lotNo || null,
      });
      setLotConfirmationOpen(true);
      const setStateTime = performance.now() - setStateStartTime;
      console.timeEnd('setLotConfirmationOpen');
      console.log(`⏱️ [HANDLE LOT MISMATCH] Modal state set to open (setState time: ${setStateTime.toFixed(2)}ms)`);
      console.log(`✅ [HANDLE LOT MISMATCH] Modal state set to open`);
    }, 0);
    const setTimeoutTime = performance.now() - setTimeoutStartTime;
    console.log(`⏱️ [PERF] setTimeout scheduling time: ${setTimeoutTime.toFixed(2)}ms`);
    
    // ✅ Fetch lotNo in background ONLY for display purposes (using cached version)
    if (!scannedLot.lotNo && scannedLot.stockInLineId) {
      const stockInLineId = scannedLot.stockInLineId;
      if (typeof stockInLineId !== 'number') {
        console.warn(`⏱️ [HANDLE LOT MISMATCH] Invalid stockInLineId: ${stockInLineId}`);
        return;
      }
      console.log(`⏱️ [HANDLE LOT MISMATCH] Fetching lotNo in background (stockInLineId: ${stockInLineId})`);
      const fetchStartTime = performance.now();
      
      fetchStockInLineInfoCached(stockInLineId)
        .then((stockInLineInfo) => {
          const fetchTime = performance.now() - fetchStartTime;
          console.log(`⏱️ [HANDLE LOT MISMATCH] fetchStockInLineInfoCached time: ${fetchTime.toFixed(2)}ms (${(fetchTime / 1000).toFixed(3)}s)`);
          
          const updateStateStartTime = performance.now();
          startTransition(() => {
            setScannedLotData((prev: any) => ({
              ...prev,
              lotNo: stockInLineInfo.lotNo || null,
            }));
          });
          const updateStateTime = performance.now() - updateStateStartTime;
          console.log(`⏱️ [PERF] Update scanned lot data time: ${updateStateTime.toFixed(2)}ms`);
          
          const totalTime = performance.now() - mismatchStartTime;
          console.log(`⏱️ [HANDLE LOT MISMATCH] Background fetch completed: ${totalTime.toFixed(2)}ms (${(totalTime / 1000).toFixed(3)}s)`);
        })
        .catch((error) => {
          if (error.name !== 'AbortError') {
            const fetchTime = performance.now() - fetchStartTime;
            console.error(`❌ [HANDLE LOT MISMATCH] fetchStockInLineInfoCached failed after ${fetchTime.toFixed(2)}ms:`, error);
          }
        });
    } else {
      const totalTime = performance.now() - mismatchStartTime;
      console.log(`⏱️ [HANDLE LOT MISMATCH END] Total time: ${totalTime.toFixed(2)}ms (${(totalTime / 1000).toFixed(3)}s)`);
    }
  }, [fetchStockInLineInfoCached]);

  //  Add handleLotConfirmation function
  const handleLotConfirmation = useCallback(async () => {
    if (!expectedLotData || !scannedLotData || !selectedLotForQr) return;
    setIsConfirmingLot(true);
    try {
      const newLotNo = scannedLotData?.lotNo;
      const newStockInLineId = scannedLotData?.stockInLineId;
    
      await confirmLotSubstitution({
        pickOrderLineId: selectedLotForQr.pickOrderLineId,
        stockOutLineId: selectedLotForQr.stockOutLineId,
        originalSuggestedPickLotId: selectedLotForQr.suggestedPickLotId,
        newInventoryLotNo: "",             
        newStockInLineId: newStockInLineId    
      });
  
      setQrScanError(false);
      setQrScanSuccess(false);
      setQrScanInput('');
      
      // ✅ 修复：在确认后重置扫描状态，避免重复处理
      resetScan();
      
      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 fetchJobOrderData();
      setIsRefreshingData(false);
    } catch (error) {
      console.error("Error confirming lot substitution:", error);
    } finally {
      setIsConfirmingLot(false);
    }
  }, [expectedLotData, scannedLotData, selectedLotForQr, fetchJobOrderData, resetScan]);
  
  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;
        
        if (filteredLotData.length > 0) {
          setFilteredLotData(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 fetchJobOrderData();
      } else if (res.code === "LOT_NUMBER_MISMATCH") {
        console.warn("⚠️ Backend reported LOT_NUMBER_MISMATCH:", res.message);
        
        // ✅ 打开 lot confirmation modal 而不是显示 alert
        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, filteredLotData, fetchJobOrderData, t]);
  
  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") {
        // ✅ 只更新本地状态，不调用 fetchJobOrderData
        const updateStartTime = performance.now();
        const entity = res.entity as any;
        
        if (filteredLotData.length > 0) {
          setFilteredLotData(prev => prev.map((lot: any) => {
            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, filteredLotData]);
  const processOutsideQrCode = useCallback(async (latestQr: string) => {
    const totalStartTime = performance.now();
    console.log(`⏱️ [PROCESS OUTSIDE QR START] QR: ${latestQr.substring(0, 50)}...`);
    console.log(`⏰ Start time: ${new Date().toISOString()}`);
    
    // ✅ Measure index access time
    const indexAccessStart = performance.now();
    const indexes = lotDataIndexes; // Access the memoized indexes
    const indexAccessTime = performance.now() - indexAccessStart;
    console.log(`⏱️ [PERF] Index access time: ${indexAccessTime.toFixed(2)}ms`);
    
    // 1) Parse JSON safely (parse once, reuse)
    const parseStartTime = performance.now();
    let qrData: any = null;
    let parseTime = 0;
    try {
      qrData = JSON.parse(latestQr);
      parseTime = performance.now() - parseStartTime;
      console.log(`⏱️ [PERF] JSON parse time: ${parseTime.toFixed(2)}ms`);
    } catch {
      console.log("QR content is not JSON; skipping lotNo direct submit to avoid false matches.");
      startTransition(() => {
        setQrScanError(true);
        setQrScanSuccess(false);
      });
      return;
    }
  
    try {
      const validationStartTime = performance.now();
      if (!(qrData?.stockInLineId && qrData?.itemId)) {
        console.log("QR JSON missing required fields (itemId, stockInLineId).");
        startTransition(() => {
          setQrScanError(true);
          setQrScanSuccess(false);
        });
        return;
      }
      const validationTime = performance.now() - validationStartTime;
      console.log(`⏱️ [PERF] Validation time: ${validationTime.toFixed(2)}ms`);
  
      const scannedItemId = qrData.itemId;
      const scannedStockInLineId = qrData.stockInLineId;
      
      // ✅ Check if this combination was already processed
      const duplicateCheckStartTime = performance.now();
      const itemProcessedSet = processedQrCombinations.get(scannedItemId);
      if (itemProcessedSet?.has(scannedStockInLineId)) {
        const duplicateCheckTime = performance.now() - duplicateCheckStartTime;
        console.log(`⏱️ [SKIP] Already processed combination: itemId=${scannedItemId}, stockInLineId=${scannedStockInLineId} (check time: ${duplicateCheckTime.toFixed(2)}ms)`);
        return;
      }
      const duplicateCheckTime = performance.now() - duplicateCheckStartTime;
      console.log(`⏱️ [PERF] Duplicate check time: ${duplicateCheckTime.toFixed(2)}ms`);
      
      // ✅ OPTIMIZATION: Use cached active lots directly (no filtering needed)
      const lookupStartTime = performance.now();
      const activeSuggestedLots = indexes.activeLotsByItemId.get(scannedItemId) || [];
      const lookupTime = performance.now() - lookupStartTime;
      console.log(`⏱️ [PERF] Index lookup time: ${lookupTime.toFixed(2)}ms, found ${activeSuggestedLots.length} active lots`);
      
      if (activeSuggestedLots.length === 0) {
        console.error("No active suggested lots found for this item");
        startTransition(() => {
          setQrScanError(true);
          setQrScanSuccess(false);
        });
        return;
      }
      
      // ✅ OPTIMIZATION: Direct Map lookup for stockInLineId match (O(1))
      const matchStartTime = performance.now();
      let exactMatch: any = null;
      const stockInLineLots = indexes.byStockInLineId.get(scannedStockInLineId) || [];
      // Find exact match from stockInLineId index, then verify it's in active lots
      for (let i = 0; i < stockInLineLots.length; i++) {
        const lot = stockInLineLots[i];
        if (lot.itemId === scannedItemId && activeSuggestedLots.includes(lot)) {
          exactMatch = lot;
          break;
        }
      }
      const matchTime = performance.now() - matchStartTime;
      console.log(`⏱️ [PERF] Find exact match time: ${matchTime.toFixed(2)}ms, found: ${exactMatch ? 'yes' : 'no'}`);
      
      if (exactMatch) {
        // ✅ Case 1: stockInLineId 匹配 - 直接处理，不需要确认
        console.log(`✅ Exact stockInLineId match found for lot: ${exactMatch.lotNo}`);
        
        if (!exactMatch.stockOutLineId) {
          console.warn("No stockOutLineId on exactMatch, cannot update status by QR.");
          startTransition(() => {
            setQrScanError(true);
            setQrScanSuccess(false);
          });
          return;
        }
  
        try {
          const apiStartTime = performance.now();
          console.log(`⏱️ [API CALL START] Calling updateStockOutLineStatusByQRCodeAndLotNo`);
          console.log(`⏰ [API CALL] API start time: ${new Date().toISOString()}`);
          const res = await updateStockOutLineStatusByQRCodeAndLotNo({
            pickOrderLineId: exactMatch.pickOrderLineId,
            inventoryLotNo: exactMatch.lotNo,
            stockOutLineId: exactMatch.stockOutLineId,
            itemId: exactMatch.itemId,
            status: "checked",
          });
          const apiTime = performance.now() - apiStartTime;
          console.log(`⏱️ [API CALL END] Total API time: ${apiTime.toFixed(2)}ms (${(apiTime / 1000).toFixed(3)}s)`);
          console.log(`⏰ [API CALL] API end time: ${new Date().toISOString()}`);
  
          if (res.code === "checked" || res.code === "SUCCESS") {
            const entity = res.entity as any;
            
            // ✅ Batch state updates using startTransition
            const stateUpdateStartTime = performance.now();
            startTransition(() => {
              setQrScanError(false);
              setQrScanSuccess(true);
              
              // Update filteredLotData if it exists, otherwise update allLotsFromData via refresh
              if (filteredLotData.length > 0) {
                setFilteredLotData(prev => prev.map((lot: any) => {
                  if (lot.stockOutLineId === exactMatch.stockOutLineId &&
                      lot.pickOrderLineId === exactMatch.pickOrderLineId) {
                    return {
                      ...lot,
                      stockOutLineStatus: 'checked',
                      stockOutLineQty: entity?.qty ?? lot.stockOutLineQty,
                    };
                  }
                  return lot;
                }));
              }
            });
            const stateUpdateTime = performance.now() - stateUpdateStartTime;
            console.log(`⏱️ [PERF] State update time: ${stateUpdateTime.toFixed(2)}ms`);
            
            // Mark this combination as processed
            const markProcessedStartTime = performance.now();
            setProcessedQrCombinations(prev => {
              const newMap = new Map(prev);
              if (!newMap.has(scannedItemId)) {
                newMap.set(scannedItemId, new Set());
              }
              newMap.get(scannedItemId)!.add(scannedStockInLineId);
              return newMap;
            });
            const markProcessedTime = performance.now() - markProcessedStartTime;
            console.log(`⏱️ [PERF] Mark processed time: ${markProcessedTime.toFixed(2)}ms`);
  
            // Refresh data to ensure consistency
            await fetchJobOrderData();
            
            const totalTime = performance.now() - totalStartTime;
            console.log(`✅ [PROCESS OUTSIDE QR END] Total time: ${totalTime.toFixed(2)}ms (${(totalTime / 1000).toFixed(3)}s)`);
            console.log(`⏰ End time: ${new Date().toISOString()}`);
            console.log(`📊 Breakdown: parse=${parseTime.toFixed(2)}ms, validation=${validationTime.toFixed(2)}ms, duplicateCheck=${duplicateCheckTime.toFixed(2)}ms, lookup=${lookupTime.toFixed(2)}ms, match=${matchTime.toFixed(2)}ms, api=${apiTime.toFixed(2)}ms, stateUpdate=${stateUpdateTime.toFixed(2)}ms, markProcessed=${markProcessedTime.toFixed(2)}ms`);
            console.log("✅ Status updated, data refreshed");
          } else {
            console.warn("Unexpected response code from backend:", res.code);
            startTransition(() => {
              setQrScanError(true);
              setQrScanSuccess(false);
            });
          }
        } catch (e) {
          const totalTime = performance.now() - totalStartTime;
          console.error(`❌ [PROCESS OUTSIDE QR ERROR] Total time: ${totalTime.toFixed(2)}ms`);
          console.error("Error calling updateStockOutLineStatusByQRCodeAndLotNo:", e);
          startTransition(() => {
            setQrScanError(true);
            setQrScanSuccess(false);
          });
        }
  
        return; // ✅ 直接返回，不需要确认表单
      }
      
      // ✅ Case 2: itemId 匹配但 stockInLineId 不匹配 - 显示确认表单
      // Check if we should allow reopening (different stockInLineId)
      const mismatchCheckStartTime = performance.now();
      const itemProcessedSet2 = processedQrCombinations.get(scannedItemId);
      if (itemProcessedSet2?.has(scannedStockInLineId)) {
        const mismatchCheckTime = performance.now() - mismatchCheckStartTime;
        console.log(`⏱️ [SKIP] Already processed this exact combination (check time: ${mismatchCheckTime.toFixed(2)}ms)`);
        return;
      }
      const mismatchCheckTime = performance.now() - mismatchCheckStartTime;
      console.log(`⏱️ [PERF] Mismatch check time: ${mismatchCheckTime.toFixed(2)}ms`);
      
      // 取第一个活跃的 lot 作为期望的 lot
      const expectedLotStartTime = performance.now();
      const expectedLot = activeSuggestedLots[0];
      if (!expectedLot) {
        console.error("Could not determine expected lot for confirmation");
        startTransition(() => {
          setQrScanError(true);
          setQrScanSuccess(false);
        });
        return;
      }
      const expectedLotTime = performance.now() - expectedLotStartTime;
      console.log(`⏱️ [PERF] Get expected lot time: ${expectedLotTime.toFixed(2)}ms`);
      
      // ✅ 立即打开确认模态框，不等待其他操作
      console.log(`⚠️ Lot mismatch: Expected stockInLineId=${expectedLot.stockInLineId}, Scanned stockInLineId=${scannedStockInLineId}`);
      
      // Set selected lot immediately (no transition delay)
      const setSelectedLotStartTime = performance.now();
      setSelectedLotForQr(expectedLot);
      const setSelectedLotTime = performance.now() - setSelectedLotStartTime;
      console.log(`⏱️ [PERF] Set selected lot time: ${setSelectedLotTime.toFixed(2)}ms`);
      
      // ✅ 获取扫描的 lot 信息（从 QR 数据中提取，或使用默认值）
      // Call handleLotMismatch immediately - it will open the modal
      const handleMismatchStartTime = performance.now();
      handleLotMismatch(
        {
          lotNo: expectedLot.lotNo,
          itemCode: expectedLot.itemCode,
          itemName: expectedLot.itemName
        },
        {
          lotNo: null, // 扫描的 lotNo 未知，需要从后端获取或显示为未知
          itemCode: expectedLot.itemCode,
          itemName: expectedLot.itemName,
          inventoryLotLineId: null,
          stockInLineId: scannedStockInLineId // ✅ 传递 stockInLineId
        }
      );
      const handleMismatchTime = performance.now() - handleMismatchStartTime;
      console.log(`⏱️ [PERF] Handle mismatch call time: ${handleMismatchTime.toFixed(2)}ms`);
      
      const totalTime = performance.now() - totalStartTime;
      console.log(`⚠️ [PROCESS OUTSIDE QR MISMATCH] Total time before modal: ${totalTime.toFixed(2)}ms (${(totalTime / 1000).toFixed(3)}s)`);
      console.log(`⏰ End time: ${new Date().toISOString()}`);
      console.log(`📊 Breakdown: parse=${parseTime.toFixed(2)}ms, validation=${validationTime.toFixed(2)}ms, duplicateCheck=${duplicateCheckTime.toFixed(2)}ms, lookup=${lookupTime.toFixed(2)}ms, match=${matchTime.toFixed(2)}ms, mismatchCheck=${mismatchCheckTime.toFixed(2)}ms, expectedLot=${expectedLotTime.toFixed(2)}ms, setSelectedLot=${setSelectedLotTime.toFixed(2)}ms, handleMismatch=${handleMismatchTime.toFixed(2)}ms`);
    } catch (error) {
      const totalTime = performance.now() - totalStartTime;
      console.error(`❌ [PROCESS OUTSIDE QR ERROR] Total time: ${totalTime.toFixed(2)}ms`);
      console.error("Error during QR code processing:", error);
      startTransition(() => {
        setQrScanError(true);
        setQrScanSuccess(false);
      });
      return;
    }
  }, [lotDataIndexes, handleLotMismatch, processedQrCombinations, filteredLotData, fetchJobOrderData]);
  
  // Store processOutsideQrCode in ref for immediate access (update on every render)
  processOutsideQrCodeRef.current = processOutsideQrCode;
  
  // Store resetScan in ref for immediate access (update on every render)
  resetScanRef.current = resetScan;


  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
      const stockOutLineData: CreateStockOutLine = {
        consoCode: selectedLotForQr.pickOrderConsoCode,
        pickOrderLineId: selectedLotForQr.pickOrderLineId,
        inventoryLotLineId: selectedLotForQr.lotId,
        qty: 0.0
      };
      
      try {
        await createStockOutLine(stockOutLineData);
        console.log("Stock out line created successfully!");
        
        // 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);
        
        // Refresh data
        await fetchJobOrderData();
      } catch (error) {
        console.error("Error creating stock out line:", error);
      }
    }
  }, [selectedLotForQr, fetchJobOrderData]);

 
  useEffect(() => {
    // Skip if scanner is not active or no data available
    if (!isManualScanning || qrValues.length === 0 || combinedLotData.length === 0 || isRefreshingData) {
      return;
    }
  
    const qrValuesChangeStartTime = performance.now();
    console.log(`⏱️ [QR VALUES EFFECT] Triggered at: ${new Date().toISOString()}`);
    console.log(`⏱️ [QR VALUES EFFECT] qrValues.length: ${qrValues.length}`);
    console.log(`⏱️ [QR VALUES EFFECT] qrValues:`, qrValues);
  
    const latestQr = qrValues[qrValues.length - 1];
    console.log(`⏱️ [QR VALUES EFFECT] Latest QR: ${latestQr}`);
    console.log(`⏰ [QR VALUES EFFECT] Latest QR detected at: ${new Date().toISOString()}`);
    
    // ✅ FIXED: Handle test shortcut {2fitestx,y} or {2fittestx,y} where x=itemId, y=stockInLineId
    // Support both formats: {2fitest (2 t's) and {2fittest (3 t's)
    if ((latestQr.startsWith("{2fitest") || latestQr.startsWith("{2fittest")) && latestQr.endsWith("}")) {
      // Extract content: remove "{2fitest" or "{2fittest" and "}"
      let content = '';
      if (latestQr.startsWith("{2fittest")) {
        content = latestQr.substring(9, latestQr.length - 1); // Remove "{2fittest" and "}"
      } else if (latestQr.startsWith("{2fitest")) {
        content = latestQr.substring(8, latestQr.length - 1); // Remove "{2fitest" and "}"
      }
      
      const parts = content.split(',');
      
      if (parts.length === 2) {
        const itemId = parseInt(parts[0].trim(), 10);
        const stockInLineId = parseInt(parts[1].trim(), 10);
        
        if (!isNaN(itemId) && !isNaN(stockInLineId)) {
          console.log(
            `%c TEST QR: Detected ${latestQr.substring(0, 9)}... - Simulating QR input (itemId=${itemId}, stockInLineId=${stockInLineId})`,
            "color: purple; font-weight: bold"
          );
          
          // ✅ Simulate QR code JSON format
          const simulatedQr = JSON.stringify({
            itemId: itemId,
            stockInLineId: stockInLineId
          });
          
          console.log(`⏱️ [TEST QR] Simulated QR content: ${simulatedQr}`);
          console.log(`⏱️ [TEST QR] Start time: ${new Date().toISOString()}`);
          const testStartTime = performance.now();
          
          // ✅ Mark as processed FIRST to avoid duplicate processing
          lastProcessedQrRef.current = latestQr;
          processedQrCodesRef.current.add(latestQr);
          if (processedQrCodesRef.current.size > 100) {
            const firstValue = processedQrCodesRef.current.values().next().value;
            if (firstValue !== undefined) {
              processedQrCodesRef.current.delete(firstValue);
            }
          }
          setLastProcessedQr(latestQr);
          setProcessedQrCodes(new Set(processedQrCodesRef.current));
          
          // ✅ Process immediately (bypass QR scanner delay)
          if (processOutsideQrCodeRef.current) {
            processOutsideQrCodeRef.current(simulatedQr).then(() => {
              const testTime = performance.now() - testStartTime;
              console.log(`⏱️ [TEST QR] Total processing time: ${testTime.toFixed(2)}ms (${(testTime / 1000).toFixed(3)}s)`);
              console.log(`⏱️ [TEST QR] End time: ${new Date().toISOString()}`);
            }).catch((error) => {
              const testTime = performance.now() - testStartTime;
              console.error(`❌ [TEST QR] Error after ${testTime.toFixed(2)}ms:`, error);
            });
          }
          
          // Reset scan
          if (resetScanRef.current) {
            resetScanRef.current();
          }
          
          const qrValuesChangeTime = performance.now() - qrValuesChangeStartTime;
          console.log(`⏱️ [QR VALUES EFFECT] Test QR handling time: ${qrValuesChangeTime.toFixed(2)}ms`);
          return; // ✅ IMPORTANT: Return early to prevent normal processing
        } else {
          console.warn(`⏱️ [TEST QR] Invalid itemId or stockInLineId: itemId=${parts[0]}, stockInLineId=${parts[1]}`);
        }
      } else {
        console.warn(`⏱️ [TEST QR] Invalid format. Expected {2fitestx,y} or {2fittestx,y}, got: ${latestQr}`);
      }
    }
    
    // Skip processing if confirmation modals are open
    // BUT: Allow processing if modal was just closed (to allow reopening for different stockInLineId)
    if (lotConfirmationOpen || manualLotConfirmationOpen) {
      // Check if this is a different QR code than what triggered the modal
      const modalTriggerQr = lastProcessedQrRef.current;
      if (latestQr === modalTriggerQr) {
        console.log(`⏱️ [QR PROCESS] Skipping - modal open for same QR: lotConfirmation=${lotConfirmationOpen}, manual=${manualLotConfirmationOpen}`);
        return;
      }
      // If it's a different QR, allow processing (user might have canceled and scanned different lot)
      console.log(`⏱️ [QR PROCESS] Different QR detected while modal open, allowing processing`);
    }
    
    const qrDetectionStartTime = performance.now();
    console.log(`⏱️ [QR DETECTION] Latest QR detected: ${latestQr?.substring(0, 50)}...`);
    console.log(`⏰ [QR DETECTION] Detection time: ${new Date().toISOString()}`);
    console.log(`⏱️ [QR DETECTION] Time since QR scanner set value: ${(qrDetectionStartTime - qrValuesChangeStartTime).toFixed(2)}ms`);
    
    // Skip if already processed (use refs to avoid dependency issues and delays)
    const checkProcessedStartTime = performance.now();
    if (processedQrCodesRef.current.has(latestQr) || lastProcessedQrRef.current === latestQr) {
      const checkTime = performance.now() - checkProcessedStartTime;
      console.log(`⏱️ [QR PROCESS] Already processed check time: ${checkTime.toFixed(2)}ms`);
      return;
    }
    const checkTime = performance.now() - checkProcessedStartTime;
    console.log(`⏱️ [QR PROCESS] Not processed check time: ${checkTime.toFixed(2)}ms`);
    
    // Handle special shortcut
    if (latestQr === "{2fic}") {
      console.log("  Detected {2fic} shortcut - opening manual lot confirmation form");
      setManualLotConfirmationOpen(true);
      if (resetScanRef.current) {
        resetScanRef.current();
      }
      lastProcessedQrRef.current = latestQr;
      processedQrCodesRef.current.add(latestQr);
      if (processedQrCodesRef.current.size > 100) {
        const firstValue = processedQrCodesRef.current.values().next().value;
        if (firstValue !== undefined) {
          processedQrCodesRef.current.delete(firstValue);
        }
      }
      setLastProcessedQr(latestQr);
      setProcessedQrCodes(prev => {
        const newSet = new Set(prev);
        newSet.add(latestQr);
        if (newSet.size > 100) {
          const firstValue = newSet.values().next().value;
          if (firstValue !== undefined) {
            newSet.delete(firstValue);
          }
        }
        return newSet;
      });
      return;
    }
    
    // Process new QR code immediately (background mode - no modal)
    // Check against refs to avoid state update delays
    if (latestQr && latestQr !== lastProcessedQrRef.current) {
      const processingStartTime = performance.now();
      console.log(`⏱️ [QR PROCESS] Starting processing at: ${new Date().toISOString()}`);
      console.log(`⏱️ [QR PROCESS] Time since detection: ${(processingStartTime - qrDetectionStartTime).toFixed(2)}ms`);
      
      // ✅ Process immediately for better responsiveness
      // Clear any pending debounced processing
      if (qrProcessingTimeoutRef.current) {
        clearTimeout(qrProcessingTimeoutRef.current);
        qrProcessingTimeoutRef.current = null;
      }
      
      // Log immediately (console.log is synchronous)
      console.log(`⏱️ [QR PROCESS] Processing new QR code with enhanced validation: ${latestQr}`);
      
      // Update refs immediately (no state update delay) - do this FIRST
      const refUpdateStartTime = performance.now();
      lastProcessedQrRef.current = latestQr;
      processedQrCodesRef.current.add(latestQr);
      if (processedQrCodesRef.current.size > 100) {
        const firstValue = processedQrCodesRef.current.values().next().value;
        if (firstValue !== undefined) {
          processedQrCodesRef.current.delete(firstValue);
        }
      }
      const refUpdateTime = performance.now() - refUpdateStartTime;
      console.log(`⏱️ [QR PROCESS] Ref update time: ${refUpdateTime.toFixed(2)}ms`);
      
      // Process immediately in background - no modal/form needed, no delays
      // Use ref to avoid dependency issues
      const processCallStartTime = performance.now();
      if (processOutsideQrCodeRef.current) {
        processOutsideQrCodeRef.current(latestQr).then(() => {
          const processCallTime = performance.now() - processCallStartTime;
          const totalProcessingTime = performance.now() - processingStartTime;
          console.log(`⏱️ [QR PROCESS] processOutsideQrCode call time: ${processCallTime.toFixed(2)}ms`);
          console.log(`⏱️ [QR PROCESS] Total processing time: ${totalProcessingTime.toFixed(2)}ms (${(totalProcessingTime / 1000).toFixed(3)}s)`);
        }).catch((error) => {
          const processCallTime = performance.now() - processCallStartTime;
          const totalProcessingTime = performance.now() - processingStartTime;
          console.error(`❌ [QR PROCESS] processOutsideQrCode error after ${processCallTime.toFixed(2)}ms:`, error);
          console.error(`❌ [QR PROCESS] Total processing time before error: ${totalProcessingTime.toFixed(2)}ms`);
        });
      }
      
      // Update state for UI (but don't block on it)
      const stateUpdateStartTime = performance.now();
      setLastProcessedQr(latestQr);
      setProcessedQrCodes(new Set(processedQrCodesRef.current));
      const stateUpdateTime = performance.now() - stateUpdateStartTime;
      console.log(`⏱️ [QR PROCESS] State update time: ${stateUpdateTime.toFixed(2)}ms`);
      
      const detectionTime = performance.now() - qrDetectionStartTime;
      const totalEffectTime = performance.now() - qrValuesChangeStartTime;
      console.log(`⏱️ [QR DETECTION] Total detection time: ${detectionTime.toFixed(2)}ms`);
      console.log(`⏱️ [QR VALUES EFFECT] Total effect time: ${totalEffectTime.toFixed(2)}ms`);
    }
    
    return () => {
      if (qrProcessingTimeoutRef.current) {
        clearTimeout(qrProcessingTimeoutRef.current);
        qrProcessingTimeoutRef.current = null;
      }
    };
  }, [qrValues.length, isManualScanning, isRefreshingData, combinedLotData.length, lotConfirmationOpen, manualLotConfirmationOpen]);

  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 {
      const currentActualPickQty = lot.actualPickQty || 0;
      const cumulativeQty = currentActualPickQty + newQty;
      
      let newStatus = 'partially_completed';
      
      if (cumulativeQty >= lot.requiredQty) {
        newStatus = 'completed';
      }
      
      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
      });
      
      if (newQty > 0) {
        await updateInventoryLotLineQuantities({
          inventoryLotLineId: lot.lotId,
          qty: newQty,
          status: 'available',
          operation: 'pick'
        });
      }
      
      //  FIXED: Use the proper API function instead of direct fetch
      if (newStatus === 'completed' && lot.pickOrderConsoCode) {
        console.log(` Lot ${lot.lotNo} completed, checking if pick order ${lot.pickOrderConsoCode} is complete...`);
        
        try {
          //  Use the imported API function instead of direct fetch
          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 fetchJobOrderData();
      console.log("Pick quantity submitted successfully!");
      
      setTimeout(() => {
        checkAndAutoAssignNext();
      }, 1000);
      
    } catch (error) {
      console.error("Error submitting pick quantity:", error);
    }
  }, [pickQtyData, fetchJobOrderData, checkAndAutoAssignNext]);
  const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: number) => {
    console.log('=== handleSubmitPickQtyWithQty called ===');
    console.log('Lot:', lot);
    console.log('submitQty:', submitQty);
    console.log('stockOutLineId:', lot.stockOutLineId);
    
    if (!lot.stockOutLineId) {
      console.error("No stock out line found for this lot:", lot);
      alert(`Error: No stock out line ID found for lot ${lot.lotNo}. Cannot update status.`);
      return;
    }
    
    try {
      // Special case: If submitQty is 0 and all values are 0, mark as completed with qty: 0
      if (submitQty === 0) {
        console.log(`=== SUBMITTING ALL ZEROS CASE ===`);
        console.log(`Lot: ${lot.lotNo}`);
        console.log(`Stock Out Line ID: ${lot.stockOutLineId}`);
        console.log(`Setting status to 'completed' with qty: 0`);
        
        const updateResult = await updateStockOutLineStatus({
          id: lot.stockOutLineId,
          status: 'completed',
          qty: 0
        });
        
        console.log('Update result:', updateResult);
        
        if (!updateResult || (updateResult as any).code !== 'SUCCESS') {
          console.error('Failed to update stock out line status:', updateResult);
          throw new Error('Failed to update stock out line status');
        }
        
        // Check if pick order is completed
        if (lot.pickOrderConsoCode) {
          console.log(` Lot ${lot.lotNo} completed (all zeros), 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 fetchJobOrderData();
        console.log("All zeros submission completed successfully!");
        
        setTimeout(() => {
          checkAndAutoAssignNext();
        }, 1000);
        
        return;
      }
      
      // Normal case: Calculate cumulative quantity correctly
      const currentActualPickQty = lot.actualPickQty || 0;
      const cumulativeQty = currentActualPickQty + submitQty;
      
      // 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
      });
      
      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 fetchJobOrderData();
      console.log("Pick quantity submitted successfully!");
      
      setTimeout(() => {
        checkAndAutoAssignNext();
      }, 1000);
      
    } catch (error) {
      console.error("Error submitting pick quantity:", error);
    }
  }, [fetchJobOrderData, checkAndAutoAssignNext]);
  const handleSubmitAllScanned = useCallback(async () => {
    const scannedLots = combinedLotData.filter(lot => 
      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 所需的格式
      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(false) // Job Order 通常都有 lot
        };
      });
      
      const request: batchSubmitListRequest = {
        userId: currentUserId || 0,
        lines: lines
      };
      
      // 使用 batchSubmitList API
      const result = await batchSubmitList(request);
      console.log(`📥 Batch submit result:`, result);
      
      // 刷新数据
      await fetchJobOrderData(); // 或 pickOrderId，根据页面
      
      if (result && result.code === "SUCCESS") {
        setQrScanSuccess(true);
        setTimeout(() => {
          setQrScanSuccess(false);
          checkAndAutoAssignNext();
        }, 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, fetchJobOrderData, checkAndAutoAssignNext, currentUserId]);

  //  Calculate scanned items count
  const scannedItemsCount = useMemo(() => {
    return combinedLotData.filter(lot => lot.stockOutLineStatus === 'checked').length;
  }, [combinedLotData]);
  //  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 fetchJobOrderData();
      console.log("Lot rejected successfully!");
      
      setTimeout(() => {
        checkAndAutoAssignNext();
      }, 1000);
      
    } catch (error) {
      console.error("Error rejecting lot:", error);
    }
  }, [fetchJobOrderData, 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: "Jo",  // Delivery Order Record 类型
      };
      
      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);
      
      await fetchJobOrderData();
    } catch (error) {
      console.error("Error submitting pick execution form:", error);
    }
  }, [fetchJobOrderData]);

  //  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 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
  const paginatedData = useMemo(() => {
    //  Sort by routerIndex first, then by other criteria
    const sortedData = [...combinedLotData].sort((a, b) => {
      const aIndex = a.routerIndex || 0;
      const bIndex = b.routerIndex || 0;
      
      // Primary sort: by routerIndex
      if (aIndex !== bIndex) {
        return aIndex - bIndex;
      }
      
      // Secondary sort: by pickOrderCode if routerIndex is the same
      if (a.pickOrderCode !== b.pickOrderCode) {
        return a.pickOrderCode.localeCompare(b.pickOrderCode);
      }
      
      // Tertiary sort: by lotNo if everything else is the same
      return (a.lotNo || '').localeCompare(b.lotNo || '');
    });
    
    const startIndex = paginationController.pageNum * paginationController.pageSize;
    const endIndex = startIndex + paginationController.pageSize;
    return sortedData.slice(startIndex, endIndex);
  }, [combinedLotData, paginationController]);

  //  Add these functions for manual scanning
  const handleStartScan = useCallback(() => {
    console.log(" Starting manual QR scan...");
    setIsManualScanning(true);
    setProcessedQrCodes(new Set());
    setLastProcessedQr('');
    setQrScanError(false);
    setQrScanSuccess(false);
    startScan();
  }, [startScan]);

  const handleStopScan = useCallback(() => {
    console.log("⏹️ Stopping manual QR scan...");
    setIsManualScanning(false);
    setQrScanError(false);
    setQrScanSuccess(false);
    stopScan();
    resetScan();
  }, [stopScan, resetScan]);
  useEffect(() => {
    return () => {
      // Cleanup when component unmounts (e.g., when switching tabs)
      if (isManualScanning) {
        console.log("🧹 Component unmounting, stopping QR scanner...");
        stopScan();
        resetScan();
      }
    };
  }, [isManualScanning, stopScan, resetScan]);
  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("🧹 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}>
        {/* Job Order Header */}
        {jobOrderData && (
          <Paper sx={{ p: 2 }}>
            <Stack direction="row" spacing={4} useFlexGap flexWrap="wrap">
              <Typography variant="subtitle1">
                <strong>{t("Job Order")}:</strong> {jobOrderData.pickOrder?.jobOrder?.code || '-'}
         </Typography>
              <Typography variant="subtitle1">
                <strong>{t("Pick Order Code")}:</strong> {jobOrderData.pickOrder?.code || '-'}
              </Typography>
              <Typography variant="subtitle1">
                <strong>{t("Target Date")}:</strong> {jobOrderData.pickOrder?.targetDate || '-'}
              </Typography>
          
            </Stack>
          </Paper>
        )}


        {/* Combined Lot Table */}
        <Box>
          <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
          
            
            <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>
              )}
               {/*  ADD THIS: Submit All Scanned Button */}
               <Button
                variant="contained"
                color="success"
                onClick={handleSubmitAllScanned}
                disabled={scannedItemsCount === 0 || isSubmittingAll}
                sx={{ minWidth: '160px' }}
              >
                {isSubmittingAll ? (
                  <>
                    <CircularProgress size={16} sx={{ mr: 1 }} />
                    {t("Submitting...")}
                  </>
                ) : (
                  `${t("Submit All Scanned")} (${scannedItemsCount})`
                )}
              </Button>
             
        </Box>
            </Box>

          {qrScanError && !qrScanSuccess && (
            <Alert severity="error" sx={{ mb: 2 }}>
              {t("QR code does not match any item in current orders.")}
            </Alert>
          )}
          {qrScanSuccess && (
            <Alert severity="success" sx={{ mb: 2 }}>
              {t("QR code verified.")}
            </Alert>
          )}
          
            <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 No")}</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={8} align="center">
                      <Typography variant="body2" color="text.secondary">
                        {t("No data available")}
                      </Typography>
                    </TableCell>
                  </TableRow>
                ) : (
                  paginatedData.map((lot, index) => (
                    <TableRow 
                      key={`${lot.pickOrderLineId}-${lot.lotId}`}
                      sx={{
                        backgroundColor: lot.lotAvailability === 'rejected' ? 'grey.100' : 'inherit',
                        opacity: lot.lotAvailability === 'rejected' ? 0.6 : 1,
                        '& .MuiTableCell-root': {
                          color: lot.lotAvailability === 'rejected' ? 'text.disabled' : 'inherit'
                        }
                      }}
                    >
                      <TableCell>
                        <Typography variant="body2" fontWeight="bold">
                          {index + 1}
                        </Typography>
                      </TableCell>
                      <TableCell>
                        <Typography variant="body2">
                          {lot.routerRoute || '-'}
                        </Typography>
                      </TableCell>
                      <TableCell>{lot.itemCode}</TableCell>
                      <TableCell>{lot.itemName+'('+lot.uomDesc+')'}</TableCell>
                      <TableCell>
                        <Box>
                          <Typography 
                            sx={{ 
                              color: lot.lotAvailability === 'rejected' ? 'text.disabled' : 'inherit',
                              opacity: lot.lotAvailability === 'rejected' ? 0.6 : 1
                            }}
                          >
                            {lot.lotNo}
                          </Typography>
                        </Box>
                      </TableCell>
                      <TableCell align="right">
                        {(() => {
                          const requiredQty = lot.requiredQty || 0;
                          return requiredQty.toLocaleString()+'('+lot.uomShortDesc+')';
                        })()}
                      </TableCell>
                    
                      <TableCell align="center">
                        {lot.stockOutLineStatus?.toLowerCase() !== 'pending' ? (
                          <Box sx={{ 
                            display: 'flex', 
                            justifyContent: 'center', 
                            alignItems: 'center',
                            width: '100%',
                            height: '100%'
                          }}>
                            <Checkbox
                              checked={lot.stockOutLineStatus?.toLowerCase() !== 'pending'}
                              disabled={true}
                              readOnly={true}
                              size="large"
                              sx={{
                                color: lot.stockOutLineStatus?.toLowerCase() !== 'pending' ? 'success.main' : 'grey.400',
                                '&.Mui-checked': {
                                  color: 'success.main',
                                },
                                transform: 'scale(1.3)',
                                '& .MuiSvgIcon-root': {
                                  fontSize: '1.5rem',
                                }
                              }}
                            />
                          </Box>
                        ) : null}
                      </TableCell>

                      <TableCell align="center">
                        <Box sx={{ display: 'flex', justifyContent: 'center' }}>
                          <Stack direction="row" spacing={1} alignItems="center">
                          <Button
                              variant="contained"
                              onClick={() => {
                                const lotKey = `${lot.pickOrderLineId}-${lot.lotId}`;
                                const submitQty = lot.requiredQty || lot.pickOrderLineRequiredQty;
                                // Submit with default lot required pick qty
                                
                                handlePickQtyChange(lotKey, submitQty);
                                handleSubmitPickQtyWithQty(lot, submitQty);
                              }}
                              disabled={
                                (lot.lotAvailability === 'expired' || 
                                 lot.lotAvailability === 'status_unavailable' || 
                                 lot.lotAvailability === 'rejected') ||
                                lot.stockOutLineStatus === 'completed' ||
                                lot.stockOutLineStatus === 'pending' //  Disable when QR scan not passed
                              }
                              sx={{ 
                                fontSize: '0.75rem',
                                py: 0.5,
                                minHeight: '28px',
                                minWidth: '70px'
                              }}
                            >
                              {t("Submit")}
                          </Button>
                            
                          <Button
                            variant="outlined"
                            size="small"
                            onClick={() => handlePickExecutionForm(lot)}
                            disabled={
                              // ✅ align with GoodPickExecutiondetail: Edit only disabled when completed
                              lot.stockOutLineStatus === 'completed'
                            }
                            sx={{ 
                              fontSize: '0.7rem',
                              py: 0.5,
                              minHeight: '28px',
                              minWidth: '60px',
                              borderColor: 'warning.main',
                              color: 'warning.main'
                            }}
                            title="Report missing or bad items"
                          >
                            {t("Edit")}
                          </Button>
                          <Button
                            variant="outlined"
                            size="small"
                            onClick={() => handleSubmitPickQtyWithQty(lot, lot.requiredQty || lot.pickOrderLineRequiredQty || 0)}
                            disabled={lot.stockOutLineStatus === 'completed'}
                            sx={{ 
                              fontSize: '0.7rem',
                              py: 0.5,
                              minHeight: '28px',
                              minWidth: '90px'
                            }}
                          >
                            {t("Just Complete")}
                          </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 */}
      {!lotConfirmationOpen && (
      <QrCodeModal
        open={qrModalOpen}
        onClose={() => {
          setQrModalOpen(false);
          setSelectedLotForQr(null);
          stopScan();
          resetScan();
        }}
        lot={selectedLotForQr}
        combinedLotData={combinedLotData}
        onQrCodeSubmit={handleQrCodeSubmitFromModal}
      />
      )}
       {/*  Add Lot Confirmation Modal */}
       {lotConfirmationOpen && expectedLotData && scannedLotData && (
        <LotConfirmationModal
          open={lotConfirmationOpen}
          onClose={() => {
            setLotConfirmationOpen(false);
            setExpectedLotData(null);
            setScannedLotData(null);
            setSelectedLotForQr(null);
 
          }}
          onConfirm={handleLotConfirmation}
          expectedLot={expectedLotData}
          scannedLot={scannedLotData}
          isLoading={isConfirmingLot}
        />
      )}
      
      {/* Manual Lot Confirmation Modal */}
      <ManualLotConfirmationModal
        open={manualLotConfirmationOpen}
        onClose={() => {
          setManualLotConfirmationOpen(false);
        }}
        onConfirm={handleManualLotConfirmation}
        expectedLot={expectedLotData}
        scannedLot={scannedLotData}
        isLoading={isConfirmingLot}
      />
      {/*  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,
            //  Add missing required properties from GetPickOrderLineInfo interface
            availableQty: selectedLotForExecutionForm.availableQty || 0,
            requiredQty: selectedLotForExecutionForm.requiredQty || 0,
            uomDesc: selectedLotForExecutionForm.uomDesc || '',
            uomShortDesc: selectedLotForExecutionForm.uomShortDesc || '',
            pickedQty: selectedLotForExecutionForm.actualPickQty || 0,
            suggestedList: [],
            noLotLines: []
          }}
          pickOrderId={selectedLotForExecutionForm.pickOrderId}
          pickOrderCreateDate={new Date()}
          onNormalPickSubmit={async (lot, submitQty) => {
            console.log('onNormalPickSubmit called in newJobPickExecution:', { lot, submitQty });
            if (!lot) {
              console.error('Lot is null or undefined');
              return;
            }
            const lotKey = `${lot.pickOrderLineId}-${lot.lotId}`;
            handlePickQtyChange(lotKey, submitQty);
            await handleSubmitPickQtyWithQty(lot, submitQty);
          }}
        />
      )}
    </FormProvider>
    </TestQrCodeProvider>
  );
};

export default JobPickExecution