"use client";

/**
 * 權限說明（與全站一致）：
 * - 登入後 JWT / session 帶有 `abilities: string[]`（見 config/authConfig、authorities.ts）。
 * - 導航「Finished Good Order」等使用 `requiredAbility: [AUTH.STOCK_FG, AUTH.ADMIN]`。
 * - 本表「撤銷領取 / 強制完成」僅允許具 **ADMIN** 能力者操作（對應 DB `authority.authority = 'ADMIN'`，例如 `user_authority` 對應 id=8 之權限列）。
 * - 一般使用者可進入本頁與檢視列表；按鈕會 disabled 並以 Tooltip 提示。
 */

import React, { useState, useEffect, useCallback, useMemo } from "react";
import {
  Box,
  Typography,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  Card,
  CardContent,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
  CircularProgress,
  TablePagination,
  Chip,
  Button,
  Tooltip,
} from "@mui/material";
import { useTranslation } from "react-i18next";
import { useSession } from "next-auth/react";
import dayjs, { Dayjs } from "dayjs";
import { arrayToDayjs, requiredDeliveryDateToDayString } from "@/app/utils/formatUtil";
import { fetchTicketReleaseTable, getTicketReleaseTable } from "@/app/api/do/actions";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import {
  forceCompleteDoPickOrder,
  revertDoPickOrderAssignment,
} from "@/app/api/pickOrder/actions";
import Swal from "sweetalert2";
import { AUTH } from "@/authorities";
import { SessionWithTokens } from "@/config/authConfig";

function isCompletedStatus(status: string | null | undefined): boolean {
  return (status ?? "").toLowerCase() === "completed";
}

/** 已領取（有負責人）的進行中單據才可撤銷或強制完成；未領取不可強制完成 */
function showDoPickOpsButtons(row: getTicketReleaseTable): boolean {
  return (
    row.isActiveDoPickOrder === true &&
    !isCompletedStatus(row.ticketStatus) &&
    row.handledBy != null
  );
}

const isDev = process.env.NODE_ENV === "development";

function shouldLogTicketFilterDebug(): boolean {
  if (isDev) return true;
  if (typeof window === "undefined") return false;
  return (window as unknown as { __FG_TICKET_FILTER_DEBUG__?: boolean }).__FG_TICKET_FILTER_DEBUG__ === true;
}

const FGPickOrderTicketReleaseTable: React.FC = () => {
  const { t } = useTranslation("ticketReleaseTable");
  const { data: session } = useSession() as { data: SessionWithTokens | null };
  const abilities = session?.abilities ?? session?.user?.abilities ?? [];
  // 依照 DB `authority.authority = 'ADMIN'` 的逻辑：仅 abilities 明確包含 ADMIN 才允許操作
  // (避免 abilities 裡出現前後空白導致 includes 判斷失效)
  const canManageDoPickOps = abilities.some((a) => a.trim() === AUTH.ADMIN);

  const [queryDate, setQueryDate] = useState<Dayjs>(() => dayjs());
  const [selectedFloor, setSelectedFloor] = useState<string>("");
  const [selectedStatus, setSelectedStatus] = useState<string>("released");

  const [data, setData] = useState<getTicketReleaseTable[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [paginationController, setPaginationController] = useState({
    pageNum: 0,
    pageSize: 5,
  });

  const [now, setNow] = useState(dayjs());
  const [lastDataRefreshTime, setLastDataRefreshTime] = useState<dayjs.Dayjs | null>(null);

  const formatTime = (timeData: unknown): string => {
    if (!timeData) return "";

    let hour: number;
    let minute: number;

    if (typeof timeData === "string") {
      const parts = timeData.split(":");
      hour = parseInt(parts[0], 10);
      minute = parseInt(parts[1] || "0", 10);
    } else if (Array.isArray(timeData)) {
      hour = timeData[0] || 0;
      minute = timeData[1] || 0;
    } else {
      return "";
    }

    const formattedHour = hour.toString().padStart(2, "0");
    const formattedMinute = minute.toString().padStart(2, "0");
    return `${formattedHour}:${formattedMinute}`;
  };

  const loadData = useCallback(async () => {
    setLoading(true);
    try {
      const dayStr = queryDate.format("YYYY-MM-DD");
      const result = await fetchTicketReleaseTable(dayStr, dayStr);
      if (shouldLogTicketFilterDebug() && Array.isArray(result) && result.length > 0) {
        const statusCounts = result.reduce<Record<string, number>>((acc, r) => {
          const k = String(r.ticketStatus ?? "(null)");
          acc[k] = (acc[k] ?? 0) + 1;
          return acc;
        }, {});
        console.log("[FGTicketReleaseTable] API rows:", result.length, "ticketStatus 分布:", statusCounts);
        console.table(
          result.slice(0, 5).map((r) => ({
            ticketStatus: r.ticketStatus ?? "(null)",
            requiredDeliveryDate: r.requiredDeliveryDate,
            itemDate: r.requiredDeliveryDate
              ? requiredDeliveryDateToDayString(r.requiredDeliveryDate)
              : "",
            queryDay: dayStr,
          })),
        );
      }
      setData(result);
      setLastDataRefreshTime(dayjs());
    } catch (error) {
      console.error("Error fetching ticket release table:", error);
    } finally {
      setLoading(false);
    }
  }, [queryDate]);

  useEffect(() => {
    loadData();
    const id = setInterval(loadData, 5 * 60 * 1000);
    return () => clearInterval(id);
  }, [loadData]);

  useEffect(() => {
    const tick = setInterval(() => setNow(dayjs()), 30 * 1000);
    return () => clearInterval(tick);
  }, []);

  const dayStr = queryDate.format("YYYY-MM-DD");

  const filteredData = useMemo(() => {
    let dropFloor = 0;
    let dropDate = 0;
    let dropStatus = 0;
    const filtered: getTicketReleaseTable[] = [];
    for (const item of data) {
      if (selectedFloor && item.storeId !== selectedFloor) {
        dropFloor++;
        continue;
      }
      if (item.requiredDeliveryDate) {
        const itemDate = requiredDeliveryDateToDayString(item.requiredDeliveryDate);
        if (itemDate !== dayStr) {
          dropDate++;
          continue;
        }
      }
      if (selectedStatus && item.ticketStatus?.toLowerCase() !== selectedStatus.toLowerCase()) {
        dropStatus++;
        continue;
      }
      filtered.push(item);
    }
    if (shouldLogTicketFilterDebug()) {
      console.log("[FGTicketReleaseTable] filter:", {
        total: data.length,
        kept: filtered.length,
        dropFloor,
        dropDate,
        dropStatus,
        selectedFloor: selectedFloor || "(all)",
        selectedStatus: selectedStatus || "(all)",
        dayStr,
      });
    }
    return filtered;
  }, [data, dayStr, selectedFloor, selectedStatus]);
  const handlePageChange = useCallback((event: unknown, newPage: number) => {
    setPaginationController((prev) => ({
      ...prev,
      pageNum: newPage,
    }));
  }, []);

  const handlePageSizeChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
    const newPageSize = parseInt(event.target.value, 10);
    setPaginationController({
      pageNum: 0,
      pageSize: newPageSize,
    });
  }, []);

  const paginatedData = useMemo(() => {
    const startIndex = paginationController.pageNum * paginationController.pageSize;
    const endIndex = startIndex + paginationController.pageSize;
    return filteredData.slice(startIndex, endIndex);
  }, [filteredData, paginationController]);

  useEffect(() => {
    setPaginationController((prev) => ({ ...prev, pageNum: 0 }));
  }, [queryDate, selectedFloor, selectedStatus]);

  const handleRevert = async (row: getTicketReleaseTable) => {
    if (!canManageDoPickOps) return;
    const r = await Swal.fire({
      title: t("Confirm revert assignment"),
      text: t("Revert assignment hint"),
      icon: "warning",
      showCancelButton: true,
      confirmButtonText: t("Confirm"),
      cancelButtonText: t("Cancel"),
    });
    if (!r.isConfirmed) return;
    try {
      const res = await revertDoPickOrderAssignment(row.id);
      if (res.code === "SUCCESS") {
        await Swal.fire({ icon: "success", text: t("Operation succeeded"), timer: 1500, showConfirmButton: false });
        await loadData();
      } else {
        await Swal.fire({ icon: "error", title: res.code ?? "", text: res.message ?? "" });
      }
    } catch (e) {
      console.error(e);
      await Swal.fire({ icon: "error", text: String(e) });
    }
  };

  const handleForceComplete = async (row: getTicketReleaseTable) => {
    if (!canManageDoPickOps) return;
    const r = await Swal.fire({
      title: t("Confirm force complete"),
      text: t("Force complete hint"),
      icon: "warning",
      showCancelButton: true,
      confirmButtonText: t("Confirm"),
      cancelButtonText: t("Cancel"),
    });
    if (!r.isConfirmed) return;
    try {
      const res = await forceCompleteDoPickOrder(row.id);
      if (res.code === "SUCCESS") {
        await Swal.fire({ icon: "success", text: t("Operation succeeded"), timer: 1500, showConfirmButton: false });
        await loadData();
      } else {
        await Swal.fire({ icon: "error", title: res.code ?? "", text: res.message ?? "" });
      }
    } catch (e) {
      console.error(e);
      await Swal.fire({ icon: "error", text: String(e) });
    }
  };

  const opsTooltip = !canManageDoPickOps ? t("Manager only hint") : "";

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

          <Stack direction="row" spacing={2} sx={{ mb: 3, flexWrap: "wrap", alignItems: "center" }}>
            <DatePicker
              label={t("Target 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>

            <FormControl sx={{ minWidth: 150 }} size="small">
              <InputLabel id="floor-select-label" shrink>
                {t("Floor")}
              </InputLabel>
              <Select
                labelId="floor-select-label"
                value={selectedFloor}
                label={t("Floor")}
                onChange={(e) => setSelectedFloor(e.target.value)}
                displayEmpty
              >
                <MenuItem value="">{t("All Floors")}</MenuItem>
                <MenuItem value="2/F">2/F</MenuItem>
                <MenuItem value="4/F">4/F</MenuItem>
              </Select>
            </FormControl>

            <FormControl sx={{ minWidth: 150 }} size="small">
              <InputLabel id="status-select-label" shrink>
                {t("Status")}
              </InputLabel>
              <Select
                labelId="status-select-label"
                value={selectedStatus}
                label={t("Status")}
                onChange={(e) => setSelectedStatus(e.target.value)}
                displayEmpty
              >
                <MenuItem value="">{t("All Statuses")}</MenuItem>
                <MenuItem value="pending">{t("pending")}</MenuItem>
                <MenuItem value="released">{t("released")}</MenuItem>
                <MenuItem value="completed">{t("completed")}</MenuItem>
              </Select>
            </FormControl>

            <Box sx={{ flexGrow: 1 }} />
            <Stack direction="row" spacing={2} sx={{ flexShrink: 0, alignSelf: "center" }}>
              <Typography variant="body2" sx={{ color: "text.secondary" }} suppressHydrationWarning>
                {t("Now")}: {now.format("HH:mm")}
              </Typography>
              <Typography variant="body2" sx={{ color: "text.secondary" }}>
                {t("Auto-refresh every 5 minutes")} | {t("Last updated")}:{" "}
                {lastDataRefreshTime ? lastDataRefreshTime.format("HH:mm:ss") : "--:--:--"}
              </Typography>
            </Stack>
          </Stack>

          <Box sx={{ mt: 2 }}>
            {loading ? (
              <Box sx={{ display: "flex", justifyContent: "center", p: 3 }}>
                <CircularProgress />
              </Box>
            ) : (
              <>
                <TableContainer component={Paper} sx={{ maxHeight: 440, overflow: "auto" }}>
                  <Table size="small" sx={{ minWidth: 650 }}>
                    <TableHead>
                      <TableRow
                        sx={{
                          position: "sticky",
                          top: 0,
                          zIndex: 1,
                          backgroundColor: "grey.100",
                        }}
                      >
                        <TableCell>{t("Store ID")}</TableCell>
                        <TableCell>{t("Required Delivery Date")}</TableCell>
                        <TableCell>
                          <Box sx={{ display: "flex", flexDirection: "column", gap: 0.5 }}>
                            <Typography variant="subtitle2" sx={{ fontWeight: 600 }}>
                              {t("Truck Information")}
                            </Typography>
                            <Typography variant="caption" sx={{ color: "text.secondary" }}>
                              {t("Truck Lane Code")} - {t("Departure Time")}
                            </Typography>
                          </Box>
                        </TableCell>
                        <TableCell sx={{ minWidth: 200, width: "20%" }}>{t("Shop Name")}</TableCell>
                        <TableCell align="right">{t("Loading Sequence")}</TableCell>
                        <TableCell>
                          <Box sx={{ display: "flex", flexDirection: "column", gap: 0.5 }}>
                            <Typography variant="subtitle2" sx={{ fontWeight: 600 }}>
                              {t("Ticket Information")}
                            </Typography>
                            <Typography variant="caption" sx={{ color: "text.secondary" }}>
                              {t("Ticket No.")} ({t("Status")})
                            </Typography>
                            <Typography variant="caption" sx={{ color: "text.secondary" }}>
                              {t("Released Time")} - {t("Completed Time")}
                            </Typography>
                          </Box>
                        </TableCell>
                        <TableCell>{t("Handler Name")}</TableCell>
                        <TableCell align="right" sx={{ minWidth: 100, width: "8%", whiteSpace: "nowrap" }}>
                          {t("Number of FG Items (Order Item(s) Count)")}
                        </TableCell>
                        <TableCell align="center" sx={{ minWidth: 200 }}>
                          {t("Actions")}
                        </TableCell>
                      </TableRow>
                    </TableHead>
                    <TableBody>
                      {paginatedData.length === 0 ? (
                        <TableRow>
                          <TableCell colSpan={9} align="center">
                            {t("No data available")}
                          </TableCell>
                        </TableRow>
                      ) : (
                        paginatedData.map((row) => (
                          <TableRow key={`${row.id}-${row.ticketNo}-${row.requiredDeliveryDate}`}>
                            <TableCell>{row.storeId || "-"}</TableCell>
                            <TableCell>
                              {row.requiredDeliveryDate
                                ? requiredDeliveryDateToDayString(row.requiredDeliveryDate)
                                : "-"}
                            </TableCell>

                            <TableCell>
                              <Box sx={{ display: "flex", gap: 0.5, flexWrap: "wrap", alignItems: "center" }}>
                                {row.truckLanceCode && (
                                  <Chip label={row.truckLanceCode} size="small" color="primary" />
                                )}
                                {row.truckDepartureTime && (
                                  <Chip label={formatTime(row.truckDepartureTime)} size="small" color="secondary" />
                                )}
                                {!row.truckLanceCode && !row.truckDepartureTime && (
                                  <Typography variant="body2" sx={{ color: "text.secondary" }}>
                                    -
                                  </Typography>
                                )}
                              </Box>
                            </TableCell>

                            <TableCell sx={{ minWidth: 200, width: "20%" }}>{row.shopName || "-"}</TableCell>
                            <TableCell align="right">{row.loadingSequence ?? "-"}</TableCell>

                            <TableCell>
                              <Box sx={{ display: "flex", flexDirection: "column", gap: 0.5 }}>
                                <Typography variant="body2">
                                  {row.ticketNo || "-"} ({row.ticketStatus ? t(row.ticketStatus.toLowerCase()) : "-"})
                                </Typography>
                                <Typography variant="body2">
                                  {t("Released Time")}:{" "}
                                  {row.ticketReleaseTime
                                    ? (() => {
                                        if (Array.isArray(row.ticketReleaseTime)) {
                                          return arrayToDayjs(row.ticketReleaseTime, true).format("HH:mm");
                                        }
                                        const parsedDate = dayjs(row.ticketReleaseTime, "YYYYMMDDHHmmss");
                                        if (!parsedDate.isValid()) {
                                          return dayjs(row.ticketReleaseTime).format("HH:mm");
                                        }
                                        return parsedDate.format("HH:mm");
                                      })()
                                    : "-"}
                                </Typography>
                                <Typography variant="body2">
                                  {t("Completed Time")}:{" "}
                                  {row.ticketCompleteDateTime
                                    ? (() => {
                                        if (Array.isArray(row.ticketCompleteDateTime)) {
                                          return arrayToDayjs(row.ticketCompleteDateTime, true).format("HH:mm");
                                        }
                                        const parsedDate = dayjs(row.ticketCompleteDateTime, "YYYYMMDDHHmmss");
                                        if (!parsedDate.isValid()) {
                                          return dayjs(row.ticketCompleteDateTime).format("HH:mm");
                                        }
                                        return parsedDate.format("HH:mm");
                                      })()
                                    : "-"}
                                </Typography>
                              </Box>
                            </TableCell>
                            <TableCell>{row.handlerName ?? "-"}</TableCell>
                            <TableCell align="right" sx={{ minWidth: 100, width: "8%" }}>
                              {row.numberOfFGItems ?? 0}
                            </TableCell>
                            <TableCell align="center">
                              {showDoPickOpsButtons(row) ? (
                                <Stack direction="row" spacing={1} justifyContent="center" flexWrap="wrap" useFlexGap>
                                  <Tooltip title={opsTooltip}>
                                    <span>
                                      <Button
                                        size="small"
                                        variant="outlined"
                                        color="warning"
                                        disabled={!canManageDoPickOps}
                                        onClick={() => void handleRevert(row)}
                                      >
                                        {t("Revert assignment")}
                                      </Button>
                                    </span>
                                  </Tooltip>
                                  <Tooltip title={opsTooltip}>
                                    <span>
                                      <Button
                                        size="small"
                                        variant="outlined"
                                        color="primary"
                                        disabled={!canManageDoPickOps}
                                        onClick={() => void handleForceComplete(row)}
                                      >
                                        {t("Force complete DO")}
                                      </Button>
                                    </span>
                                  </Tooltip>
                                </Stack>
                              ) : (
                                <Typography variant="caption" color="text.secondary">
                                  —
                                </Typography>
                              )}
                            </TableCell>
                          </TableRow>
                        ))
                      )}
                    </TableBody>
                  </Table>
                </TableContainer>
                {filteredData.length > 0 && (
                  <TablePagination
                    component="div"
                    count={filteredData.length}
                    page={paginationController.pageNum}
                    rowsPerPage={paginationController.pageSize}
                    onPageChange={handlePageChange}
                    onRowsPerPageChange={handlePageSizeChange}
                    rowsPerPageOptions={[5, 10, 15]}
                    labelRowsPerPage={t("Rows per page")}
                  />
                )}
              </>
            )}
          </Box>
        </CardContent>
      </Card>
    </LocalizationProvider>
  );
};

export default FGPickOrderTicketReleaseTable;
