"use client";

import { Box, Button, Grid, Stack, Typography, Select, MenuItem, FormControl, InputLabel } from "@mui/material";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { useSession } from "next-auth/react";
import { SessionWithTokens } from "@/config/authConfig";
import type { StoreLaneSummary, LaneRow, LaneBtn } from "@/app/api/pickOrder/actions";
import {
  assignByDeliveryOrderPickOrderId,
  assignWorkbenchByLane,
  fetchWorkbenchReleasedDoPickOrdersForSelection,
  fetchWorkbenchReleasedDoPickOrdersForSelectionToday,
  fetchWorkbenchStoreLaneSummary,
} from "@/app/api/doworkbench/actions";
import Swal from "sweetalert2";
import dayjs from "dayjs";
import ReleasedDoPickOrderSelectModal from "@/components/FinishedGoodSearch/ReleasedDoPickOrderSelectModal";

interface Props {
  onPickOrderAssigned?: () => void;
  onSwitchToDetailTab?: () => void;
  initialReleaseType?: string;
}

type LaneSlot4F = { truckDepartureTime: string; lane: LaneBtn };
type TruckGroup4F = { truckLanceCode: string; slots: (LaneSlot4F & { sequenceIndex: number })[] };

const WorkbenchFloorLanePanel: React.FC<Props> = ({ onPickOrderAssigned, onSwitchToDetailTab, initialReleaseType = "batch" }) => {
  const { t } = useTranslation("pickOrder");
  const { data: session } = useSession() as { data: SessionWithTokens | null };
  const currentUserId = session?.id ? parseInt(session.id) : undefined;
  const [selectedStore, setSelectedStore] = useState<string>("2/F");
  const [selectedTruck, setSelectedTruck] = useState<string>("");
  const [modalOpen, setModalOpen] = useState(false);
  const [truckCounts2F, setTruckCounts2F] = useState<{ truck: string; count: number }[]>([]);
  const [truckCounts4F, setTruckCounts4F] = useState<{ truck: string; count: number }[]>([]);
  const [summary2F, setSummary2F] = useState<StoreLaneSummary | null>(null);
  const [summary4F, setSummary4F] = useState<StoreLaneSummary | null>(null);
  const [defaultDateScope, setDefaultDateScope] = useState<"today" | "before">("today");
  const [isLoadingSummary, setIsLoadingSummary] = useState(false);
  const [isAssigning, setIsAssigning] = useState(false);
  const [isDefaultTruck, setIsDefaultTruck] = useState(false);
  const [beforeTodayTruckXCount, setBeforeTodayTruckXCount] = useState(0);
  const [selectedDate, setSelectedDate] = useState<string>("today");
  const [releaseType, setReleaseType] = useState<string>(initialReleaseType);
  const [ticketFloor, setTicketFloor] = useState<"2/F" | "4/F">("2/F");
  const defaultTruckCount = summary4F?.defaultTruckCount ?? 0;

  const hasLoggedRef = useRef(false);
  const fullReadyLoggedRef = useRef(false);
  const pendingRef = useRef(0);

  const workbenchReleasedListBridge = useMemo(
    () => ({
      loadBeforeToday: fetchWorkbenchReleasedDoPickOrdersForSelection,
      loadToday: fetchWorkbenchReleasedDoPickOrdersForSelectionToday,
      assignByListItemId: assignByDeliveryOrderPickOrderId,
    }),
    [],
  );

  const startFullTimer = () => {
    if (typeof window === "undefined") return;
    const key = "__FG_FLOOR_FULL_TIMER_STARTED__" as const;
    if (!(window as any)[key]) {
      (window as any)[key] = true;
      console.time("[FG] FloorLanePanel full ready");
    }
  };
  const tryEndFullTimer = () => {
    if (typeof window === "undefined") return;
    const key = "__FG_FLOOR_FULL_TIMER_STARTED__" as const;
    if ((window as any)[key] && !fullReadyLoggedRef.current && pendingRef.current === 0) {
      fullReadyLoggedRef.current = true;
      console.timeEnd("[FG] FloorLanePanel full ready");
      delete (window as any)[key];
    }
  };

  const loadSummaries = useCallback(async () => {
    setIsLoadingSummary(true);
    pendingRef.current += 1;
    startFullTimer();
    try {
      let dateParam: string | undefined;
      if (selectedDate === "today") dateParam = dayjs().format("YYYY-MM-DD");
      else if (selectedDate === "tomorrow") dateParam = dayjs().add(1, "day").format("YYYY-MM-DD");
      else if (selectedDate === "dayAfterTomorrow") dateParam = dayjs().add(2, "day").format("YYYY-MM-DD");
      const [s2, s4] = await Promise.all([
        fetchWorkbenchStoreLaneSummary("2/F", dateParam, releaseType),
        fetchWorkbenchStoreLaneSummary("4/F", dateParam, releaseType),
      ]);
      setSummary2F(s2);
      setSummary4F(s4);
    } catch (error) {
      console.error("Error loading summaries:", error);
    } finally {
      setIsLoadingSummary(false);
      pendingRef.current -= 1;
      tryEndFullTimer();
      if (!hasLoggedRef.current) {
        hasLoggedRef.current = true;
      }
    }
  }, [selectedDate, releaseType]);

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

  useEffect(() => {
    const loadCounts = async () => {
      pendingRef.current += 1;
      startFullTimer();
      try {
        const [list2F, list4F] = await Promise.all([
          fetchWorkbenchReleasedDoPickOrdersForSelection(undefined, "2/F"),
          fetchWorkbenchReleasedDoPickOrdersForSelection(undefined, "4/F"),
        ]);
        const groupByTruck = (list: { truckLanceCode?: string | null }[]) => {
          const map: Record<string, number> = {};
          list.forEach((item) => {
            const lane = item.truckLanceCode || "-";
            map[lane] = (map[lane] || 0) + 1;
          });
          return Object.entries(map)
            .map(([truck, count]) => ({ truck, count }))
            .sort((a, b) => a.truck.localeCompare(b.truck));
        };
        setTruckCounts2F(groupByTruck(list2F));
        setTruckCounts4F(groupByTruck(list4F));
      } catch (e) {
        console.error("Error loading counts:", e);
        setTruckCounts2F([]);
        setTruckCounts4F([]);
      } finally {
        pendingRef.current -= 1;
        tryEndFullTimer();
      }
    };
    void loadCounts();
  }, [loadSummaries]);

  useEffect(() => {
    const loadBeforeTodayTruckX = async () => {
      pendingRef.current += 1;
      startFullTimer();
      try {
        const list = await fetchWorkbenchReleasedDoPickOrdersForSelection(undefined, undefined, "車線-X");
        setBeforeTodayTruckXCount(list.length);
      } catch {
        setBeforeTodayTruckXCount(0);
      } finally {
        pendingRef.current -= 1;
        tryEndFullTimer();
      }
    };
    void loadBeforeTodayTruckX();
  }, []);

  const handleAssignByLane = useCallback(
    async (storeId: string, truckDepartureTime: string, truckLanceCode: string, requiredDate: string) => {
      if (!currentUserId) return;
      let dateParam: string | undefined;
      if (requiredDate === "today") dateParam = dayjs().format("YYYY-MM-DD");
      else if (requiredDate === "tomorrow") dateParam = dayjs().add(1, "day").format("YYYY-MM-DD");
      else if (requiredDate === "dayAfterTomorrow") dateParam = dayjs().add(2, "day").format("YYYY-MM-DD");
      setIsAssigning(true);
      try {
        const res = await assignWorkbenchByLane({
          userId: currentUserId,
          storeId,
          truckLanceCode,
          truckDepartureTime,
          requiredDate: dateParam,
        });
        console.log("assignByLane result:", res);
        if (res.code === "SUCCESS") {
          window.dispatchEvent(new CustomEvent("pickOrderAssigned"));
          void loadSummaries();
          onPickOrderAssigned?.();
          onSwitchToDetailTab?.();
        }
      } catch {
        await Swal.fire({ icon: "error", title: t("Error"), text: t("Error occurred during assignment."), confirmButtonText: t("Confirm"), confirmButtonColor: "#8dba00" });
      } finally {
        setIsAssigning(false);
      }
    },
    [currentUserId, loadSummaries, onPickOrderAssigned, onSwitchToDetailTab, t],
  );

  const handleLaneButtonClick = useCallback(
    async (
      storeId: string,
      truckDepartureTime: string,
      truckLanceCode: string,
      loadingSequence: number | null | undefined,
      requiredDate: string,
      unassigned: number,
      total: number,
    ) => {
      let dateDisplay = requiredDate;
      if (requiredDate === "today") dateDisplay = dayjs().format("YYYY-MM-DD");
      else if (requiredDate === "tomorrow") dateDisplay = dayjs().add(1, "day").format("YYYY-MM-DD");
      else if (requiredDate === "dayAfterTomorrow") dateDisplay = dayjs().add(2, "day").format("YYYY-MM-DD");
      const result = await Swal.fire({
        title: t("Confirm Assignment"),
        html: `<div style="text-align: left; padding: 10px 0;">
          <p><strong>${t("Store")}:</strong> ${storeId}</p>
          <p><strong>${t("Lane Code")}:</strong> ${truckLanceCode}</p>
          ${loadingSequence != null ? `<p><strong>${t("Loading Sequence")}:</strong> ${loadingSequence}</p>` : ""}
          <p><strong>${t("Departure Time")}:</strong> ${truckDepartureTime}</p>
          <p><strong>${t("Required Date")}:</strong> ${dateDisplay}</p>
          <p><strong>${t("Available Orders")}:</strong> ${unassigned}/${total}</p>
        </div>`,
        icon: "question",
        showCancelButton: true,
        confirmButtonText: t("Confirm"),
        cancelButtonText: t("Cancel"),
        confirmButtonColor: "#8dba00",
        cancelButtonColor: "#F04438",
      });
      if (result.isConfirmed) {
        await handleAssignByLane(storeId, truckDepartureTime, truckLanceCode, requiredDate);
      }
    },
    [handleAssignByLane, t],
  );

  const getDateLabel = (offset: number) => dayjs().add(offset, "day").format("YYYY-MM-DD");

  const truckGroups4F = useMemo((): TruckGroup4F[] => {
    const rows = summary4F?.rows as LaneRow[] | undefined;
    if (!rows?.length) return [];
    const map = new Map<string, LaneSlot4F[]>();
    for (const row of rows) {
      for (const lane of row.lanes) {
        const list = map.get(lane.truckLanceCode);
        const slot: LaneSlot4F = { truckDepartureTime: row.truckDepartureTime, lane };
        if (list) list.push(slot);
        else map.set(lane.truckLanceCode, [slot]);
      }
    }
    return Array.from(map.entries()).map(([truckLanceCode, slots]) => ({
      truckLanceCode,
      slots: slots
        .slice()
        .sort((a, b) => (a.lane.loadingSequence ?? 999) - (b.lane.loadingSequence ?? 999))
        .map((s, i) => ({ ...s, sequenceIndex: i + 1 })),
    }));
  }, [summary4F?.rows]);

  const renderNoEntry = () => (
    <Typography variant="body2" color="text.secondary" sx={{ fontWeight: 600, fontSize: "1rem", textAlign: "center", py: 1 }}>
      {t("No entries available")}
    </Typography>
  );

  return (
    <Box sx={{ mb: 2 }}>
      <Stack direction="row" spacing={2} sx={{ mb: 2, alignItems: "flex-start" }}>
        <Box sx={{ maxWidth: 300 }}>
          <FormControl fullWidth size="small">
            <InputLabel id="date-select-label">{t("Select Date")}</InputLabel>
            <Select labelId="date-select-label" value={selectedDate} label={t("Select Date")} onChange={(e) => setSelectedDate(e.target.value)}>
              <MenuItem value="today">{t("Today")} ({getDateLabel(0)})</MenuItem>
              <MenuItem value="tomorrow">{t("Tomorrow")} ({getDateLabel(1)})</MenuItem>
              <MenuItem value="dayAfterTomorrow">{t("Day After Tomorrow")} ({getDateLabel(2)})</MenuItem>
            </Select>
          </FormControl>
        </Box>
        <Box sx={{ minWidth: 140, maxWidth: 300 }}>
          <FormControl fullWidth size="small">
            <InputLabel id="release-type-select-label">{t("Release Type")}</InputLabel>
            <Select labelId="release-type-select-label" value={releaseType} label={t("Release Type")} onChange={(e) => setReleaseType(e.target.value)}>
              <MenuItem value="batch">{t("Batch")}</MenuItem>
              <MenuItem value="single">{t("Single")}</MenuItem>
            </Select>
          </FormControl>
        </Box>
        <Box sx={{ minWidth: 120, maxWidth: 200 }}>
          <FormControl fullWidth size="small">
            <InputLabel id="ticket-floor-select-label">{t("Floor ticket")}</InputLabel>
            <Select labelId="ticket-floor-select-label" value={ticketFloor} label={t("Floor ticket")} onChange={(e) => setTicketFloor(e.target.value as "2/F" | "4/F")}>
              <MenuItem value="2/F">{t("2F ticket")}</MenuItem>
              <MenuItem value="4/F">{t("4F ticket")}</MenuItem>
            </Select>
          </FormControl>
        </Box>
      </Stack>

      <Grid container spacing={2}>
        {ticketFloor === "2/F" && (
          <Grid item xs={12}>
            <Stack direction="row" spacing={2} alignItems="flex-start">
              <Typography variant="h6" sx={{ fontWeight: 600, minWidth: 60, pt: 1 }}>2/F</Typography>
              <Box sx={{ border: "1px solid #e0e0e0", borderRadius: 1, p: 1, backgroundColor: "#fafafa", flex: 1 }}>
                {isLoadingSummary ? <Typography variant="caption">{t("Loading...")}</Typography> : !summary2F?.rows?.length ? renderNoEntry() : (
                  <Grid container spacing={1}>
                    {summary2F.rows.map((row) => (
                      <Grid item xs={12} key={row.truckDepartureTime}>
                        <Stack direction={{ xs: "column", sm: "row" }} spacing={1} alignItems={{ xs: "stretch", sm: "center" }} sx={{ border: "1px solid #e0e0e0", borderRadius: 0.5, p: 1, backgroundColor: "#fff" }}>
                          <Typography variant="body2" sx={{ fontWeight: 600, minWidth: { sm: 60 } }}>{row.truckDepartureTime}</Typography>
                          <Stack direction="row" flexWrap="wrap" sx={{ gap: 1 }}>
                            {row.lanes.map((lane) => (
                              <Button key={`${row.truckDepartureTime}-${lane.truckLanceCode}`} variant="outlined" disabled={lane.unassigned === 0 || isAssigning} onClick={() => void handleLaneButtonClick("2/F", row.truckDepartureTime, lane.truckLanceCode, null, selectedDate, lane.unassigned, lane.total)}>
                                {`${lane.truckLanceCode} (${lane.unassigned}/${lane.total})`}
                              </Button>
                            ))}
                          </Stack>
                        </Stack>
                      </Grid>
                    ))}
                  </Grid>
                )}
              </Box>
            </Stack>
          </Grid>
        )}

        {ticketFloor === "4/F" && (
          <Grid item xs={12}>
            <Stack direction="row" spacing={2} alignItems="flex-start">
              <Typography variant="h6" sx={{ fontWeight: 600, minWidth: 60, pt: 1 }}>4/F</Typography>
              <Box sx={{ border: "1px solid #e0e0e0", borderRadius: 1, p: 1, backgroundColor: "#fafafa", flex: 1 }}>
                {isLoadingSummary ? <Typography variant="caption">{t("Loading...")}</Typography> : !truckGroups4F.length ? renderNoEntry() : (
                  <Grid container spacing={1}>
                    {truckGroups4F.map(({ truckLanceCode, slots }) => (
                      <Grid item xs={12} key={truckLanceCode}>
                        <Stack direction={{ xs: "column", sm: "row" }} spacing={1} alignItems={{ xs: "stretch", sm: "center" }} sx={{ border: "1px solid #e0e0e0", borderRadius: 0.5, p: 1, backgroundColor: "#fff" }}>
                          <Typography variant="body2" sx={{ fontWeight: 700, minWidth: { sm: 160 } }}>{truckLanceCode}</Typography>
                          <Stack direction="row" flexWrap="wrap" sx={{ gap: 1 }}>
                            {slots.map((slot) => {
                              const handlerName = (slot.lane.handlerName ?? "").trim();
                              return (
                                <Button key={`${truckLanceCode}-${slot.sequenceIndex}-${slot.truckDepartureTime}`} variant="outlined" disabled={slot.lane.unassigned === 0 || isAssigning} onClick={() => void handleLaneButtonClick("4/F", slot.truckDepartureTime, slot.lane.truckLanceCode, slot.lane.loadingSequence ?? null, selectedDate, slot.lane.unassigned, slot.lane.total)}>
                                  {`${t("Loading sequence n", { n: slot.lane.loadingSequence ?? slot.sequenceIndex })} (${slot.lane.unassigned}/${slot.lane.total})${handlerName ? ` ${handlerName}` : ""}`}
                                </Button>
                              );
                            })}
                          </Stack>
                        </Stack>
                      </Grid>
                    ))}
                  </Grid>
                )}
              </Box>
            </Stack>
          </Grid>
        )}

        <Grid item xs={12}>
          <Box sx={{ py: 2, mt: 1, mb: 0.5, borderTop: "1px solid #e0e0e0" }}>
            <Typography variant="subtitle1" sx={{ fontWeight: 600, mb: 0.5 }}>
              {t("Not yet finished released do pick orders")}
            </Typography>
            <Typography variant="body2" color="text.secondary">
              {t("Released orders not yet completed - click lane to select and assign")}
            </Typography>
          </Box>
        </Grid>

        {ticketFloor === "2/F" && (
          <Grid item xs={12}>
            <Stack direction="row" spacing={2} alignItems="flex-start">
              <Typography variant="h6" sx={{ fontWeight: 600, minWidth: 60, pt: 1 }}>2/F</Typography>
              <Box sx={{ border: "1px solid #e0e0e0", borderRadius: 1, p: 1, backgroundColor: "#fafafa", flex: 1 }}>
                {truckCounts2F.length === 0 ? renderNoEntry() : (
                  <Grid container spacing={1}>
                    {truckCounts2F.map(({ truck, count }) => (
                      <Grid item xs={6} sm={4} md={3} key={`2F-${truck}`} sx={{ display: "flex" }}>
                        <Button
                          variant="outlined"
                          onClick={() => {
                            setIsDefaultTruck(false);
                            setSelectedStore("2/F");
                            setSelectedTruck(truck);
                            setModalOpen(true);
                          }}
                          sx={{ flex: 1 }}
                        >
                          {`${truck} (${count})`}
                        </Button>
                      </Grid>
                    ))}
                  </Grid>
                )}
              </Box>
            </Stack>
          </Grid>
        )}

        {ticketFloor === "4/F" && (
          <Grid item xs={12}>
            <Stack direction="row" spacing={2} alignItems="flex-start">
              <Typography variant="h6" sx={{ fontWeight: 600, minWidth: 60, pt: 1 }}>4/F</Typography>
              <Box sx={{ border: "1px solid #e0e0e0", borderRadius: 1, p: 1, backgroundColor: "#fafafa", flex: 1 }}>
                {truckCounts4F.length === 0 ? renderNoEntry() : (
                  <Grid container spacing={1}>
                    {truckCounts4F.map(({ truck, count }) => (
                      <Grid item xs={6} sm={4} md={3} key={`4F-${truck}`} sx={{ display: "flex" }}>
                        <Button
                          variant="outlined"
                          onClick={() => {
                            setIsDefaultTruck(false);
                            setSelectedStore("4/F");
                            setSelectedTruck(truck);
                            setModalOpen(true);
                          }}
                          sx={{ flex: 1 }}
                        >
                          {`${truck} (${count})`}
                        </Button>
                      </Grid>
                    ))}
                  </Grid>
                )}
              </Box>
            </Stack>
          </Grid>
        )}

        <Grid item xs={12}>
          <Stack direction="row" spacing={2} alignItems="flex-start">
            <Typography sx={{ fontWeight: 600, minWidth: 60, pt: 1 }}>{t("Truck X")}</Typography>
            <Box sx={{ border: "1px solid #e0e0e0", borderRadius: 1, p: 1, backgroundColor: "#fafafa", flex: 1 }}>
              {beforeTodayTruckXCount === 0 && defaultTruckCount === 0 ? renderNoEntry() : (
                <Stack direction="row" spacing={1}>
                  {defaultTruckCount > 0 && (
                    <Button
                      variant="outlined"
                      onClick={() => {
                        setSelectedStore("");
                        setSelectedTruck("車線-X");
                        setIsDefaultTruck(true);
                        setDefaultDateScope("today");
                        setModalOpen(true);
                      }}
                    >
                      {`${t("Today")} (${defaultTruckCount})`}
                    </Button>
                  )}
                  {beforeTodayTruckXCount > 0 && (
                    <Button
                      variant="outlined"
                      onClick={() => {
                        setSelectedStore("4/F");
                        setSelectedTruck("車線-X");
                        setIsDefaultTruck(true);
                        setDefaultDateScope("before");
                        setModalOpen(true);
                      }}
                    >
                      {`${t("車線-X")} (${beforeTodayTruckXCount})`}
                    </Button>
                  )}
                </Stack>
              )}
            </Box>
          </Stack>
        </Grid>

        <ReleasedDoPickOrderSelectModal
          open={modalOpen}
          storeId={selectedStore}
          truck={selectedTruck}
          isDefaultTruck={isDefaultTruck}
          defaultDateScope={defaultDateScope}
          listBridge={workbenchReleasedListBridge}
          onClose={() => setModalOpen(false)}
          onAssigned={() => {
            void loadSummaries();
            onPickOrderAssigned?.();
            onSwitchToDetailTab?.();
          }}
        />
      </Grid>
    </Box>
  );
};

export default WorkbenchFloorLanePanel;