"use client";

import {
  Box,
  Button,
  Stack,
  Typography,
  Chip,
  CircularProgress,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
  TextField,
  Radio,
  TablePagination,
  TableSortLabel,
  Card,
  CardContent,
  CardActions,
  Grid,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  Autocomplete,
  FormControlLabel,
  Checkbox,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
} from "@mui/material";
import { useState, useCallback, useEffect, useMemo, useRef } from "react";
import { Collapse } from "@mui/material";
import Accordion from "@mui/material/Accordion";
import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import { useTranslation } from "react-i18next";
import {
  AllPickedStockTakeListReponse,
  InventoryLotDetailResponse,
  SaveApproverStockTakeRecordRequest,
  saveApproverStockTakeRecord,
  batchSaveApproverStockTakeRecordsByIds,
  getApproverInventoryLotDetailsAllPending,
  getApproverInventoryLotDetailsAllApproved,
  updateStockTakeRecordStatusToNotMatch,
  type ApproverInventoryLotDetailsQuery,
} from "@/app/api/stockTake/actions";
import { fetchStockTakeSections } from "@/app/api/warehouse/actions";
import { useSession } from "next-auth/react";
import { SessionWithTokens } from "@/config/authConfig";
import dayjs from "dayjs";
import { OUTPUT_DATE_FORMAT, roundDownPercent } from "@/app/utils/formatUtil";
import { DataGrid, GridColDef, GridRenderCellParams } from '@mui/x-data-grid';
import StyledDataGrid from "@/components/StyledDataGrid/StyledDataGrid";
import type {

  GridPaginationModel,
  GridSortModel,
} from "@mui/x-data-grid";
interface ApproverStockTakeAllProps {
  selectedSession: AllPickedStockTakeListReponse;
  mode: "pending" | "approved";
  onBack?: () => void;
  onSnackbar: (message: string, severity: "success" | "error" | "warning") => void;
}

type QtySelectionType = "first" | "second" | "approver";

type ApprovedSortKey =
  | "stockTakeEndTime"
  | "stockTakeSection"
  | "item"
  | "stockTakerName"
  | "variance";

type ApproverSearchFilters = {
  sectionDescription: string;
  stockTakeSession: string;
  itemKeyword: string;
  warehouseKeyword: string;
  storeId: string;
  status: string;
  variancePercentTolerance: string;
  varianceFilterInclusive: boolean;
  varianceFilterStrict: boolean;
};

function buildApproverInventoryQuery(filters: ApproverSearchFilters): ApproverInventoryLotDetailsQuery {
  const tolerance = filters.variancePercentTolerance.trim();
  return {
    sectionDescription: filters.sectionDescription !== "All" ? filters.sectionDescription : undefined,
    stockTakeSections: filters.stockTakeSession.trim() ? filters.stockTakeSession.trim() : undefined,
    itemKeyword: filters.itemKeyword.trim() ? filters.itemKeyword.trim() : undefined,
    warehouseKeyword: filters.warehouseKeyword.trim() ? filters.warehouseKeyword.trim() : undefined,
    variancePercentTolerance: tolerance !== "" ? tolerance : undefined,
    varianceFilterInclusive: filters.varianceFilterInclusive,
    varianceFilterStrict: filters.varianceFilterStrict,
  };
}

function isBlankApproverField(value: string | undefined): boolean {
  return value == null || String(value).trim() === "";
}

/** 審核員「盤點數」與「不良數」皆未輸入時應跳過儲存，維持 pending */
function isApproverInputsBothEmpty(
  detailId: number,
  approverQty: Record<number, string>,
  approverBadQty: Record<number, string>
): boolean {
  return isBlankApproverField(approverQty[detailId]) && isBlankApproverField(approverBadQty[detailId]);
}

type ApproverSaveBuildResult =
  | {
      ok: true;
      request: SaveApproverStockTakeRecordRequest;
      finalQty: number;
      finalBadQty: number;
      goodQty: number;
      selection: QtySelectionType;
    }
  | { ok: false; reason: "skip_approver_empty" }
  | { ok: false; reason: "error"; message: string };

function buildApproverSaveRequest(
  detail: InventoryLotDetailResponse,
  qtySelection: Record<number, QtySelectionType>,
  approverQty: Record<number, string>,
  approverBadQty: Record<number, string>,
  currentUserId: number,
  t: (key: string) => string
): ApproverSaveBuildResult {
  const selection = qtySelection[detail.id] || "first";
  let finalQty: number;
  let finalBadQty: number;

  if (selection === "first") {
    if (detail.firstStockTakeQty == null) {
      return { ok: false, reason: "error", message: t("First QTY is not available") };
    }
    finalQty = detail.firstStockTakeQty;
    finalBadQty = detail.firstBadQty || 0;
  } else if (selection === "second") {
    if (detail.secondStockTakeQty == null) {
      return { ok: false, reason: "error", message: t("Second QTY is not available") };
    }
    finalQty = detail.secondStockTakeQty;
    finalBadQty = detail.secondBadQty || 0;
  } else {
    if (isApproverInputsBothEmpty(detail.id, approverQty, approverBadQty)) {
      return { ok: false, reason: "skip_approver_empty" };
    }
    const approverQtyValue = approverQty[detail.id] || "0";
    const approverBadQtyValue = approverBadQty[detail.id] || "0";
    finalQty = parseFloat(approverQtyValue) || 0;
    finalBadQty = parseFloat(approverBadQtyValue) || 0;
  }

  const request: SaveApproverStockTakeRecordRequest = {
    stockTakeRecordId: detail.stockTakeRecordId || null,
    qty: finalQty,
    badQty: finalBadQty,
    approverId: currentUserId,
    approverQty: selection === "approver" ? finalQty : null,
    approverBadQty: selection === "approver" ? finalBadQty : null,
    lastSelect: selection === "first" ? 1 : selection === "second" ? 2 : 3,
  };

  const goodQty = finalQty - finalBadQty;
  return { ok: true, request, finalQty, finalBadQty, goodQty, selection };
}

function buildBatchApproverSaveRequests(
  details: InventoryLotDetailResponse[],
  qtySelection: Record<number, QtySelectionType>,
  approverQty: Record<number, string>,
  approverBadQty: Record<number, string>,
  currentUserId: number,
  t: (key: string) => string
): SaveApproverStockTakeRecordRequest[] {
  const records: SaveApproverStockTakeRecordRequest[] = [];
  for (const detail of details) {
    if (!detail.stockTakeRecordId || detail.stockTakeRecordId <= 0) {
      continue;
    }
    const built = buildApproverSaveRequest(
      detail,
      qtySelection,
      approverQty,
      approverBadQty,
      currentUserId,
      t
    );
    if (!built.ok) {
      continue;
    }
    records.push(built.request);
  }
  return records;
}

function parseDateTimeMs(
  v: string | string[] | null | undefined
): number {
  if (v == null) return 0;
  if (Array.isArray(v)) {
    const arr = v as unknown as number[];
    const [y, m, d, h = 0, min = 0, s = 0] = arr;
    return dayjs(`${y}-${String(m).padStart(2, "0")}-${String(d).padStart(2, "0")} ${h}:${min}:${s}`).valueOf();
  }
  return dayjs(v as string).valueOf();
}

const ApproverStockTakeAll: React.FC<ApproverStockTakeAllProps> = ({
  selectedSession,
  mode,
  onBack,
  onSnackbar,
}) => {
  const { t } = useTranslation(["stockTake", "common"]);
  const { data: session } = useSession() as { data: SessionWithTokens | null };

  const [inventoryLotDetails, setInventoryLotDetails] = useState<InventoryLotDetailResponse[]>([]);
  const [loadingDetails, setLoadingDetails] = useState(false);
  const [searchVariancePercentTolerance, setSearchVariancePercentTolerance] = useState<string>("5");
  const [searchVarianceFilterInclusive, setSearchVarianceFilterInclusive] = useState(false);
  const [searchVarianceFilterStrict, setSearchVarianceFilterStrict] = useState(false);
  const [qtySelection, setQtySelection] = useState<Record<number, QtySelectionType>>({});
  const [approverQty, setApproverQty] = useState<Record<number, string>>({});
  const [approverBadQty, setApproverBadQty] = useState<Record<number, string>>({});
  const [saving, setSaving] = useState(false);
  const [batchSaving, setBatchSaving] = useState(false);
  const [updatingStatus, setUpdatingStatus] = useState(false);
  const [page, setPage] = useState(0);
  const [pageSize, setPageSize] = useState<number | string>(50);
  const [total, setTotal] = useState(0);
  const [approvedSortKey, setApprovedSortKey] = useState<ApprovedSortKey | null>(null);
  const [approvedSortDir, setApprovedSortDir] = useState<"asc" | "desc">("asc");
  const [sectionDescriptionOptions, setSectionDescriptionOptions] = useState<string[]>([]);
  const [stockTakeSectionOptions, setStockTakeSectionOptions] = useState<string[]>([]);
  const [storeIdOptions, setStoreIdOptions] = useState<string[]>(["2F", "4F"]);
  const [searchSectionDescription, setSearchSectionDescription] = useState<string>("All");
  const [searchStockTakeSession, setSearchStockTakeSession] = useState<string>("");
  const [searchItemKeyword, setSearchItemKeyword] = useState<string>("");
  const [searchWarehouseKeyword, setSearchWarehouseKeyword] = useState<string>("");
  const [searchStoreId, setSearchStoreId] = useState<string>("All");
  const [searchStatus, setSearchStatus] = useState<string>(mode === "pending" ? "pass" : "All");
  const [showFilters, setShowFilters] = useState(true)
  const [appliedFilters, setAppliedFilters] = useState<ApproverSearchFilters | null>(null);
  const [openBatchSaveConfirmDialog, setOpenBatchSaveConfirmDialog] = useState(false);
  const batchSaveInFlightRef = useRef(false);

  const currentUserId = session?.id ? parseInt(session.id) : undefined;

  const handleChangePage = useCallback((_: unknown, newPage: number) => {
    setPage(newPage);
  }, []);

  const handleChangeRowsPerPage = useCallback(
    (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
      const newSize = parseInt(event.target.value, 10);
      if (newSize === -1) {
        setPageSize("all");
      } else if (!isNaN(newSize)) {
        setPageSize(newSize);
      }
      setPage(0);
    },
    []
  );

  const handleSearch = useCallback(() => {
    const next: ApproverSearchFilters = {
      sectionDescription: searchSectionDescription || "All",
      stockTakeSession: searchStockTakeSession || "",
      itemKeyword: searchItemKeyword || "",
      warehouseKeyword: searchWarehouseKeyword || "",
      storeId: searchStoreId || "All",
      status: mode === "pending" ? (searchStatus || "pass") : "All",
      variancePercentTolerance: searchVariancePercentTolerance,
      varianceFilterInclusive: searchVarianceFilterInclusive,
      varianceFilterStrict: searchVarianceFilterStrict,
    };
    setAppliedFilters(next);
    setPage(0);
  }, [
    searchSectionDescription,
    searchStockTakeSession,
    searchItemKeyword,
    searchWarehouseKeyword,
    searchStoreId,
    searchStatus,
    searchVariancePercentTolerance,
    searchVarianceFilterInclusive,
    searchVarianceFilterStrict,
    mode,
  ]);

  const handleResetSearch = useCallback(() => {
    const defaultStatus = mode === "pending" ? "pass" : "All";
    setSearchSectionDescription("All");
    setSearchStockTakeSession("");
    setSearchItemKeyword("");
    setSearchWarehouseKeyword("");
    setSearchStoreId("All");
    setSearchStatus(defaultStatus);
    setSearchVariancePercentTolerance("5");
    setSearchVarianceFilterInclusive(false);
    setSearchVarianceFilterStrict(false);
    setAppliedFilters(null);
    setPage(0);
    setInventoryLotDetails([]);
    setTotal(0);
  }, [mode]);

  const loadDetails = useCallback(async (filters: ApproverSearchFilters) => {
    setLoadingDetails(true);
    console.time("🔥 Total time from API call to DataGrid ready");

    try {
      const searchQuery: ApproverInventoryLotDetailsQuery = buildApproverInventoryQuery(filters);

      // Always request ALL rows (max 5000)
      const response = mode === "approved"
        ? await getApproverInventoryLotDetailsAllApproved(
            selectedSession.stockTakeId > 0 ? selectedSession.stockTakeId : null,
            0,
            5000,
            searchQuery
          )
        : await getApproverInventoryLotDetailsAllPending(
            selectedSession.stockTakeId > 0 ? selectedSession.stockTakeId : null,
            0,
            5000,
            searchQuery
          );

      console.timeEnd("🔥 Total time from API call to DataGrid ready");

      setInventoryLotDetails(Array.isArray(response.records) ? response.records : []);
      setTotal(response.total ?? response.records?.length ?? 0);
      console.log(`Loaded ${response.records?.length || 0} rows from backend`);
    } catch (e) {
      console.error(e);
      setInventoryLotDetails([]);
    } finally {
      setLoadingDetails(false);
    }
  }, [selectedSession, mode]);
  

  useEffect(() => {
    if (!appliedFilters) return;
    loadDetails(appliedFilters);
  }, [appliedFilters, loadDetails]);

  useEffect(() => {
    fetchStockTakeSections()
      .then((sections) => {
        const descSet = new Set<string>();
        const sectionSet = new Set<string>();
        const storeSet = new Set<string>(["2F", "4F"]);
        sections.forEach((s) => {
          const section = s.stockTakeSection?.trim();
          if (section) sectionSet.add(section);
          const desc = s.stockTakeSectionDescription?.trim();
          if (desc) descSet.add(desc);
          const storeId = s.storeId?.trim();
          if (storeId) storeSet.add(storeId);
        });
        setStockTakeSectionOptions(Array.from(sectionSet).sort((a, b) => a.localeCompare(b)));
        setSectionDescriptionOptions(Array.from(descSet).sort((a, b) => a.localeCompare(b)));
        setStoreIdOptions(Array.from(storeSet).sort((a, b) => a.localeCompare(b)));
      })
      .catch((e) => {
        console.error("Failed to load section descriptions for approver search:", e);
      });
  }, []);

  // 切换模式或盘次时，清空选择与搜索；approved 模式需要以后端结果为准。
  useEffect(() => {
    setQtySelection({});
    setApproverQty({});
    setApproverBadQty({});
    setAppliedFilters(null);
    setSearchStatus(mode === "pending" ? "pass" : "All");
    setPage(0);
    setInventoryLotDetails([]);
    setTotal(0);
  }, [mode, selectedSession.stockTakeId]);

  useEffect(() => {
    const inferSelection = (
      detail: InventoryLotDetailResponse
    ): QtySelectionType => {
      // 优先使用后端记录的 lastSelect（1=First, 2=Second, 3=Approver Input）
      if (detail.lastSelect != null) {
        if (detail.lastSelect === 1) return "first";
        if (detail.lastSelect === 2) return "second";
        if (detail.lastSelect === 3) return "approver";
      }

      // 目标：在 approved 模式下，即使后端把 approver 字段也回填了，
      // 只要 finalQty 来自 first/second（picker 结果），就优先勾选 first/second。
      // 只有匹配不到 first/second 时，才推断为 approver。
      if (detail.finalQty != null) {
        const eps = 1e-6;
        const firstAvailable = detail.firstStockTakeQty;
        const secondAvailable = detail.secondStockTakeQty;

        // 如果这一行确实有 approver 结果，那么 approved 时应该优先显示为 approver
        // （尤其是：picker first 后又手动改 approver input 的情况）
        if (detail.approverQty != null) {
          const approverAvailable =
            detail.approverQty - (detail.approverBadQty ?? 0);
          if (Math.abs(approverAvailable - detail.finalQty) <= eps) {
            return "approver";
          }
        }

        if (secondAvailable != null && Math.abs(secondAvailable - detail.finalQty) <= eps) {
          return "second";
        }

        if (firstAvailable != null && Math.abs(firstAvailable - detail.finalQty) <= eps) {
          return "first";
        }

        // approver 字段口径可能是「available」或「total+bad」两种之一，这里同时尝试两种。
        if (detail.approverQty != null) {
          const approverAvailable = detail.approverQty;
          const approverAvailable2 =
            detail.approverQty - (detail.approverBadQty ?? 0);

          if (
            Math.abs(approverAvailable - detail.finalQty) <= eps ||
            Math.abs(approverAvailable2 - detail.finalQty) <= eps
          ) {
            return "approver";
          }
        }
      }

      // pending/无法反推时：second 存在则默认 second，否则 first
      if (detail.secondStockTakeQty != null && detail.secondStockTakeQty >= 0) {
        return "second";
      }
      return "first";
    };

    const newSelections: Record<number, QtySelectionType> = {};
    inventoryLotDetails.forEach((detail) => {
      if (qtySelection[detail.id]) return;
      newSelections[detail.id] = inferSelection(detail);
    });

    if (Object.keys(newSelections).length > 0) {
      setQtySelection((prev) => ({ ...prev, ...newSelections }));
    }
  }, [inventoryLotDetails, qtySelection]);

  // approved 模式下：把已保存的 approver 输入值回填到 TextField，避免“radio 显示了但输入框为空”
  useEffect(() => {
    if (mode !== "approved") return;

    const newApproverQty: Record<number, string> = {};
    const newApproverBadQty: Record<number, string> = {};

    inventoryLotDetails.forEach((detail) => {
      if (detail.approverQty != null && approverQty[detail.id] == null) {
        newApproverQty[detail.id] = String(detail.approverQty);
      }
      if (
        detail.approverBadQty != null &&
        approverBadQty[detail.id] == null
      ) {
        newApproverBadQty[detail.id] = String(detail.approverBadQty);
      }
    });

    if (Object.keys(newApproverQty).length > 0) {
      setApproverQty((prev) => ({ ...prev, ...newApproverQty }));
    }
    if (Object.keys(newApproverBadQty).length > 0) {
      setApproverBadQty((prev) => ({ ...prev, ...newApproverBadQty }));
    }
  }, [mode, inventoryLotDetails, approverQty, approverBadQty]);

  const calculateDifference = useCallback(
    (detail: InventoryLotDetailResponse, selection: QtySelectionType): number => {
      let selectedQty = 0;

      if (selection === "first") {
        selectedQty = detail.firstStockTakeQty || 0;
      } else if (selection === "second") {
        selectedQty = detail.secondStockTakeQty || 0;
      } else if (selection === "approver") {
        selectedQty =
          (parseFloat(approverQty[detail.id] || "0") -
            parseFloat(approverBadQty[detail.id] || "0")) || 0;
      }

      const bookQty = detail.bookQty != null ? detail.bookQty : detail.availableQty || 0;
      return selectedQty - bookQty;
    },
    [approverQty, approverBadQty]
  );
  const normalizeStatus = (v: unknown) =>
    String(v ?? "")
      .trim()
      .toLowerCase()
      .replaceAll("_", "");
  const filteredDetails = useMemo(() => {
    const statusFilter = mode === "pending" ? (appliedFilters?.status ?? "pass") : "All";
    const storeIdFilter = appliedFilters?.storeId ?? "All";
    return inventoryLotDetails.filter((detail) => {
      if (storeIdFilter !== "All") {
        if ((detail.storeId || "").trim().toLowerCase() !== storeIdFilter.trim().toLowerCase()) {
          return false;
        }
      }
      if (statusFilter !== "All") {
        const rowStatus = normalizeStatus(detail.stockTakeRecordStatus);
        const wanted = normalizeStatus(statusFilter);
        if (rowStatus !== wanted) return false;
      }
      return true;
    });
  }, [inventoryLotDetails, appliedFilters, mode]);

  const sortedDetails = useMemo(() => {
    const list = [...filteredDetails];
    if (mode !== "approved") {
      return list.sort((a, b) =>
        (a.stockTakeSection || "").localeCompare(b.stockTakeSection || "", undefined, {
          numeric: true,
          sensitivity: "base",
        })
      );
    }
    const key = approvedSortKey ?? "stockTakeSection";
    const mul = approvedSortDir === "asc" ? 1 : -1;
    return list.sort((a, b) => {
      let cmp = 0;
      switch (key) {
        case "stockTakeEndTime":
          cmp =
            parseDateTimeMs(a.approverTime ?? a.stockTakeEndTime) -
            parseDateTimeMs(b.approverTime ?? b.stockTakeEndTime);
          break;
        case "stockTakeSection":
          cmp = (a.stockTakeSection || "").localeCompare(b.stockTakeSection || "", undefined, {
            numeric: true,
            sensitivity: "base",
          });
          break;
        case "item":
          cmp = `${a.itemCode || ""} ${a.itemName || ""}`.localeCompare(
            `${b.itemCode || ""} ${b.itemName || ""}`,
            undefined,
            { numeric: true, sensitivity: "base" }
          );
          break;
        case "stockTakerName":
          cmp = (a.stockTakerName || "").localeCompare(b.stockTakerName || "", undefined, {
            numeric: true,
            sensitivity: "base",
          });
          break;
        case "variance":
          cmp = Number(a.varianceQty ?? 0) - Number(b.varianceQty ?? 0);
          break;
        default:
          cmp = 0;
      }
      return cmp * mul;
    });
  }, [filteredDetails, mode, approvedSortKey, approvedSortDir]);
  useEffect(() => {
    if (inventoryLotDetails.length === 0) return;

    console.group(` ApproverStockTakeAll - ${inventoryLotDetails.length} rows`);
    console.time("1. After API response");

    // Timing point 1: right after data is set
    console.timeEnd("1. After API response");

    // Timing point 2: after inferSelection
    console.time("2. inferSelection useEffect");
  }, [inventoryLotDetails]);

  // Add this useEffect to measure inferSelection
  useEffect(() => {
    if (inventoryLotDetails.length === 0) return;
    console.timeEnd("2. inferSelection useEffect");
    console.time("3. filteredDetails memo");
  }, [inventoryLotDetails, qtySelection]);

  // Add this to measure filteredDetails
  useEffect(() => {
    console.timeEnd("3. filteredDetails memo");
    console.time("4. sortedDetails memo");
  }, [filteredDetails]);

  // Add this to measure sortedDetails
  useEffect(() => {
    console.timeEnd("4. sortedDetails memo");
    console.time("5. Before DataGrid render");
  }, [sortedDetails]);
  const handleApprovedSort = useCallback((property: ApprovedSortKey) => {
    if (approvedSortKey === property) {
      setApprovedSortDir((d) => (d === "asc" ? "desc" : "asc"));
    } else {
      setApprovedSortKey(property);
      setApprovedSortDir("asc");
    }
  }, [approvedSortKey]);

  const handleSaveApproverStockTake = useCallback(
    async (detail: InventoryLotDetailResponse) => {
      if (mode === "approved") return;
      if (!selectedSession || !currentUserId) {
        return;
      }

      const built = buildApproverSaveRequest(
        detail,
        qtySelection,
        approverQty,
        approverBadQty,
        currentUserId,
        t
      );
      if (!built.ok) {
        if (built.reason === "skip_approver_empty") {
          onSnackbar(t("Approver input empty; save skipped, row remains pending"), "warning");
          return;
        }
        onSnackbar(built.message, "error");
        return;
      }

      const { request, goodQty, finalQty, finalBadQty, selection } = built;

      setSaving(true);
      try {
        await saveApproverStockTakeRecord(request, selectedSession.stockTakeId);

        onSnackbar(t("Approver stock take record saved successfully"), "success");

        setInventoryLotDetails((prev) =>
          prev.map((d) =>
            d.id === detail.id
              ? {
                  ...d,
                  finalQty: goodQty,
                  approverQty: selection === "approver" ? finalQty : d.approverQty,
                  approverBadQty: selection === "approver" ? finalBadQty : d.approverBadQty,
                  stockTakeRecordStatus: "completed",
                }
              : d
          )
        );
      } catch (e: any) {
        console.error("Save approver stock take record error:", e);
        let errorMessage = t("Failed to save approver stock take record");

        if (e?.message) {
          errorMessage = e.message;
        } else if (e?.response) {
          try {
            const errorData = await e.response.json();
            errorMessage = errorData.message || errorData.error || errorMessage;
          } catch {
          }
        }

        onSnackbar(errorMessage, "error");
      } finally {
        setSaving(false);
      }
    },
    [selectedSession, currentUserId, qtySelection, approverQty, approverBadQty, t, onSnackbar, mode]
  );

  const handleUpdateStatusToNotMatch = useCallback(
    async (detail: InventoryLotDetailResponse) => {
      if (mode === "approved") return;
      if (!detail.stockTakeRecordId) {
        onSnackbar(t("Stock take record ID is required"), "error");
        return;
      }

      setUpdatingStatus(true);
      try {
        await updateStockTakeRecordStatusToNotMatch(detail.stockTakeRecordId);

        onSnackbar(t("Stock take record status updated to not match"), "success");
        setInventoryLotDetails((prev) =>
          prev.map((d) =>
            d.id === detail.id ? { ...d, stockTakeRecordStatus: "notMatch" } : d
          )
        );
      } catch (e: any) {
        console.error("Update stock take record status error:", e);
        let errorMessage = t("Failed to update stock take record status");

        if (e?.message) {
          errorMessage = e.message;
        } else if (e?.response) {
          try {
            const errorData = await e.response.json();
            errorMessage = errorData.message || errorData.error || errorMessage;
          } catch {
          }
        }

        onSnackbar(errorMessage, "error");
      } finally {
        setUpdatingStatus(false);
      }
    },
    [t, onSnackbar]
  );
  const blockNonIntegerKeys = (e: React.KeyboardEvent<HTMLInputElement>) => {
    // 禁止小数点、逗号、科学计数、正负号
    if ([".", ",", "e", "E", "+", "-"].includes(e.key)) {
      e.preventDefault();
    }
  };
  
  const sanitizeIntegerInput = (value: string) => {
    // 只保留数字
    return value.replace(/[^\d]/g, "");
  };

  const sanitizePositiveDecimalInput = (value: string) => {
    const unsigned = value.replace(/[^\d.]/g, "");
    const parts = unsigned.split(".");
    return parts.length <= 1 ? unsigned : `${parts[0]}.${parts.slice(1).join("")}`;
  };

  const isIntegerString = (value: string) => /^\d+$/.test(value);
  const batchApproverSaveRecords = useMemo(
    () =>
      currentUserId
        ? buildBatchApproverSaveRequests(
            sortedDetails,
            qtySelection,
            approverQty,
            approverBadQty,
            currentUserId,
            t
          )
        : [],
    [sortedDetails, qtySelection, approverQty, approverBadQty, currentUserId, t]
  );

  const batchSaveSectionLabels = useMemo(() => {
    const labels = new Set<string>();
    sortedDetails.forEach((d) => {
      const sec = d.stockTakeSection?.trim();
      if (sec) labels.add(sec);
    });
    return Array.from(labels).sort((a, b) => a.localeCompare(b));
  }, [sortedDetails]);

  const handleOpenBatchSaveConfirm = useCallback(() => {
    if (mode === "approved") return;
    if (!selectedSession || !currentUserId) return;
    if (inventoryLotDetails.length === 0) {
      onSnackbar(t("No rows loaded; set search criteria and search first"), "warning");
      return;
    }
    if (batchApproverSaveRecords.length === 0) {
      onSnackbar(t("No valid records to batch save"), "warning");
      return;
    }
    setOpenBatchSaveConfirmDialog(true);
  }, [
    mode,
    selectedSession,
    currentUserId,
    inventoryLotDetails.length,
    batchApproverSaveRecords.length,
    onSnackbar,
    t,
  ]);

  const handleBatchSubmitAll = useCallback(async () => {
    if (batchSaveInFlightRef.current) return;
    if (mode === "approved") return;
    if (!selectedSession || !currentUserId) return;

    const records = buildBatchApproverSaveRequests(
      sortedDetails,
      qtySelection,
      approverQty,
      approverBadQty,
      currentUserId,
      t
    );
    if (records.length === 0) {
      onSnackbar(t("No valid records to batch save"), "warning");
      return;
    }

    batchSaveInFlightRef.current = true;
    setBatchSaving(true);
    setOpenBatchSaveConfirmDialog(false);

    try {
      const result = await batchSaveApproverStockTakeRecordsByIds({
        stockTakeId: selectedSession.stockTakeId,
        approverId: currentUserId,
        recordIds: records
          .map((r) => r.stockTakeRecordId)
          .filter((id): id is number => typeof id === "number" && id > 0),
        records,
      });

      onSnackbar(
        t("Batch approver save completed: {{success}} success, {{errors}} errors", {
          success: result.successCount,
          errors: result.errorCount,
        }),
        result.errorCount > 0 ? "warning" : "success",
      );

      if (appliedFilters && result.successCount > 0) {
        await loadDetails(appliedFilters);
      }
    } catch (e: unknown) {
      console.error("handleBatchSubmitAll (all): Error:", e);
      let errorMessage = t("Failed to batch save approver stock take records");
      if (e instanceof Error && e.message) {
        errorMessage = e.message;
      }
      onSnackbar(errorMessage, "error");
    } finally {
      setBatchSaving(false);
      batchSaveInFlightRef.current = false;
    }
  }, [
    mode,
    selectedSession,
    currentUserId,
    sortedDetails,
    qtySelection,
    approverQty,
    approverBadQty,
    t,
    onSnackbar,
    loadDetails,
    appliedFilters,
  ]);

  const formatNumber = (num: number | null | undefined): string => {
    if (num == null) return "0";
    return num.toLocaleString("en-US", {
      minimumFractionDigits: 0,
      maximumFractionDigits: 0,
    });
  };

  const uniqueWarehouses = useMemo(
    () =>
      Array.from(
        new Set(
          inventoryLotDetails
            .map((detail) => detail.warehouse)
            .filter((warehouse) => warehouse && warehouse.trim() !== "")
        )
      ).join(", "),
    [inventoryLotDetails]
  );

  const formatRecordEndTime = (detail: InventoryLotDetailResponse) => {
    const ms = parseDateTimeMs(detail.approverTime ?? detail.stockTakeEndTime);
    if (!ms) return "-";
    return dayjs(ms).format("YYYY-MM-DD HH:mm");
  };
  const rows = sortedDetails;

  const columns = useMemo<GridColDef<InventoryLotDetailResponse>[]>(() => {
    const cols: GridColDef<InventoryLotDetailResponse>[] = [];
  
    if (mode === "approved") {
      cols.push({
        field: "approverTime",
        headerName: t("Approver Time"),
        minWidth: 150,
        flex: 0.6,
        sortable: false,
        renderCell: (params) => (
          <Typography variant="caption" color="text.secondary">
            {formatRecordEndTime(params.row)}
          </Typography>
        ),
      });
    }
  
    cols.push(
      {
        field: "warehouseLocation",
        headerName: t("Warehouse Location"),
        minWidth: 220,
        flex: 1,
        sortable: false,
        renderCell: (params) => (
          <Stack spacing={0.5}>
            <Typography variant="body2">
              <strong>
                {params.row.stockTakeSection || "-"}{" "}
                {params.row.stockTakeSectionDescription || "-"}
              </strong>
            </Typography>
            <Typography variant="body2">{params.row.warehouseCode || "-"}</Typography>
          </Stack>
        ),
      },
      {
        field: "itemLot",
        headerName: t("Item-lotNo-ExpiryDate"),
        minWidth: 160,
        flex: 1,
        sortable: false,
        renderCell: (params) => (
          <Stack spacing={0.5} sx={{ lineHeight: 1.5 }}>
            <Box>
              {params.row.itemCode || "-"} {params.row.itemName || "-"}
            </Box>
            <Box>{params.row.lotNo || "-"}</Box>
            <Box>
              {params.row.expiryDate
                ? dayjs(params.row.expiryDate).format(OUTPUT_DATE_FORMAT)
                : "-"}
            </Box>
          </Stack>
        ),
      },
      {
        field: "uom",
        headerName: t("UOM"),
        minWidth: 90,
        flex: 0.4,
        sortable: false,
        valueGetter: (params) => params.row.uom || "-",
      },
      {
        field: "qtyBlock",
        headerName: t("Stock Take Qty Data and Variance Analysis"),
        minWidth: 480,
        flex: 3.2,
        sortable: false,
        renderCell: (params: GridRenderCellParams<InventoryLotDetailResponse>) => {
          const detail = params.row;
  
          const hasFirst =
            detail.firstStockTakeQty != null && detail.firstStockTakeQty >= 0;
          const hasSecond =
            detail.secondStockTakeQty != null && detail.secondStockTakeQty >= 0;
  
          const selection =
            qtySelection[detail.id] || (hasSecond ? "second" : "first");
  
          const canApprover =
            mode === "pending"
              ? true
              : selection === "approver" &&
                (detail.approverQty != null || detail.approverBadQty != null);
  
          const showRadioBlock = mode === "approved" || detail.finalQty == null;
          const bookQty = detail.bookQty ?? detail.availableQty ?? 0;
          const selectedQty =
            selection === "first"
              ? (detail.firstStockTakeQty ?? 0)
              : selection === "second"
                ? (detail.secondStockTakeQty ?? 0)
                : (parseFloat(approverQty[detail.id] || "0") - parseFloat(approverBadQty[detail.id] || "0")) || 0;
          const difference = selectedQty - bookQty;
          const approverQtyNum = parseFloat(approverQty[detail.id] || "0") || 0;
          const approverBadQtyNum = parseFloat(approverBadQty[detail.id] || "0") || 0;
          const approverGoodQty = approverQtyNum - approverBadQtyNum;
          const variancePercentageRaw =
            bookQty !== 0
              ? (difference / bookQty) * 100
              : difference !== 0
                ? difference > 0
                  ? 100
                  : -100
                : 0;
          const variancePercentage = roundDownPercent(variancePercentageRaw);
          const hasVariance = difference !== 0;
          const pctLabel = `${variancePercentage}%`;

          const summaryLine = (label: string, value: string, valueColor?: string) => (
            <Stack
              key={label}
              direction="row"
              justifyContent="space-between"
              alignItems="center"
              spacing={1}
            >
              <Typography variant="body2" color="text.secondary" noWrap>
                {label}
              </Typography>
              <Typography
                variant="body2"
                fontWeight={700}
                sx={{ color: valueColor ?? "text.primary", whiteSpace: "nowrap" }}
              >
                {value}
              </Typography>
            </Stack>
          );

          return (
            <Box sx={{ width: "100%" }}>
              {!showRadioBlock ? (
                <Typography variant="body2" color="text.secondary">
                  -
                </Typography>
              ) : (
                <Stack
                  direction="row"
                  spacing={1}
                  alignItems="stretch"
                  sx={{ width: "100%", py: 0.5 }}
                >
                  <Stack spacing={1} sx={{  minWidth: 0, justifyContent: "center" }}>
                    {hasFirst && (
                      <Stack direction="row" spacing={0.5} alignItems="center">
                        <Radio
                          size="small"
                          checked={selection === "first"}
                          disabled={mode === "approved"}
                          onChange={() =>
                            setQtySelection({
                              ...qtySelection,
                              [detail.id]: "first",
                            })
                          }
                        />
                        <Typography variant="body2" component="span">
                          {t("First")}:{" "}
                          {formatNumber(
                            (detail.firstStockTakeQty ?? 0) + (detail.firstBadQty ?? 0)
                          )}{" "}
                          {/*
                          = {formatNumber(detail.firstStockTakeQty ?? 0)}
                          */}
                        </Typography>
                      </Stack>
                    )}

                    {hasSecond && (
                      <Stack direction="row" spacing={0.5} alignItems="center">
                        <Radio
                          size="small"
                          checked={selection === "second"}
                          disabled={mode === "approved"}
                          onChange={() =>
                            setQtySelection({
                              ...qtySelection,
                              [detail.id]: "second",
                            })
                          }
                        />
                        <Typography variant="body2" component="span">
                          {t("Second")}:{" "}
                          {formatNumber(
                            (detail.secondStockTakeQty ?? 0) + (detail.secondBadQty ?? 0)
                          )}{" "}
                          {/*
                          = {formatNumber(detail.secondStockTakeQty ?? 0)}
                          */}
                        </Typography>
                       
                      </Stack>
                    )}

                    {canApprover && (
                      <Stack direction="row" spacing={0.5} alignItems="center" flexWrap="wrap">
                        <Radio
                          size="small"
                          checked={selection === "approver"}
                          disabled={mode === "approved"}
                          onChange={() =>
                            setQtySelection({
                              ...qtySelection,
                              [detail.id]: "approver",
                            })
                          }
                        />
                        <Typography variant="body2" component="span" sx={{ mr: 0.5 }}>
                          {t("Approver Input")}:
                        </Typography>
                        <TextField
                          size="small"
                          type="number"
                          value={approverQty[detail.id] || ""}
                          onKeyDown={blockNonIntegerKeys}
                          onChange={(e) => {
                            const clean = sanitizeIntegerInput(e.target.value);
                            setApproverQty({
                              ...approverQty,
                              [detail.id]: clean,
                            });
                          }}
                          sx={{
                            width: 72,
                            minWidth: 72,
                            "& .MuiInputBase-input": {
                              py: 0.5,
                              px: 1,
                            },
                          }}
                        //  placeholder={t("Stock Take Qty")}
                          disabled={mode === "approved" || selection !== "approver"}
                          inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
                        />
                        {/*
                        <Typography variant="body2" component="span" sx={{ ml: 0.5 }}>
                          = {formatNumber(approverGoodQty)}
                        </Typography>
                        */}
                      </Stack>
                    )}
                  </Stack>

                  <Box
                    sx={{
                      flexShrink: 0,
                      minWidth: 168,
                      maxWidth: 200,
                      bgcolor: "grey.50",
                      borderRadius: 1,
                      border: "1px solid",
                      borderColor: "divider",
                      p: 1.25,
                    }}
                  >
                    <Stack spacing={0.75}>
                      {summaryLine(
                        `${t("Selected Qty")}:`,
                        formatNumber(selectedQty)
                      )}
                      {summaryLine(`${t("Book Qty")}:`, formatNumber(bookQty))}
                      {summaryLine(
                        `${t("Inventory Difference")}:`,
                        formatNumber(difference),
                        hasVariance ? "error.main" : "text.primary"
                      )}
                      <Box
                        sx={{
                          mt: 0.25,
                          py: 0.5,
                          px: 1,
                          borderRadius: 1,
                          textAlign: "center",
                          bgcolor: hasVariance ? "error.light" : "grey.200",
                        }}
                      >
                        <Typography
                          variant="caption"
                          fontWeight={600}
                          sx={{ color: hasVariance ? "error.dark" : "text.secondary" }}
                        >
                          {t("variance Percentage")}: {pctLabel}
                        </Typography>
                      </Box>
                    </Stack>
                  </Box>
                </Stack>
              )}
            </Box>
          );
        },
      }
    );
  {/*
    if (mode === "approved") {
      cols.push({
        field: "varianceQty",
        headerName: t("Variance"),
        minWidth: 110,
        flex: 0.5,
        sortable: false,
        valueGetter: (params) => String(params.row.varianceQty ?? 0),
      });
    }
    */}
    cols.push(
      /*
      {
        field: "remarks",
        headerName: t("Remark"),
        minWidth: 120,
        flex: 0.8,
        sortable: false,
        renderCell: (params) => (
          <Typography variant="body2" sx={{ whiteSpace: "normal", wordBreak: "break-word" }}>
            {params.row.remarks || "-"}
          </Typography>
        ),
      },
      */
      {
        field: "stockTakeRecordStatus",
        headerName: t("Record Status"),
        minWidth: 130,
        flex: 0.6,
        sortable: false,
        renderCell: (params) => {
          const raw = params.row.stockTakeRecordStatus;
          const status = String(raw ?? "").trim().toLowerCase();
        
          const colorMap: Record<string, "success" | "warning" | "info" | "default" | "error"> = {
            completed: "success",
            notmatch: "warning",
            pending: "info",
            "not_match": "warning",
          };
        
          return (
            <Chip
              size="small"
              label={t(`${status}`) || "-"}
              color={colorMap[status] ?? "default"}
              variant="outlined"
            />
          );
        }
      },
      {
        field: "stockTakerName",
        headerName: t("Picker"),
        minWidth: 140,
        flex: 0.7,
        sortable: false,
        valueGetter: (params) => params.row.stockTakerName || "-",
      },
      {
        field: "actions",
        headerName: t("Action"),
        minWidth: 110,
        flex: 0.9,
        sortable: false,
        renderCell: (params) => {
          const detail = params.row;
          const hasSecond = detail.secondStockTakeQty != null && detail.secondStockTakeQty >= 0;
          const selection =
            qtySelection[detail.id] || (hasSecond ? "second" : "first");
  
          return (
            <Stack direction="column" spacing={1} sx={{ width: "100%" }}>
              {mode === "pending" && (
                <>
                <Box>
                  <Button
                    size="small"
                    variant="contained"
                    onClick={() => handleSaveApproverStockTake(detail)}
                    disabled={saving}
                  >
                    {t("Save")}
                  </Button>
                  </Box>
                  <Box>
                  <Button
                    size="small"
                    variant="outlined"
                    color="warning"
                    onClick={() => handleUpdateStatusToNotMatch(detail)}
                    disabled={updatingStatus||hasSecond}
                  >
                    {t("Not Match")}
                  </Button>
                  </Box>
                </>
              )}
  
              {mode === "approved" && (
                <Typography variant="caption" color="text.secondary">
                  {selection === "first"
                    ? t("First")
                    : selection === "second"
                      ? t("Second")
                      : t("Approver Input")}
                </Typography>
              )}
            </Stack>
          );
        },
      }
    );
  
    return cols;
  }, [
    mode,
    t,
    qtySelection,
    approverQty,
    approverBadQty,
    saving,
    updatingStatus,
    blockNonIntegerKeys,
    sanitizeIntegerInput,
    handleSaveApproverStockTake,
    handleUpdateStatusToNotMatch,
    formatRecordEndTime,
  ]);
  const effectivePageSize =
  pageSize === "all" ? Math.max(total || 0, 0) : (pageSize as number);
  useEffect(() => {
    setStockTakeSectionOptions((prev) => {
      const sectionSet = new Set<string>(prev);
      inventoryLotDetails.forEach((item) => {
        const section = item.stockTakeSection?.trim();
        if (section) sectionSet.add(section);
      });
      return Array.from(sectionSet).sort((a, b) => a.localeCompare(b));
    });
    setStoreIdOptions((prev) => {
      const storeSet = new Set<string>([...prev, "2F", "4F"]);
      inventoryLotDetails.forEach((item) => {
        const storeId = item.storeId?.trim();
        if (storeId) storeSet.add(storeId);
      });
      return Array.from(storeSet).sort((a, b) => a.localeCompare(b));
    });
  }, [inventoryLotDetails]);

  return (
    <Box>
      {onBack && (
        <Button
          onClick={onBack}
          sx={{ mb: 2, border: "1px solid", borderColor: "primary.main" }}
        >
          {t("Back to List")}
        </Button>
      )}
      <Stack
        direction="row"
        justifyContent="space-between"
        alignItems="center"
        sx={{ mb: 2 }}
      >
        <Typography variant="h6" sx={{ mb: 2 }}>
         
          {uniqueWarehouses && (
            <> {t("Warehouse")}: {uniqueWarehouses}</>
          )}
        </Typography>

        <Stack direction="row" spacing={2} alignItems="center">
          {mode === "pending" && (
            <Button
              variant="contained"
              color="primary"
              onClick={handleOpenBatchSaveConfirm}
              disabled={batchSaving}
            >
              {t("Batch Save All")}
            </Button>
          )}
        </Stack>
      </Stack>
      <Accordion
  expanded={showFilters}
  onChange={(_, expanded) => setShowFilters(expanded)}
  elevation={0}
  sx={{ mb: 2, border: "1px solid", borderColor: "divider", borderRadius: 1 }}
>
  <AccordionSummary expandIcon={<ExpandMoreIcon />}>
    <Typography variant="body2">
      {(<strong>{t("Search Criteria")}</strong>)}
    </Typography>
  </AccordionSummary>

  <AccordionDetails>
    <Box sx={{ width: "100%" }}>
      <Card elevation={0}>
        <CardContent>
          <Grid container spacing={2}>
            <Grid item xs={12} md={4}>
              <FormControl fullWidth>
                <InputLabel>{t("Stock Take Section")}</InputLabel>
                <Select
                  value={searchSectionDescription}
                  label={t("Stock Take Section")}
                  onChange={(e) => setSearchSectionDescription(e.target.value)}
                >
                  <MenuItem value="All">{t("All")}</MenuItem>
                  {sectionDescriptionOptions.map((desc) => (
                    <MenuItem key={desc} value={desc}>
                      {desc}
                    </MenuItem>
                  ))}
                </Select>
              </FormControl>
            </Grid>
            <Grid item xs={12} md={4}>
              <Autocomplete
                freeSolo
                options={stockTakeSectionOptions}
                value={searchStockTakeSession}
                onInputChange={(_, newValue) => setSearchStockTakeSession(newValue)}
                renderInput={(params) => (
                  <TextField
                    {...params}
                    fullWidth
                    label={t("Stock Take Section (can use , to search multiple sections)")}
                  />
                )}
              />
            </Grid>
            <Grid item xs={12} md={4}>
              <TextField
                fullWidth
                label={t("Item")}
                value={searchItemKeyword}
                onChange={(e) => setSearchItemKeyword(e.target.value)}
              />
            </Grid>
            <Grid item xs={12} md={4}>
              <TextField
                fullWidth
                label={t("Warehouse")}
                value={searchWarehouseKeyword}
                onChange={(e) => setSearchWarehouseKeyword(e.target.value)}
              />
            </Grid>
            <Grid item xs={12} md={4}>
              <FormControl fullWidth>
                <InputLabel>{t("Store ID")}</InputLabel>
                <Select
                  value={searchStoreId}
                  label={t("Store ID")}
                  onChange={(e) => setSearchStoreId(e.target.value)}
                >
                  <MenuItem value="All">{t("All")}</MenuItem>
                  {storeIdOptions.map((storeId) => (
                    <MenuItem key={storeId} value={storeId}>
                      {storeId}
                    </MenuItem>
                  ))}
                </Select>
              </FormControl>
            </Grid>
            {mode === "pending" && (
              <Grid item xs={12} md={4}>
                <FormControl fullWidth>
                  <InputLabel>{t("Record Status")}</InputLabel>
                  <Select
                    value={searchStatus}
                    label={t("Record Status")}
                    onChange={(e) => setSearchStatus(e.target.value)}
                  >
                    <MenuItem value="pending">{t("Pending")}</MenuItem>
                    <MenuItem value="notMatch">{t("Not Match")}</MenuItem>
                    <MenuItem value="pass">{t("Pass")}</MenuItem>
                  </Select>
                </FormControl>
              </Grid>
            )}
            <Grid item xs={12} md={4}>
              <Stack spacing={0.5}>
                <TextField
                  fullWidth
                  size="small"
                  type="number"
                  label={t("Variance %")}
                  value={searchVariancePercentTolerance}
                  onChange={(e) =>
                    setSearchVariancePercentTolerance(sanitizePositiveDecimalInput(e.target.value))
                  }
                  inputProps={{ min: 0, step: 0.1 }}
                />
                <FormControlLabel
                  sx={{ ml: 0, mr: 0 }}
                  control={
                    <Checkbox
                      size="small"
                      checked={searchVarianceFilterInclusive}
                      onChange={(e) => setSearchVarianceFilterInclusive(e.target.checked)}
                    />
                  }
                  label={
                    <Typography variant="body2">{t("Variance filter inclusive only")}</Typography>
                  }
                />
                <Typography variant="caption" color="text.secondary" sx={{ pl: 0.5 }}>
                  {searchVarianceFilterInclusive
                    ? t("Variance filter inclusive range hint", {
                        value: searchVariancePercentTolerance || "0",
                        op: searchVarianceFilterStrict ? "<" : "≤",
                      })
                    : t("Variance filter exclusive range hint", {
                        value: searchVariancePercentTolerance || "0",
                        op: searchVarianceFilterStrict ? ">" : "≥",
                      })}
                </Typography>
              </Stack>
            </Grid>
          </Grid>
          <CardActions sx={{ px: 0, pt: 2, gap: 1 }}>
            <Button variant="outlined" onClick={handleResetSearch}>
              {t("Reset")}
            </Button>
            <Button variant="contained" onClick={handleSearch}>
              {t("Search")}
            </Button>
          </CardActions>
        </CardContent>
      </Card>
    </Box>
  </AccordionDetails>
</Accordion>
      <Typography variant="body2" color="text.secondary">
        {t("Total")}: {total} | {t("Shown")}: {sortedDetails.length}
      </Typography>
    {loadingDetails ? (
      <Box sx={{ display: "flex", justifyContent: "center", p: 3 }}>
        <CircularProgress />
      </Box>
    ) : (
      <Box sx={{ width: "100%", height: 700 }}>
          <StyledDataGrid
            rows={sortedDetails}
            columns={columns}
            getRowId={(row) => row.id}
            loading={loadingDetails}
            disableRowSelectionOnClick
            paginationMode="client"             // ← important: client-side
            pageSizeOptions={[50, 100, 200, 500]}
            getRowHeight={() => "auto"}
            sx={{
              backgroundColor: "transparent",
              "& .MuiDataGrid-columnHeaders": { backgroundColor: "#fff" },
              "& .MuiDataGrid-cell": { py: 1, alignItems: "flex-start" },
              "& .MuiDataGrid-row": { minHeight: 96 },
            }}
          />
        </Box>
    )}

      <Dialog
        open={openBatchSaveConfirmDialog}
        onClose={() => {
          if (!batchSaving) setOpenBatchSaveConfirmDialog(false);
        }}
        maxWidth="sm"
        fullWidth
      >
        <DialogTitle>{t("Confirm batch save approver")}</DialogTitle>
        <DialogContent dividers>
          <Typography variant="body2" sx={{ mb: 2 }}>
            {t("Batch save confirm message", { count: batchApproverSaveRecords.length })}
          </Typography>
          {batchSaveSectionLabels.length > 0 ? (
            <Box>
              <Typography variant="caption" color="text.secondary" display="block" sx={{ mb: 1 }}>
                {t("Stock take sections in current list", { count: batchSaveSectionLabels.length })}
              </Typography>
              <Box
                sx={{
                  maxHeight: 240,
                  overflowY: "auto",
                  border: 1,
                  borderColor: "divider",
                  borderRadius: 1,
                  p: 1.5,
                }}
              >
                <Stack spacing={0.5}>
                  {batchSaveSectionLabels.map((section) => (
                    <Typography key={section} variant="body2">
                      {section}
                    </Typography>
                  ))}
                </Stack>
              </Box>
            </Box>
          ) : null}
        </DialogContent>
        <DialogActions sx={{ px: 3, py: 2 }}>
          <Button onClick={() => setOpenBatchSaveConfirmDialog(false)} disabled={batchSaving}>
            {t("Cancel")}
          </Button>
          <Button
            variant="contained"
            color="primary"
            onClick={handleBatchSubmitAll}
            disabled={batchSaving}
          >
            {batchSaving ? <CircularProgress size={20} /> : t("Confirm")}
          </Button>
        </DialogActions>
      </Dialog>
  </Box>
);
};

export default ApproverStockTakeAll;

