"use client";

import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import {
  Box,
  Button,
  Card,
  CardContent,
  Chip,
  CircularProgress,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Paper,
  Stack,
  Tab,
  Tabs,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TablePagination,
  TableRow,
  Typography,
  Avatar,
  Tooltip,
} from "@mui/material";
import { useTranslation } from "react-i18next";
import { useSession } from "next-auth/react";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import dayjs, { Dayjs } from "dayjs";
import { SessionWithTokens } from "@/config/authConfig";
import { AUTH, hasAbility } from "@/authorities";
import { OUTPUT_DATE_FORMAT } from "@/app/utils/formatUtil";
import {
  AllJoborderProductProcessInfoResponse,
  completeProductProcessLine,
  fetchJoborderProductProcessesPage,
  fetchJos,
  fetchProductProcessesByJobOrderId,
  setJobOrderHidden,
} from "@/app/api/jo/actions";
import { JobOrder } from "@/app/api/jo";
import QcStockInModal from "@/components/Qc/QcStockInModal";
import { StockInLineInput } from "@/app/api/stockIn";
import type { PrinterCombo } from "@/app/api/settings/printer";

type PrimaryTab =
  | "needs_action"
  | "pending"
  | "processing"
  | "carried_over"
  | "pending_qc"
  | "putawayed"
  | "issue";
/** Shared small tabs for 需處理 / 待生產 / 生產中. */
type ProductionSubTab = "all" | "not_picked" | "picked";
type IssueSubTab = "stop" | "cancel";

const NOT_PICKED_BUCKETS = new Set([
  "not_picked_not_started",
  "not_picked_started",
]);
const PICKED_BUCKETS = new Set(["picked_not_started", "picked_started"]);
const PENDING_BUCKETS = new Set([
  "not_picked_not_started",
  "picked_not_started",
]);
const PROCESSING_BUCKETS = new Set(["picked_started", "not_picked_started"]);

type OpsRow = {
  key: string;
  jobOrderId: number;
  jobOrderCode: string;
  itemCode: string;
  itemName: string;
  requiredQty: number;
  uom: string;
  productionDate: string;
  statusLabel: string;
  pickProcessBucket?: string | null;
  isPaused: boolean;
  isCancelled: boolean;
  /** pending_qc | putawayed | production | cancelled */
  rowKind: "production" | "pending_qc" | "putawayed" | "cancelled";
  stockInLineId?: number | null;
  /** Present for production rows; used by complete-JO. */
  sourceProcess?: AllJoborderProductProcessInfoResponse;
};

/** Same as ProductionProcessList: unfinished from (searchDate - 4) .. searchDate. */
const PRODUCTION_LOOKBACK_DAYS = 4;
/** Cards / page size for ops table fetch. */
const FETCH_SIZE = 200;

function isCarriedOver(row: OpsRow, searchDay: Dayjs): boolean {
  if (!row.productionDate || !dayjs(row.productionDate).isValid()) return false;
  return dayjs(row.productionDate).startOf("day").isBefore(searchDay);
}

function tabLabel(text: string, count: number): string {
  return count > 0 ? `${text} (${count})` : text;
}

function isPausedProcess(p: AllJoborderProductProcessInfoResponse): boolean {
  return (p.lines ?? []).some(
    (l) => String(l.status ?? "").trim().toLowerCase() === "paused",
  );
}

function toProductionRow(
  p: AllJoborderProductProcessInfoResponse,
  rowKind: OpsRow["rowKind"] = "production",
): OpsRow | null {
  if (!p.jobOrderId) return null;
  return {
    key: `pp-${rowKind}-${p.jobOrderId}-${p.id}`,
    jobOrderId: p.jobOrderId,
    jobOrderCode: p.jobOrderCode || "-",
    itemCode: p.itemCode || "-",
    itemName: p.itemName || "-",
    requiredQty: p.requiredQty ?? 0,
    uom: p.uom || "",
    productionDate: p.date || "",
    statusLabel:
      rowKind === "pending_qc"
        ? "pending_qc"
        : rowKind === "putawayed"
          ? "putawayed"
          : p.pickProcessBucket || p.status || "-",
    pickProcessBucket: p.pickProcessBucket,
    isPaused: isPausedProcess(p),
    isCancelled: false,
    rowKind,
    stockInLineId: p.stockInLineId ?? null,
    sourceProcess: p,
  };
}

function toCancelledRow(jo: JobOrder): OpsRow {
  const planStart = Array.isArray(jo.planStart)
    ? dayjs(
        new Date(
          jo.planStart[0],
          (jo.planStart[1] ?? 1) - 1,
          jo.planStart[2] ?? 1,
        ),
      ).format("YYYY-MM-DD")
    : jo.planStart
      ? dayjs(jo.planStart as unknown as string).format("YYYY-MM-DD")
      : "";
  return {
    key: `jo-${jo.id}`,
    jobOrderId: jo.id,
    jobOrderCode: jo.code || "-",
    itemCode: jo.item?.code || "-",
    itemName: jo.itemName || jo.item?.name || "-",
    requiredQty: jo.reqQty ?? 0,
    uom: "",
    productionDate: planStart,
    statusLabel: "cancelled",
    pickProcessBucket: null,
    isPaused: false,
    isCancelled: true,
    rowKind: "cancelled",
    stockInLineId: null,
  };
}

/** Deduplicate by jobOrderId (prefer paused / higher priority). */
function dedupeByJobOrder(rows: OpsRow[]): OpsRow[] {
  const map = new Map<number, OpsRow>();
  for (const row of rows) {
    const existing = map.get(row.jobOrderId);
    if (!existing) {
      map.set(row.jobOrderId, row);
      continue;
    }
    if (!existing.isPaused && row.isPaused) {
      map.set(row.jobOrderId, row);
    }
  }
  return Array.from(map.values());
}

/** Prefer pending_qc over production when same JO appears in off-plan merge. */
function dedupeOffPlanRows(rows: OpsRow[]): OpsRow[] {
  const map = new Map<number, OpsRow>();
  for (const row of rows) {
    const existing = map.get(row.jobOrderId);
    if (!existing) {
      map.set(row.jobOrderId, row);
      continue;
    }
    if (existing.rowKind !== "pending_qc" && row.rowKind === "pending_qc") {
      map.set(row.jobOrderId, row);
      continue;
    }
    if (!existing.isPaused && row.isPaused) {
      map.set(row.jobOrderId, row);
    }
  }
  return Array.from(map.values());
}

function isRowPutawayCompleted(row: OpsRow): boolean {
  return (
    String(row.sourceProcess?.stockInLineStatus ?? "")
      .trim()
      .toLowerCase() === "completed"
  );
}

interface JobOrderOpsTableProps {
  onSelectProcess?: (jobOrderId: number) => void;
  printerCombo?: PrinterCombo[];
}

/** FP-MTMS Version Checklist | Functions Ref. No. 47 | v1.0.2 | 2026-08-05 */
const JobOrderOpsTable: React.FC<JobOrderOpsTableProps> = ({
  onSelectProcess,
  printerCombo = [],
}) => {
  const { t } = useTranslation(["productionProcess", "common"]);
  const { data: session } = useSession() as { data: SessionWithTokens | null };
  const sessionToken = session as SessionWithTokens | null;
  const abilities = session?.abilities ?? session?.user?.abilities ?? [];
  /** 取消工單：僅 ADMIN */
  const canCancel = hasAbility(abilities, AUTH.ADMIN);
  /** 完成工單：僅 PRODUCT_PROCESS（工單 生產流程 完成工單） */
  const canComplete = hasAbility(abilities, AUTH.PRODUCT_PROCESS);

  const [queryDate, setQueryDate] = useState<Dayjs>(() => dayjs());
  const [primaryTab, setPrimaryTab] = useState<PrimaryTab>("needs_action");
  const [productionSub, setProductionSub] = useState<ProductionSubTab>("all");
  const [issueSub, setIssueSub] = useState<IssueSubTab>("stop");

  const searchDay = useMemo(() => queryDate.startOf("day"), [queryDate]);

  const [productionRows, setProductionRows] = useState<OpsRow[]>([]);
  const [pendingQcRows, setPendingQcRows] = useState<OpsRow[]>([]);
  const [putawayedRows, setPutawayedRows] = useState<OpsRow[]>([]);
  const [cancelledRows, setCancelledRows] = useState<OpsRow[]>([]);
  const [loading, setLoading] = useState(false);
  const [page, setPage] = useState(0);
  const [pageSize, setPageSize] = useState(10);

  const [confirmOpen, setConfirmOpen] = useState(false);
  const [confirmMessage, setConfirmMessage] = useState("");
  const [confirmLoading, setConfirmLoading] = useState(false);
  const [pendingAction, setPendingAction] = useState<null | (() => Promise<void>)>(null);
  const actionInFlightRef = useRef(false);
  const [rowBusyIds, setRowBusyIds] = useState<Set<number>>(new Set());
  const [qcModalOpen, setQcModalOpen] = useState(false);
  const [qcModalInfo, setQcModalInfo] = useState<StockInLineInput | undefined>();

  const loadProduction = useCallback(async () => {
    const dayStr = queryDate.format("YYYY-MM-DD");
    const data = await fetchJoborderProductProcessesPage({
      date: dayStr,
      lookbackDays: PRODUCTION_LOOKBACK_DAYS,
      bucket: "all",
      qcReady: false,
      page: 0,
      size: FETCH_SIZE,
    });
    const rows = (data?.content ?? [])
      .map((p) => toProductionRow(p, "production"))
      .filter((r): r is OpsRow => r != null);
    setProductionRows(dedupeByJobOrder(rows));
  }, [queryDate]);

  const loadPendingQc = useCallback(async () => {
    const dayStr = queryDate.format("YYYY-MM-DD");
    try {
      const data = await fetchJoborderProductProcessesPage({
        date: dayStr,
        lookbackDays: PRODUCTION_LOOKBACK_DAYS,
        qcReady: true,
        includePutaway: true,
        putawayStatus: "notCompleted",
        page: 0,
        size: FETCH_SIZE,
      });
      const rows = (data?.content ?? [])
        .map((p) => toProductionRow(p, "pending_qc"))
        .filter((r): r is OpsRow => r != null);
      setPendingQcRows(dedupeByJobOrder(rows));
    } catch (e) {
      console.error("loadPendingQc failed", e);
      setPendingQcRows([]);
    }
  }, [queryDate]);

  const loadPutawayed = useCallback(async () => {
    const dayStr = queryDate.format("YYYY-MM-DD");
    try {
      const data = await fetchJoborderProductProcessesPage({
        date: dayStr,
        qcReady: true,
        includePutaway: true,
        putawayStatus: "completed",
        page: 0,
        size: FETCH_SIZE,
      });
      const rows = (data?.content ?? [])
        .map((p) => toProductionRow(p, "putawayed"))
        .filter((r): r is OpsRow => r != null);
      setPutawayedRows(dedupeByJobOrder(rows));
    } catch (e) {
      console.error("loadPutawayed failed", e);
      setPutawayedRows([]);
    }
  }, [queryDate]);

  const loadCancelled = useCallback(async () => {
    const dayStr = queryDate.format("YYYY-MM-DD");
    try {
      const res = await fetchJos({
        code: "",
        planStart: dayStr,
        planStartTo: dayStr,
        joSearchStatus: "cancel",
        pageNum: 0,
        pageSize: FETCH_SIZE,
      });
      setCancelledRows((res?.records ?? []).map(toCancelledRow));
    } catch (e) {
      console.error("loadCancelled failed", e);
      setCancelledRows([]);
    }
  }, [queryDate]);

  const loadData = useCallback(async () => {
    setLoading(true);
    const results = await Promise.allSettled([
      loadProduction(),
      loadPendingQc(),
      loadPutawayed(),
      loadCancelled(),
    ]);
    if (results[0].status === "rejected") {
      console.error(results[0].reason);
      setProductionRows([]);
    }
    setLoading(false);
  }, [loadProduction, loadPendingQc, loadPutawayed, loadCancelled]);

  useEffect(() => {
    void loadData();
  }, [loadData]);

  useEffect(() => {
    setPage(0);
  }, [primaryTab, productionSub, issueSub, queryDate]);

  useEffect(() => {
    setProductionSub("all");
  }, [primaryTab]);

  const offPlanRows = useMemo(() => {
    const fromProd = productionRows.filter(
      (r) => isCarriedOver(r, searchDay) && !isRowPutawayCompleted(r),
    );
    const fromQc = pendingQcRows.filter(
      (r) => isCarriedOver(r, searchDay) && !isRowPutawayCompleted(r),
    );
    return dedupeOffPlanRows([...fromProd, ...fromQc]);
  }, [productionRows, pendingQcRows, searchDay]);

  const applyProductionSub = useCallback((list: OpsRow[], sub: ProductionSubTab) => {
    if (sub === "not_picked") {
      return list.filter((r) => NOT_PICKED_BUCKETS.has(String(r.pickProcessBucket ?? "")));
    }
    if (sub === "picked") {
      return list.filter((r) => PICKED_BUCKETS.has(String(r.pickProcessBucket ?? "")));
    }
    return list;
  }, []);

  const filteredRows = useMemo(() => {
    if (primaryTab === "putawayed") return putawayedRows;
    if (primaryTab === "pending_qc") return pendingQcRows;
    if (primaryTab === "carried_over") return offPlanRows;
    if (primaryTab === "issue" && issueSub === "cancel") return cancelledRows;

    let list = productionRows;
    if (primaryTab === "pending") {
      list = list.filter((r) => PENDING_BUCKETS.has(String(r.pickProcessBucket ?? "")));
    } else if (primaryTab === "processing") {
      list = list.filter((r) => PROCESSING_BUCKETS.has(String(r.pickProcessBucket ?? "")));
    } else if (primaryTab === "issue" && issueSub === "stop") {
      return list.filter((r) => r.isPaused);
    }

    if (
      primaryTab === "needs_action" ||
      primaryTab === "pending" ||
      primaryTab === "processing"
    ) {
      list = applyProductionSub(list, productionSub);
    }
    return list;
  }, [
    primaryTab,
    productionSub,
    issueSub,
    productionRows,
    pendingQcRows,
    putawayedRows,
    cancelledRows,
    offPlanRows,
    applyProductionSub,
  ]);

  const counts = useMemo(() => {
    const pendingRows = productionRows.filter((r) =>
      PENDING_BUCKETS.has(String(r.pickProcessBucket ?? "")),
    );
    const processingRows = productionRows.filter((r) =>
      PROCESSING_BUCKETS.has(String(r.pickProcessBucket ?? "")),
    );
    const stop = productionRows.filter((r) => r.isPaused).length;

    const scopeForSub =
      primaryTab === "pending"
        ? pendingRows
        : primaryTab === "processing"
          ? processingRows
          : productionRows;

    return {
      needsAction: productionRows.length,
      pending: pendingRows.length,
      processing: processingRows.length,
      carriedOver: offPlanRows.length,
      pendingQc: pendingQcRows.length,
      putawayed: putawayedRows.length,
      stop,
      cancel: cancelledRows.length,
      subAll: scopeForSub.length,
      subNotPicked: scopeForSub.filter((r) =>
        NOT_PICKED_BUCKETS.has(String(r.pickProcessBucket ?? "")),
      ).length,
      subPicked: scopeForSub.filter((r) =>
        PICKED_BUCKETS.has(String(r.pickProcessBucket ?? "")),
      ).length,
    };
  }, [
    productionRows,
    pendingQcRows,
    putawayedRows,
    cancelledRows,
    offPlanRows,
    primaryTab,
  ]);

  const paginatedRows = useMemo(() => {
    const start = page * pageSize;
    return filteredRows.slice(start, start + pageSize);
  }, [filteredRows, page, pageSize]);

  const openConfirm = useCallback((message: string, action: () => Promise<void>) => {
    setConfirmMessage(message);
    setPendingAction(() => action);
    setConfirmOpen(true);
  }, []);

  const closeConfirm = useCallback(() => {
    if (confirmLoading) return;
    setConfirmOpen(false);
    setPendingAction(null);
    setConfirmMessage("");
  }, [confirmLoading]);

  const markBusy = (id: number, busy: boolean) => {
    setRowBusyIds((prev) => {
      const next = new Set(prev);
      if (busy) next.add(id);
      else next.delete(id);
      return next;
    });
  };

  const handleOpenQcModal = useCallback(
    (row: OpsRow) => {
      if (!row.stockInLineId) {
        alert(t("Invalid Stock In Line Id"));
        return;
      }
      setQcModalInfo({ id: row.stockInLineId });
      setQcModalOpen(true);
    },
    [t],
  );

  const handleComplete = useCallback(
    (row: OpsRow) => {
      if (!canComplete || row.isCancelled) return;
      openConfirm(t("Confirm to update this Job Order?"), async () => {
        if (actionInFlightRef.current) return;
        actionInFlightRef.current = true;
        markBusy(row.jobOrderId, true);
        try {
          const processes = await fetchProductProcessesByJobOrderId(row.jobOrderId);
          const lineIds = (processes ?? [])
            .flatMap((p) => (p as { productProcessLines?: { id?: number }[] }).productProcessLines ?? [])
            .map((l) => l.id)
            .filter((id): id is number => !!id);
          for (const lineId of lineIds) {
            try {
              await completeProductProcessLine(lineId);
            } catch (e) {
              console.error("completeProductProcessLine failed", lineId, e);
            }
          }
          await loadData();
        } finally {
          markBusy(row.jobOrderId, false);
          actionInFlightRef.current = false;
        }
      });
    },
    [canComplete, openConfirm, t, loadData],
  );

  const handleCancel = useCallback(
    (row: OpsRow) => {
      if (!canCancel || row.isCancelled) return;
      openConfirm(t("Cancel job order confirm message"), async () => {
        if (actionInFlightRef.current) return;
        actionInFlightRef.current = true;
        markBusy(row.jobOrderId, true);
        try {
          await setJobOrderHidden(row.jobOrderId, true);
          await loadData();
        } finally {
          markBusy(row.jobOrderId, false);
          actionInFlightRef.current = false;
        }
      });
    },
    [canCancel, openConfirm, t, loadData],
  );

  const onConfirm = useCallback(async () => {
    if (!pendingAction) return;
    setConfirmLoading(true);
    try {
      await pendingAction();
    } catch (e) {
      console.error(e);
    } finally {
      setConfirmLoading(false);
      setConfirmOpen(false);
      setPendingAction(null);
      setConfirmMessage("");
    }
  }, [pendingAction]);

  const bucketLabel = (row: OpsRow) => {
    if (row.rowKind === "pending_qc") return t("Waiting QC Put Away");
    if (row.rowKind === "putawayed") return t("Put Awayed");
    if (row.isCancelled) return t("Cancelled");
    if (primaryTab === "carried_over") {
      switch (row.pickProcessBucket) {
        case "not_picked_not_started":
        case "picked_not_started":
          return t("pending");
        case "picked_started":
        case "not_picked_started":
          return t("processing");
        default:
          break;
      }
    }
    switch (row.pickProcessBucket) {
      case "not_picked_not_started":
      case "not_picked_started":
        return t("Not picked");
      case "picked_not_started":
      case "picked_started":
        return t("Picked");
      default:
        // Prefer explicit key over t("completed") → purchaseOrder「已上架」
        if (String(row.statusLabel).toLowerCase() === "completed") {
          return t("Completed");
        }
        return row.statusLabel || "-";
    }
  };

  const showManageActionsForRow = (row: OpsRow) => {
    if (row.isCancelled || row.rowKind === "putawayed") return false;
    if (row.rowKind === "pending_qc") return false;
    if (primaryTab === "pending_qc" || primaryTab === "putawayed") return false;
    if (primaryTab === "issue" && issueSub === "cancel") return false;
    return true;
  };

  const showQcActionForRow = (row: OpsRow) =>
    (primaryTab === "pending_qc" ||
      primaryTab === "putawayed" ||
      (primaryTab === "carried_over" && row.rowKind === "pending_qc")) &&
    row.stockInLineId != null;

  return (
    <LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale="zh-hk">
      <Card sx={{ mb: 2 }}>
        <CardContent>
          <Typography variant="h5" sx={{ fontWeight: 600, mb: 2 }}>
            {t("Job Order Ops Table")}
          </Typography>

          <Stack
            direction="row"
            spacing={2}
            sx={{ mb: 2, flexWrap: "wrap", alignItems: "center" }}
          >
            <DatePicker
              label={t("Search date")}
              value={queryDate}
              onChange={(v) => v && setQueryDate(v)}
              slotProps={{ textField: { size: "small", sx: { minWidth: 180 } } }}
            />
            <Button variant="outlined" size="small" onClick={() => void loadData()}>
              {t("Reload data")}
            </Button>
          </Stack>

          <Tabs
            value={primaryTab}
            onChange={(_, v: PrimaryTab) => setPrimaryTab(v)}
            variant="scrollable"
            scrollButtons="auto"
            sx={{ mb: 1, borderBottom: 1, borderColor: "divider" }}
          >
            <Tab
              value="needs_action"
              label={tabLabel(t("Needs action"), counts.needsAction)}
            />
            <Tab
              value="pending"
              label={tabLabel(t("pending"), counts.pending)}
            />
            <Tab
              value="processing"
              label={tabLabel(t("Processing"), counts.processing)}
            />
            <Tab
              value="carried_over"
              label={tabLabel(t("Off-plan unfinished"), counts.carriedOver)}
            />
            <Tab
              value="pending_qc"
              label={tabLabel(t("Waiting QC Put Away"), counts.pendingQc)}
            />
            <Tab
              value="putawayed"
              label={tabLabel(t("Put Awayed"), counts.putawayed)}
            />
            <Tab
              value="issue"
              label={tabLabel(t("Issue"), counts.stop + counts.cancel)}
            />
          </Tabs>

          {(
            ["needs_action", "pending", "processing"] as PrimaryTab[]
          ).includes(primaryTab) && (
            <Tabs
              value={productionSub}
              onChange={(_, v: ProductionSubTab) => setProductionSub(v)}
              sx={{ mb: 2 }}
            >
              <Tab value="all" label={tabLabel(t("All"), counts.subAll)} />
              <Tab
                value="not_picked"
                label={tabLabel(t("Not picked"), counts.subNotPicked)}
              />
              <Tab
                value="picked"
                label={tabLabel(t("Picked"), counts.subPicked)}
              />
            </Tabs>
          )}

          {primaryTab === "issue" && (
            <Tabs
              value={issueSub}
              onChange={(_, v: IssueSubTab) => setIssueSub(v)}
              sx={{ mb: 2 }}
            >
              <Tab
                value="stop"
                label={tabLabel(t("Stop (paused)"), counts.stop)}
              />
              <Tab
                value="cancel"
                label={tabLabel(t("Cancelled"), counts.cancel)}
              />
            </Tabs>
          )}

          {loading ? (
            <Box sx={{ display: "flex", justifyContent: "center", p: 3 }}>
              <CircularProgress />
            </Box>
          ) : (
            <>
              <TableContainer component={Paper} sx={{ maxHeight: 480, overflow: "auto" }}>
                <Table size="small" stickyHeader sx={{ minWidth: 800 }}>
                  <TableHead>
                    <TableRow>
                      <TableCell>{t("Job Order Code")}</TableCell>
                      <TableCell>{t("Item Code")}</TableCell>
                      <TableCell align="right">{t("Required Qty")}</TableCell>
                      <TableCell>{t("Production Date")}</TableCell>
                      <TableCell>{t("Status")}</TableCell>
                      <TableCell align="center" sx={{ minWidth: 280 }}>
                        {t("Actions")}
                      </TableCell>
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    {paginatedRows.length === 0 ? (
                      <TableRow>
                        <TableCell colSpan={6} align="center">
                          {t("No data available")}
                        </TableCell>
                      </TableRow>
                    ) : (
                      paginatedRows.map((row) => {
                        const busy = rowBusyIds.has(row.jobOrderId);
                        const carriedOver = isCarriedOver(row, searchDay);
                        const carriedCellSx = carriedOver
                          ? {
                              bgcolor: "warning.light",
                              borderBottomColor: "warning.main",
                            }
                          : undefined;
                        return (
                          <TableRow
                            key={row.key}
                            hover={!carriedOver}
                            sx={
                              carriedOver
                                ? {
                                    bgcolor: "warning.light",
                                    "&:hover": {
                                      bgcolor: "warning.light",
                                    },
                                    "& > .MuiTableCell-root": {
                                      bgcolor: "warning.light",
                                    },
                                    "&:hover > .MuiTableCell-root": {
                                      bgcolor: "warning.light",
                                    },
                                  }
                                : undefined
                            }
                          >
                            <TableCell sx={carriedCellSx}>
                              <Stack
                                direction="row"
                                alignItems="center"
                                spacing={0.75}
                              >
                                <Typography variant="body2" component="span">
                                  {row.jobOrderCode}
                                </Typography>
                                {carriedOver ? (
                                  <Tooltip title={t("Carried over from past day")}>
                                    <Avatar
                                      aria-label={t("Carried over from past day")}
                                      sx={{
                                        width: 24,
                                        height: 24,
                                        flexShrink: 0,
                                        bgcolor: "error.main",
                                        color: "error.contrastText",
                                        fontSize: "0.9rem",
                                        fontWeight: 800,
                                      }}
                                    >
                                      !
                                    </Avatar>
                                  </Tooltip>
                                ) : null}
                              </Stack>
                            </TableCell>
                            <TableCell sx={carriedCellSx}>
                              <Typography variant="body2">
                                {[row.itemCode, row.itemName].filter(Boolean).join(" ")}
                              </Typography>
                            </TableCell>
                            <TableCell align="right" sx={carriedCellSx}>
                              {row.requiredQty}
                              {row.uom ? ` ${row.uom}` : ""}
                            </TableCell>
                            <TableCell sx={carriedCellSx}>
                              {row.productionDate && dayjs(row.productionDate).isValid()
                                ? dayjs(row.productionDate).format(OUTPUT_DATE_FORMAT)
                                : "-"}
                            </TableCell>
                            <TableCell sx={carriedCellSx}>
                              <Stack direction="row" spacing={0.5} flexWrap="wrap" useFlexGap>
                                {row.isPaused && (
                                  <Chip size="small" color="warning" label={t("Stop (paused)")} />
                                )}
                                <Chip
                                  size="small"
                                  variant="outlined"
                                  label={bucketLabel(row)}
                                />
                              </Stack>
                            </TableCell>
                            <TableCell align="center" sx={carriedCellSx}>
                              <Stack
                                direction="row"
                                spacing={1}
                                justifyContent="center"
                                flexWrap="wrap"
                                useFlexGap
                              >
                                <Button
                                  size="small"
                                  variant="outlined"
                                  onClick={() => onSelectProcess?.(row.jobOrderId)}
                                >
                                  {t("View Details")}
                                </Button>
                                {showQcActionForRow(row) && (
                                  <Button
                                    size="small"
                                    variant="contained"
                                    onClick={() => handleOpenQcModal(row)}
                                  >
                                    {primaryTab === "putawayed" ||
                                    row.rowKind === "putawayed"
                                      ? t("Put Away Detail")
                                      : t("view stockin")}
                                  </Button>
                                )}
                                {showManageActionsForRow(row) && (
                                  <Button
                                    size="small"
                                    variant="contained"
                                    disabled={!canComplete || busy}
                                    onClick={() => handleComplete(row)}
                                    startIcon={
                                      busy ? (
                                        <CircularProgress size={14} color="inherit" />
                                      ) : undefined
                                    }
                                  >
                                    {t("Update Job Order")}
                                  </Button>
                                )}
                                {showManageActionsForRow(row) && (
                                  <Button
                                    size="small"
                                    variant="outlined"
                                    color="warning"
                                    disabled={!canCancel || busy}
                                    onClick={() => handleCancel(row)}
                                  >
                                    {t("Cancel Job Order")}
                                  </Button>
                                )}
                              </Stack>
                            </TableCell>
                          </TableRow>
                        );
                      })
                    )}
                  </TableBody>
                </Table>
              </TableContainer>
              <TablePagination
                component="div"
                count={filteredRows.length}
                page={page}
                onPageChange={(_, p) => setPage(p)}
                rowsPerPage={pageSize}
                onRowsPerPageChange={(e) => {
                  setPageSize(parseInt(e.target.value, 10));
                  setPage(0);
                }}
                rowsPerPageOptions={[5, 10, 25, 50]}
                labelRowsPerPage={t("Rows per page")}
              />
            </>
          )}
        </CardContent>
      </Card>

      <Dialog open={confirmOpen} onClose={closeConfirm} maxWidth="xs" fullWidth>
        <DialogTitle>{t("Confirm")}</DialogTitle>
        <DialogContent>
          <Typography variant="body2">{confirmMessage}</Typography>
        </DialogContent>
        <DialogActions>
          <Button onClick={closeConfirm} disabled={confirmLoading}>
            {t("Cancel")}
          </Button>
          <Button
            variant="contained"
            onClick={() => void onConfirm()}
            disabled={confirmLoading || !pendingAction}
          >
            {confirmLoading ? t("Processing...") : t("Confirm")}
          </Button>
        </DialogActions>
      </Dialog>

      <QcStockInModal
        session={sessionToken}
        open={qcModalOpen}
        onClose={() => {
          setQcModalOpen(false);
          setQcModalInfo(undefined);
        }}
        inputDetail={qcModalInfo}
        printerCombo={printerCombo}
        warehouse={[]}
        printSource="productionProcess"
        uiMode="default"
      />
    </LocalizationProvider>
  );
};

export default JobOrderOpsTable;
