import { InventoryLotLineResult, InventoryResult } from "@/app/api/inventory";
import { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useRef, useState } from "react";
import SaveIcon from "@mui/icons-material/Save";
import EditIcon from "@mui/icons-material/Edit";
import RestartAltIcon from "@mui/icons-material/RestartAlt";
import { useTranslation } from "react-i18next";
import { Column } from "../SearchResults";
import SearchResults, { defaultPagingController, defaultSetPagingController } from "../SearchResults/SearchResults";
import { arrayToDateString } from "@/app/utils/formatUtil";
import { Box, Card, Checkbox, FormControlLabel, Grid, IconButton, Modal, TextField, Typography, Button, Chip } from "@mui/material";
import useUploadContext from "../UploadProvider/useUploadContext";
import { downloadFile } from "@/app/utils/commonUtil";
import { fetchQrCodeByLotLineId, LotLineToQrcode } from "@/app/api/pdf/actions";
import QrCodeIcon from "@mui/icons-material/QrCode";
import PrintIcon from "@mui/icons-material/Print";
import SwapHoriz from "@mui/icons-material/SwapHoriz";
import CloseIcon from "@mui/icons-material/Close";
import { Autocomplete } from "@mui/material";
import { WarehouseResult } from "@/app/api/warehouse";
import { fetchWarehouseListClient } from "@/app/api/warehouse/client";
import { createStockTransfer } from "@/app/api/inventory/actions";
import { msg, msgError } from "@/components/Swal/CustomAlerts";
import { PrinterCombo } from "@/app/api/settings/printer";
import { printLabelForInventoryLotLine } from "@/app/api/pdf/actions";
import TuneIcon from "@mui/icons-material/Tune"; 
import AddIcon from "@mui/icons-material/Add";
import { Table, TableBody, TableCell, TableHead, TableRow } from "@mui/material";
import DeleteIcon from "@mui/icons-material/Delete";
import { INPUT_DATE_FORMAT } from "@/app/utils/formatUtil";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import dayjs from "dayjs";
import CheckIcon from "@mui/icons-material/Check";
import { submitStockAdjustment, StockAdjustmentLineRequest } from "@/app/api/stockAdjustment/actions";

type AdjustmentEntry = InventoryLotLineResult & { 
  adjustedQty: number; 
  originalQty?: number; 
  productlotNo?: string; 
  dnNo?: string; 
  isNew?: boolean;
  isOpeningInventory?: boolean;
  remarks?: string;
};


interface Props {
    inventoryLotLines: InventoryLotLineResult[] | null;
    setPagingController: defaultSetPagingController;
    pagingController: typeof defaultPagingController;
    totalCount: number;
    inventory: InventoryResult | null;
    filterLotNo?: string;
    onStockTransferSuccess?: () => void | Promise<void>;
    printerCombo?: PrinterCombo[];
    onStockAdjustmentSuccess?: () => void | Promise<void>;
}

const InventoryLotLineTable: React.FC<Props> = ({
  inventoryLotLines, pagingController, setPagingController, totalCount, inventory,
  filterLotNo,
  onStockTransferSuccess, printerCombo = [],
  onStockAdjustmentSuccess,
}) => {
    const { t } = useTranslation(["inventory"]);
    const PRINT_PRINTER_ID_KEY = 'inventoryLotLinePrintPrinterId';
    const { setIsUploading } = useUploadContext();
    const [stockTransferModalOpen, setStockTransferModalOpen] = useState(false);
    const [selectedLotLine, setSelectedLotLine] = useState<InventoryLotLineResult | null>(null);
    const [startLocation, setStartLocation] = useState<string>("");
    const [targetLocation, setTargetLocation] = useState<number | null>(null); // Store warehouse ID instead of code
    const [targetLocationInput, setTargetLocationInput] = useState<string>("");
    const [qtyToBeTransferred, setQtyToBeTransferred] = useState<string>("");
    const [warehouses, setWarehouses] = useState<WarehouseResult[]>([]);
    const [printModalOpen, setPrintModalOpen] = useState(false);
    const [lotLineForPrint, setLotLineForPrint] = useState<InventoryLotLineResult | null>(null);
    const [printPrinter, setPrintPrinter] = useState<PrinterCombo | null>(null);
    const [printQty, setPrintQty] = useState(1);
    const [stockAdjustmentModalOpen, setStockAdjustmentModalOpen] = useState(false);
    const [pendingRemovalLineId, setPendingRemovalLineId] = useState<number | null>(null);
    const [removalReasons, setRemovalReasons] = useState<Record<number, string>>({});
    const [addEntryModalOpen, setAddEntryModalOpen] = useState(false);
    const [addEntryForm, setAddEntryForm] = useState({
        lotNo: '',
        qty: 0,
        expiryDate: '',
        locationId: null as number | null,
        locationInput: '',
        productlotNo: '',
        dnNo: '',
        isOpeningInventory: false,
        remarks: '',
    });
    const originalAdjustmentLinesRef = useRef<AdjustmentEntry[]>([]);
    const [adjustmentEntries, setAdjustmentEntries] = useState<AdjustmentEntry[]>([]);
    useEffect(() => {
        if (stockTransferModalOpen) {
            fetchWarehouseListClient()
                .then(setWarehouses)
                .catch(console.error);
        }
    }, [stockTransferModalOpen]);

    useEffect(() => {
        if (addEntryModalOpen) {
            fetchWarehouseListClient()
                .then(setWarehouses)
                .catch(console.error);
        }
    }, [addEntryModalOpen]);

    const availableLotLines = useMemo(() => {
        const base = (inventoryLotLines ?? []).filter((line) => line.status?.toLowerCase() === "available");
        const f = filterLotNo?.trim?.() ? filterLotNo.trim() : '';
        if (!f) return base;
        return base.filter((line) => line.lotNo === f);
    }, [inventoryLotLines, filterLotNo]);
    const originalQty = selectedLotLine?.availableQty || 0;
    const validatedTransferQty = useMemo(() => {
        const raw = (qtyToBeTransferred ?? '').replace(/\D/g, '');
        if (raw === '') return 0;

        const parsed = parseInt(raw, 10);
        if (Number.isNaN(parsed)) return 0;
        if (originalQty < 1) return 0;

        const minClamped = Math.max(1, parsed);
        return Math.min(minClamped, originalQty);
    }, [qtyToBeTransferred, originalQty]);
    const remainingQty = originalQty - validatedTransferQty;

const prevAdjustmentModalOpenRef = useRef(false);

    useEffect(() => {
        const wasOpen = prevAdjustmentModalOpenRef.current;
        prevAdjustmentModalOpenRef.current = stockAdjustmentModalOpen;

        if (stockAdjustmentModalOpen && inventory) {
            // Only init when we transition to open (modal just opened)
            if (!wasOpen) {
                const initial = (availableLotLines ?? []).map((line) => ({
                    ...line,
                    adjustedQty: line.availableQty ?? 0,
                    originalQty: line.availableQty ?? 0,
                    remarks: '',
                }));
                setAdjustmentEntries(initial);
                originalAdjustmentLinesRef.current = initial;
            }
            setPendingRemovalLineId(null);
            setRemovalReasons({});
        }
    }, [stockAdjustmentModalOpen, inventory, availableLotLines]);

    const handleAdjustmentReset = useCallback(() => {

        setPendingRemovalLineId(null);
        setRemovalReasons({});
        setAdjustmentEntries(
            (availableLotLines ?? []).map((line) => ({
            ...line,
            adjustedQty: line.availableQty ?? 0,
            originalQty: line.availableQty ?? 0,
            remarks: '',
            }))
        );
    }, [availableLotLines]);

    const handleAdjustmentQtyChange = useCallback((lineId: number, value: number) => {
        setAdjustmentEntries((prev) =>
            prev.map((line) =>
            line.id === lineId ? { ...line, adjustedQty: Math.max(0, value) } : line
            )
        );
    }, []);

    const handleAdjustmentRemarksChange = useCallback((lineId: number, value: string) => {
        setAdjustmentEntries((prev) =>
            prev.map((line) =>
                line.id === lineId ? { ...line, remarks: value } : line
            )
        );
    }, []);

    const handleRemoveAdjustmentLine = useCallback((lineId: number) => {
        setAdjustmentEntries((prev) => prev.filter((line) => line.id !== lineId));
    }, []);

    const handleRemoveClick = useCallback((lineId: number) => {
    setPendingRemovalLineId((prev) => (prev === lineId ? null : lineId));
    }, []);

    const handleRemovalReasonChange = useCallback((lineId: number, value: string) => {
    setRemovalReasons((prev) => ({ ...prev, [lineId]: value }));
    }, []);

    const handleConfirmRemoval = useCallback((lineId: number) => {
    setAdjustmentEntries((prev) => prev.filter((line) => line.id !== lineId));
    setPendingRemovalLineId(null);
    }, []);

    const handleCancelRemoval = useCallback(() => {
    setPendingRemovalLineId(null);
    }, []);
    
    const hasAdjustmentChange = useMemo(() => {
        const original = originalAdjustmentLinesRef.current;
        const current = adjustmentEntries;
        if (original.length !== current.length) return true;
        const origById = new Map(original.map((line) => [line.id, { adjustedQty: line.adjustedQty ?? 0, remarks: line.remarks ?? '' }]));
        for (const line of current) {
            const o = origById.get(line.id);
            if (!o) return true;
            if (o.adjustedQty !== (line.adjustedQty ?? 0) || (o.remarks ?? '') !== (line.remarks ?? '')) return true;
        }
        return false;
    }, [adjustmentEntries]);

    const toApiLine = useCallback((line: AdjustmentEntry, itemCode: string): StockAdjustmentLineRequest => {
        const [y, m, d] = Array.isArray(line.expiryDate) ? line.expiryDate : [];
        const expiryDate = y != null && m != null && d != null
            ? `${y}-${String(m).padStart(2, '0')}-${String(d).padStart(2, '0')}`
            : '';
        return {
            id: line.id,
            lotNo: line.lotNo ?? null,
            adjustedQty: line.adjustedQty ?? 0,
            productlotNo: line.productlotNo ?? null,
            dnNo: line.dnNo ?? null,
            isOpeningInventory: line.isOpeningInventory ?? false,
            isNew: line.isNew ?? false,
            itemId: line.item?.id ?? 0,
            itemNo: line.item?.code ?? itemCode,
            expiryDate,
            warehouseId: line.warehouse?.id ?? 0,
            uom: line.uom ?? null,
        };
    }, []);

    const handleAdjustmentSave = useCallback(async () => {
        if (!inventory) return;
        const itemCode = inventory.itemCode;
        const originalLines = originalAdjustmentLinesRef.current.map((line) => toApiLine(line, itemCode));
        const currentLines = adjustmentEntries.map((line) => toApiLine(line, itemCode));
        try {
            setIsUploading(true);
            await submitStockAdjustment({
                itemId: inventory.itemId,
                originalLines,
                currentLines,
            });
            msg(t("Saved successfully"));
            setStockAdjustmentModalOpen(false);
            await onStockAdjustmentSuccess?.();
        } catch (e: unknown) {
            const message = e instanceof Error ? e.message : String(e);
            msgError(message || t("Save failed"));
        } finally {
            setIsUploading(false);
        }
    }, [adjustmentEntries, inventory, t, toApiLine, onStockAdjustmentSuccess]);

    const handleOpenAddEntry = useCallback(() => {
        setAddEntryForm({
            lotNo: '',
            qty: 0,
            expiryDate: '',
            locationId: null,
            locationInput: '',
            productlotNo: '',
            dnNo: '',
            isOpeningInventory: false,
            remarks: '',
        });
        setAddEntryModalOpen(true);
    }, []);

    const handleAddEntrySubmit = useCallback(() => {
        if (addEntryForm.qty < 0 || !addEntryForm.expiryDate || !addEntryForm.locationId || !inventory) return;
        const warehouse = warehouses.find(w => w.id === addEntryForm.locationId);
        if (!warehouse) return;
        const [y, m, d] = addEntryForm.expiryDate.split('-').map(Number);
        const newEntry: AdjustmentEntry = {
            id: -Date.now(),
            lotNo: addEntryForm.lotNo.trim() || '',
            item: { id: inventory.itemId, code: inventory.itemCode, name: inventory.itemName, type: inventory.itemType },
            warehouse: { id: warehouse.id, code: warehouse.code, name: warehouse.name },
            inQty: 0, outQty: 0, holdQty: 0,
            expiryDate: [y, m, d],
            status: 'available',
            availableQty: addEntryForm.qty,
            uom: inventory.uomUdfudesc || inventory.uomShortDesc || inventory.uomCode,
            qtyPerSmallestUnit: inventory.qtyPerSmallestUnit ?? 1,
            baseUom: inventory.baseUom || '',
            stockInLineId: 0,
            originalQty: 0,
            adjustedQty: addEntryForm.qty,
            productlotNo: addEntryForm.productlotNo.trim() || undefined,
            dnNo: addEntryForm.dnNo.trim() || undefined,
            isNew: true,
            isOpeningInventory: addEntryForm.isOpeningInventory,
            remarks: addEntryForm.remarks?.trim() ?? '',
        };
        setAdjustmentEntries(prev => [...prev, newEntry]);
        setAddEntryModalOpen(false);
    }, [addEntryForm, inventory, warehouses]);

    const downloadQrCode = useCallback(async (lotLineId: number) => {
      setIsUploading(true);
      // const postData = { stockInLineIds: [42,43,44] };
      const postData: LotLineToQrcode = {
        inventoryLotLineId: lotLineId
      }
      const response = await fetchQrCodeByLotLineId(postData);
      if (response) {
        downloadFile(new Uint8Array(response.blobValue), response.filename!);
      }
      setIsUploading(false);
    }, [setIsUploading]);
    
    const handleStockTransfer = useCallback(
      (lotLine: InventoryLotLineResult) => {
        setSelectedLotLine(lotLine);
        setStockTransferModalOpen(true);
        setStartLocation(lotLine.warehouse.code || "");
        setTargetLocation(null);
        setTargetLocationInput("");
        setQtyToBeTransferred("");
      },
      [],
    );

    const handlePrintClick = useCallback((lotLine: InventoryLotLineResult) => {
        setLotLineForPrint(lotLine);
        const labelPrinters = (printerCombo || []).filter(p => p.type === 'Label');
        const savedId = typeof sessionStorage !== 'undefined' ? sessionStorage.getItem(PRINT_PRINTER_ID_KEY) : null;
        const savedPrinter = savedId ? labelPrinters.find(p => p.id === Number(savedId)) : null;
        setPrintPrinter(savedPrinter ?? labelPrinters[0] ?? null);
        setPrintQty(1);
        setPrintModalOpen(true);
    }, [printerCombo]);

    const handlePrintConfirm = useCallback(async () => {
    if (!lotLineForPrint || !printPrinter) return;
    try {
        setIsUploading(true);
        await printLabelForInventoryLotLine({
        inventoryLotLineId: lotLineForPrint.id,
        printerId: printPrinter.id,
        printQty,
        });
        msg(t("Print sent"));
        setPrintModalOpen(false);
    } catch (e: any) {
        msgError(e?.message ?? t("Print failed"));
    } finally {
        setIsUploading(false);
    }
    }, [lotLineForPrint, printPrinter, printQty, setIsUploading, t]);

    const onDetailClick = useCallback(
      (lotLine: InventoryLotLineResult) => {
        downloadQrCode(lotLine.id)
        // lot line id to find stock in line
      },
      [downloadQrCode],
    );
    const columns = useMemo<Column<InventoryLotLineResult>[]>(
        () => [
            // {
            //     name: "item",
            //     label: t("Code"),
            //     renderCell: (params) => {
            //         return params.item.code;
            //     },
            // },
            // {
            //     name: "item",
            //     label: t("Name"),
            //     renderCell: (params) => {
            //         return params.item.name;
            //     },
            // },
            {
                name: "lotNo",
                label: t("Lot No"),
            },
            // {
            //     name: "item",
            //     label: t("Type"),
            //     renderCell: (params) => {
            //         return t(params.item.type);
            //     },
            // },
            {
                name: "availableQty",
                label: t("Available Qty"),
                align: "right",
                headerAlign: "right",
                type: "integer",
            },
            {
                name: "uom",
                label: t("Stock UoM"),
                align: "left",
                headerAlign: "left",
            },
            // {
            //     name: "qtyPerSmallestUnit",
            //     label: t("Available Qty Per Smallest Unit"),
            //     align: "right",
            //     headerAlign: "right",
            //     type: "integer",
            // },
            // {
            //     name: "baseUom",
            //     label: t("Base UoM"),
            //     align: "left",
            //     headerAlign: "left",
            // },
            {
                name: "expiryDate",
                label: t("Expiry Date"),
                renderCell: (params) => {
                    return arrayToDateString(params.expiryDate)
                },
            },
            {
                name: "warehouse",
                label: t("Warehouse"),
                renderCell: (params) => {
                    return `${params.warehouse.code}`
                },
            },
            {
                name: "id",
                label: t("Download QR Code"),
                onClick: onDetailClick,
                buttonIcon: <QrCodeIcon />,
                align: "center",
                headerAlign: "center",
            },
            {
                name: "id",
                label: t("Print QR Code"),
                onClick: handlePrintClick,
                buttonIcon: <PrintIcon />,
                align: "center",
                headerAlign: "center",
            },
            {
                name: "id",
                label: t("Stock Transfer"),
                onClick: handleStockTransfer,
                buttonIcon: <SwapHoriz />,
                align: "center",
                headerAlign: "center",
            },
            // {
            //     name: "status",
            //     label: t("Status"),
            //     type: "icon",
            //     icons: {
            //         available: <CheckCircleOutline fontSize="small"/>,
            //         unavailable: <DoDisturb fontSize="small"/>,
            //     },
            //     colors: {
            //         available: "success",
            //         unavailable: "error",
            //     }
            // },
        ],
        [t, onDetailClick, downloadQrCode, handleStockTransfer, handlePrintClick],
    );

    

    const handleCloseStockTransferModal = useCallback(() => {
    setStockTransferModalOpen(false);
    setSelectedLotLine(null);
    setStartLocation("");
    setTargetLocation(null);
    setTargetLocationInput("");
    setQtyToBeTransferred("");
    }, []);

    const handleSubmitStockTransfer = useCallback(async () => {
    if (!selectedLotLine || !targetLocation || validatedTransferQty < 1 || validatedTransferQty > originalQty) {
        return;
    }

    try {
        setIsUploading(true);
        
        const request = {
        inventoryLotLineId: selectedLotLine.id,
        transferredQty: validatedTransferQty,
        warehouseId: targetLocation, // targetLocation now contains warehouse ID
        };

        const response = await createStockTransfer(request);
        
        if (response && response.type === "success") {
        const successMsg =
          response.code === "MERGED_EXISTING_LOT_AMBIGUOUS"
            ? t("Stock transfer merged ambiguous")
            : response.code === "MERGED_EXISTING_LOT"
              ? t("Stock transfer merged existing lot")
              : response.code === "CREATED_NEW_LOT"
                ? t("Stock transfer created new lot")
                : response.message?.trim() || t("Stock transfer successful");
        msg(successMsg);
        handleCloseStockTransferModal();
        await onStockTransferSuccess?.();
        } else {
        throw new Error(response?.message || t("Failed to transfer stock"));
        }
    } catch (error: any) {
        console.error("Error transferring stock:", error);
        msgError(error?.message || t("Failed to transfer stock. Please try again."));
    } finally {
        setIsUploading(false);
    }
}, [selectedLotLine, targetLocation, validatedTransferQty, originalQty, handleCloseStockTransferModal, setIsUploading, t, onStockTransferSuccess]);

    return <>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap', mb: 2 }}>
  <Typography variant="h6">
    {inventory ? `${t("Item selected")}: ${inventory.itemCode} | ${inventory.itemName} (${t(inventory.itemType)})` : t("No items are selected yet.")}
  </Typography>
{inventory && (
  <Chip
    icon={<TuneIcon />}
    label={t("Stock Adjustment")}
    onClick={() => setStockAdjustmentModalOpen(true)}
    sx={{
      cursor: 'pointer',
      height: 30,
      fontWeight: 'bold',
      '& .MuiChip-label': {
        fontSize: '0.875rem',
        fontWeight: 'bold',
      },
      '& .MuiChip-icon': {
        fontSize: '1rem',
      },
    }}
  />
)}
</Box>
    
    <SearchResults<InventoryLotLineResult>
        items={availableLotLines}
        columns={columns}
        pagingController={pagingController}
        setPagingController={setPagingController}
        totalCount={totalCount}
    />
    
    <Modal
      open={stockTransferModalOpen}
      onClose={handleCloseStockTransferModal}
      sx={{
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
      }}
    >
      <Card
        sx={{
          position: 'relative',
          width: '95%',
          maxWidth: '1200px',
          maxHeight: '90vh',
          overflow: 'auto',
          p: 3,
        }}
      >
        <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
          <Typography variant="h6">
            {inventory && selectedLotLine 
              ? `${inventory.itemCode} ${inventory.itemName} (${selectedLotLine.lotNo})`
              : t("Stock Transfer")
            }
          </Typography>
          <IconButton onClick={handleCloseStockTransferModal}>
            <CloseIcon />
          </IconButton>
        </Box>
        <Grid container spacing={1} sx={{ mt: 2 }}>
        <Grid item xs={5.5}>
            <TextField
                label={t("Start Location")}
                fullWidth
                variant="outlined"
                value={startLocation}
                disabled
                InputLabelProps={{
                    shrink: !!startLocation,
                    sx: { fontSize: "0.9375rem" },
                }}
            />
        </Grid>
        <Grid item xs={1} sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <Typography variant="body1">{t("to")}</Typography>
        </Grid>
        <Grid item xs={5.5}>
        <Autocomplete
        options={warehouses.filter(w => w.code !== startLocation)}
        getOptionLabel={(option) => option.code || ""}
        value={targetLocation ? warehouses.find(w => w.id === targetLocation) || null : null}
        inputValue={targetLocationInput}
        onInputChange={(event, newInputValue) => {
            setTargetLocationInput(newInputValue);
            if (targetLocation && newInputValue !== warehouses.find(w => w.id === targetLocation)?.code) {
            setTargetLocation(null);
            }
        }}
        onChange={(event, newValue) => {
            if (newValue) {
            setTargetLocation(newValue.id);
            setTargetLocationInput(newValue.code);
            } else {
            setTargetLocation(null);
            setTargetLocationInput("");
            }
        }}
        filterOptions={(options, { inputValue }) => {
            if (!inputValue || inputValue.trim() === "") return options;
            const searchTerm = inputValue.toLowerCase().trim();
            return options.filter((option) =>
            (option.code || "").toLowerCase().includes(searchTerm) ||
            (option.name || "").toLowerCase().includes(searchTerm) ||
            (option.description || "").toLowerCase().includes(searchTerm)
            );
        }}
        isOptionEqualToValue={(option, value) => option.id === value.id}
        autoHighlight={false}
        autoSelect={false}
        clearOnBlur={false}
        renderOption={(props, option) => (
            <li {...props}>
            {option.code}
            </li>
        )}
        renderInput={(params) => (
            <TextField
            {...params}
            label={t("Target Location")}
            variant="outlined"
            fullWidth
            InputLabelProps={{
                shrink: !!targetLocation || !!targetLocationInput,
                sx: { fontSize: "0.9375rem" },
            }}
            />
        )}
        />
        </Grid>
        </Grid>
        <Grid container spacing={1} sx={{ mt: 2 }}>
            <Grid item xs={2}>
                <TextField
                    label={t("Original Qty")}
                    fullWidth
                    variant="outlined"
                    value={originalQty}
                    disabled
                    InputLabelProps={{
                        shrink: true,
                        sx: { fontSize: "0.9375rem" },
                    }}
                />
            </Grid>
            <Grid item xs={1} sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <Typography variant="body1">-</Typography>
            </Grid>
            <Grid item xs={2}>
                <TextField
                    label={t("Qty To Be Transferred")}
                    fullWidth
                    variant="outlined"
                    type="text"
                    inputMode="numeric"
                    value={qtyToBeTransferred}
                    onChange={(e) => {
                        const raw = e.target.value.replace(/\D/g, '');
                        if (raw === '') {
                            setQtyToBeTransferred('');
                            return;
                        }
                        const parsed = parseInt(raw, 10);
                        if (Number.isNaN(parsed)) {
                            setQtyToBeTransferred('');
                            return;
                        }
                        if (originalQty < 1) {
                            setQtyToBeTransferred('');
                            return;
                        }
                        const clamped = Math.min(Math.max(1, parsed), originalQty);
                        setQtyToBeTransferred(String(clamped));
                    }}
                    onFocus={(e) => (e.target as HTMLInputElement).select()}
                    inputProps={{ pattern: "[0-9]*" }}
                    InputLabelProps={{
                        shrink: true,
                        sx: { fontSize: "0.9375rem" },
                    }}
                />
            </Grid>
            <Grid item xs={1} sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <Typography variant="body1">=</Typography>
            </Grid>
            <Grid item xs={2}>
                <TextField
                    label={t("Remaining Qty")}
                    fullWidth
                    variant="outlined"
                    value={remainingQty}
                    disabled
                    InputLabelProps={{
                        shrink: true,
                        sx: { fontSize: "0.9375rem" },
                    }}
                />
            </Grid>
            <Grid item xs={2}>
                <TextField
                    label={t("Stock UoM")}
                    fullWidth
                    variant="outlined"
                    value={selectedLotLine?.uom || ""}
                    disabled
                    InputLabelProps={{
                        shrink: true,
                        sx: { fontSize: "0.9375rem" },
                    }}
                />
            </Grid>
            <Grid item xs={2} sx={{ display: 'flex', alignItems: 'center' }}>
                <Button
                    variant="contained"
                    fullWidth
                    sx={{ 
                        height: '56px',
                        fontSize: '0.9375rem',
                    }}
                    onClick={handleSubmitStockTransfer}
                    disabled={!selectedLotLine || !targetLocation || validatedTransferQty < 1 || validatedTransferQty > originalQty}
                >
                    {t("Submit")}
                </Button>
            </Grid>
        </Grid>
      </Card> 
    </Modal>

<Modal
  open={printModalOpen}
  onClose={() => setPrintModalOpen(false)}
  sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}
>
  <Card sx={{ position: 'relative', minWidth: 320, maxWidth: 480, p: 3 }}>
    <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
      <Typography variant="h6">{t("Print QR Code")}</Typography>
      <IconButton onClick={() => setPrintModalOpen(false)}><CloseIcon /></IconButton>
    </Box>
    <Grid container spacing={2}>
      <Grid item xs={12}>
        <Autocomplete
          options={(printerCombo || []).filter(printer => printer.type === 'Label')}
          getOptionLabel={(opt) => opt.name ?? opt.label ?? opt.code ?? `Printer ${opt.id}`}
          value={printPrinter}
          onChange={(_, v) => {
            setPrintPrinter(v);
            if (typeof sessionStorage !== 'undefined') {
              if (v?.id != null) sessionStorage.setItem(PRINT_PRINTER_ID_KEY, String(v.id));
              else sessionStorage.removeItem(PRINT_PRINTER_ID_KEY);
            }
          }}
          renderInput={(params) => <TextField {...params} label={t("Printer")} />}
        />
      </Grid>
      <Grid item xs={12}>
        <TextField
          label={t("Print Qty")}
          type="number"
          value={printQty}
          onChange={(e) => setPrintQty(Math.max(1, parseInt(e.target.value) ))}
          inputProps={{ min: 1 }}
          fullWidth
        />
      </Grid>
      <Grid item xs={12}>
        <Button variant="contained" fullWidth onClick={handlePrintConfirm} disabled={!printPrinter}>
          {t("Print")}
        </Button>
      </Grid>
    </Grid>
  </Card>
</Modal>
<Modal
  open={stockAdjustmentModalOpen}
  onClose={() => setStockAdjustmentModalOpen(false)}
  sx={{
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
  }}
>
  <Card
    sx={{
    position: 'relative',
    width: '95%',
    maxWidth: '1400px',
    maxHeight: '92vh',
    overflow: 'auto',
    p: 3,
    }}
  >
    <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
    <Typography variant="h6">
{inventory
  ? `${t("Edit mode")}: ${inventory.itemCode} ${inventory.itemName}`
  : t("Stock Adjustment")
}
    </Typography>
      <IconButton onClick={() => setStockAdjustmentModalOpen(false)}>
        <CloseIcon />
      </IconButton>
    </Box>
<Box sx={{ display: 'flex', gap: 1, mb: 2 }}>
    <Button
    variant="contained"
    startIcon={<AddIcon />}
    onClick={handleOpenAddEntry}
    >
    {t("Add entry")}
    </Button>
  <Button
    variant="outlined"
    startIcon={<RestartAltIcon />}
    onClick={handleAdjustmentReset}
  >
    {t("Reset")}
  </Button>
    <Button
    variant="contained"
    color="primary"
    startIcon={<SaveIcon />}
    onClick={handleAdjustmentSave}
    disabled={!hasAdjustmentChange}
    >
    {t("Save")}
    </Button>
</Box>

{/* List view */}
<Box sx={{ overflow: 'auto' }}>
  <Table size="small">
    <TableHead>
      <TableRow>
        <TableCell>{t("Lot No")}</TableCell>
        <TableCell align="right">{t("Original Qty")}</TableCell>
        <TableCell align="right">{t("Adjusted Qty")}</TableCell>
        <TableCell align="right" sx={{ minWidth: 100 }}>{t("Difference")}</TableCell>
        <TableCell>{t("Stock UoM")}</TableCell>
        <TableCell>{t("Expiry Date")}</TableCell>
        <TableCell>{t("Location")}</TableCell>
        <TableCell>{t("Remarks")}</TableCell>
        <TableCell align="center" sx={{ minWidth: 240 }}>{t("Action")}</TableCell>
      </TableRow>
    </TableHead>
    <TableBody>
      {adjustmentEntries.map((line) => (
        <TableRow
        key={line.id}
        sx={{
            backgroundColor: pendingRemovalLineId === line.id ? 'action.hover' : undefined,
        }}
        >
            <TableCell>
              <Box component="span" sx={{ display: 'flex', flexDirection: 'column', gap: 0.25 }}>
                <span>
                  {line.lotNo?.trim() ? line.lotNo : t("No lot no entered, will be generated by system.")}
                  {line.isOpeningInventory && ` (${t("Opening Inventory")})`}
                </span>
                {line.productlotNo && <span>{t("productLotNo")}: {line.productlotNo}</span>}
                {line.dnNo && <span>{t("dnNo")}: {line.dnNo}</span>}
              </Box>
            </TableCell>
            <TableCell align="right">{line.originalQty ?? 0}</TableCell>
            <TableCell align="right">
              <TextField
                type="text"
                inputMode="numeric"
                value={String(line.adjustedQty)}
                onChange={(e) => {
                  const raw = e.target.value.replace(/\D/g, '');
                  if (raw === '') {
                    handleAdjustmentQtyChange(line.id, 0);
                    return;
                  }
                  const num = parseInt(raw, 10);
                  if (!Number.isNaN(num) && num >= 0) handleAdjustmentQtyChange(line.id, num);
                }}
                inputProps={{ style: { textAlign: 'right' } }}
                size="small"
                sx={{
                  width: 120,
                  '& .MuiInputBase-root': {
                    display: 'flex',
                    alignItems: 'center',
                    height: 56,
                  },
                  '& .MuiInputBase-input': {
                    fontSize: 16,
                    textAlign: 'right',
                    height: 40,
                    lineHeight: '40px',
                    paddingTop: 0,
                    paddingBottom: 0,
                    boxSizing: 'border-box',
                    MozAppearance: 'textfield',
                  },
                  '& .MuiInputBase-input::-webkit-outer-spin-button': {
                    WebkitAppearance: 'none',
                    margin: 0,
                  },
                  '& .MuiInputBase-input::-webkit-inner-spin-button': {
                    WebkitAppearance: 'none',
                    margin: 0,
                  },
                }}
              />
            </TableCell>
            <TableCell align="right" sx={{ minWidth: 100, fontWeight: 700 }}>
            {(() => {
                const diff = line.adjustedQty - (line.originalQty ?? 0);
                const text = diff > 0 ? `+${diff}` : diff < 0 ? `${diff}` : '±0';
                const color = diff > 0 ? 'success.main' : diff < 0 ? 'error.main' : 'text.secondary';
                return <Box component="span" sx={{ color }}>{text}</Box>;
            })()}
            </TableCell>
            <TableCell>{line.uom}</TableCell>
          <TableCell>{arrayToDateString(line.expiryDate)}</TableCell>
          <TableCell>{line.warehouse?.code ?? ""}</TableCell>
            <TableCell>
            {pendingRemovalLineId === line.id ? (
                <TextField
                    size="small"
                    placeholder={t("Reason for removal")}
                    value={removalReasons[line.id] ?? ""}
                    onChange={(e) => handleRemovalReasonChange(line.id, e.target.value)}
                    sx={{
                    width: 160,
                    maxWidth: '100%',
                    '& .MuiInputBase-root': {
                    display: 'flex',
                    alignItems: 'center',
                    height: 56,
                    },
                    '& .MuiInputBase-input': {
                    fontSize: '1rem',
                    height: 40,
                    lineHeight: '40px',
                    paddingTop: 0,
                    paddingBottom: 0,
                    boxSizing: 'border-box',
                    '&::placeholder': { color: '#9e9e9e', opacity: 1 },
                    },
                    }}
                />
            ) : (line.adjustedQty - (line.originalQty ?? 0)) !== 0 ? (
                <TextField
                size="small"
                placeholder={t("Reason for adjustment")}
                value={line.remarks ?? ""}
                onChange={(e) => handleAdjustmentRemarksChange(line.id, e.target.value)}
                sx={{
                    width: 160,
                    maxWidth: '100%',
                    '& .MuiInputBase-root': {
                    display: 'flex',
                    alignItems: 'center',
                    height: 56,
                    },
                    '& .MuiInputBase-input': {
                    fontSize: '1rem',
                    height: 40,
                    lineHeight: '40px',
                    paddingTop: 0,
                    paddingBottom: 0,
                    boxSizing: 'border-box',
                    '&::placeholder': { color: '#9e9e9e', opacity: 1 },
                    },
                }}
                />
            ) : null}
            </TableCell>
            <TableCell align="center">
            {pendingRemovalLineId === line.id ? (
                <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 0.5 }}>
                    <Button size="small" variant="outlined" onClick={handleCancelRemoval}>
                        {t("Cancel")}
                    </Button>
                    <Button
                        size="small"
                        variant="contained"
                        color="error"
                        startIcon={<CheckIcon />}
                        onClick={() => handleConfirmRemoval(line.id)}
                    >
                        {t("Confirm remove")}
                    </Button>
                </Box>
            ) : (
                <IconButton
                size="small"
                onClick={() => handleRemoveClick(line.id)}
                color="error"
                title={t("Remove")}
                >
                <DeleteIcon fontSize="small" />
                </IconButton>
            )}
            </TableCell>
        </TableRow>
      ))}
    </TableBody>
  </Table>
</Box>
  </Card>
</Modal>

<Modal
  open={addEntryModalOpen}
  onClose={() => setAddEntryModalOpen(false)}
  sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}
>
<Card sx={{ position: 'relative', minWidth: 600, maxWidth: 900, p: 3 }}>
    <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
      <Typography variant="h6">{t("Add entry")}</Typography>
      <IconButton onClick={() => setAddEntryModalOpen(false)}><CloseIcon /></IconButton>
    </Box>
<Grid container spacing={2}>
  <Grid item xs={4}>
    <TextField label={t("Available Qty")} type="number" fullWidth required value={addEntryForm.qty || ''} onChange={(e) => setAddEntryForm(f => ({ ...f, qty: Math.max(0, parseInt(e.target.value) || 0) }))} inputProps={{ min: 0 }} />
  </Grid>
  <Grid item xs={4}>
    <TextField label={t("Stock UoM")} fullWidth disabled value={inventory?.uomUdfudesc || inventory?.uomShortDesc || inventory?.uomCode || ''} sx={{ '& .MuiInputBase-input': { color: 'text.secondary' } }} InputLabelProps={{ shrink: true }} />
  </Grid>
  <Grid item xs={4}>
    <LocalizationProvider dateAdapter={AdapterDayjs}>
      <DatePicker label={t("Expiry Date")} format={INPUT_DATE_FORMAT} value={addEntryForm.expiryDate ? dayjs(addEntryForm.expiryDate) : null} onChange={(value) => setAddEntryForm(f => ({ ...f, expiryDate: value ? dayjs(value).format(INPUT_DATE_FORMAT) : '' }))} slotProps={{ textField: { fullWidth: true, required: true } }} />
    </LocalizationProvider>
  </Grid>
  <Grid item xs={6}>
    <Autocomplete options={warehouses} getOptionLabel={(o) => o.code || ''} value={addEntryForm.locationId ? warehouses.find(w => w.id === addEntryForm.locationId) ?? null : null} inputValue={addEntryForm.locationInput} onInputChange={(_, v) => setAddEntryForm(f => ({ ...f, locationInput: v }))} onChange={(_, v) => setAddEntryForm(f => ({ ...f, locationId: v?.id ?? null, locationInput: v?.code ?? '' }))} renderInput={(params) => <TextField {...params} label={t("Location")} required />} />
  </Grid>
  <Grid item xs={6} sx={{ display: 'flex', alignItems: 'center' }}>
    <FormControlLabel control={<Checkbox checked={addEntryForm.isOpeningInventory} onChange={(e) => setAddEntryForm(f => ({ ...f, isOpeningInventory: e.target.checked }))} />} label={t("Opening Inventory")} />
  </Grid>
  <Grid item xs={4}>
<TextField label={t("productLotNo")} fullWidth placeholder={t("Optional - system will generate")} value={addEntryForm.productlotNo} onChange={(e) => setAddEntryForm(f => ({ ...f, productlotNo: e.target.value }))} sx={{ '& .MuiInputBase-input::placeholder': { color: '#9e9e9e', opacity: 1 } }} />
  </Grid>
  <Grid item xs={4}>
<TextField label={t("dnNo")} fullWidth placeholder={t("Optional - system will generate")} value={addEntryForm.dnNo} onChange={(e) => setAddEntryForm(f => ({ ...f, dnNo: e.target.value }))} sx={{ '& .MuiInputBase-input::placeholder': { color: '#9e9e9e', opacity: 1 } }} />
  </Grid>
  <Grid item xs={4}>
<TextField label={t("Lot No")} fullWidth placeholder={t("Optional - system will generate")} value={addEntryForm.lotNo} onChange={(e) => setAddEntryForm(f => ({ ...f, lotNo: e.target.value }))} sx={{ '& .MuiInputBase-input::placeholder': { color: '#9e9e9e', opacity: 1 } }} />
  </Grid>
    <Grid item xs={12}>
    <TextField
      label={t("Remarks")}
      fullWidth
      placeholder={t("Reason for adjustment")}
      value={addEntryForm.remarks}
      onChange={(e) => setAddEntryForm(f => ({ ...f, remarks: e.target.value }))}
      multiline
      minRows={2}
      sx={{ '& .MuiInputBase-input::placeholder': { color: '#9e9e9e', opacity: 1 } }}
    />
  </Grid>
  <Grid item xs={12}>
    <Button variant="contained" fullWidth onClick={handleAddEntrySubmit} disabled={addEntryForm.qty < 0 || !addEntryForm.expiryDate || !addEntryForm.locationId}>
      {t("Add")}
    </Button>
  </Grid>
</Grid>
  </Card>
</Modal>
</>

}

export default InventoryLotLineTable;