"use client";

import React, { useState, useEffect, useCallback, useMemo } from "react";

import {
  Box,
  Typography,
  Card,
  CardContent,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
  CircularProgress,
  Stack,
  Button,
  ToggleButton,
  ToggleButtonGroup,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
} from "@mui/material";

import { useTranslation } from "react-i18next";

import dayjs from "dayjs";

import type { Dayjs } from "dayjs";

import {
  fetchJobProcessStatus,
  JobProcessStatusResponse,
} from "@/app/api/jo/actions";

import { arrayToDayjs } from "@/app/utils/formatUtil";

import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers";

import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";

const REFRESH_INTERVAL = 10 * 60 * 1000; // 10 minutes

/** 每頁顯示工序數（4～6）；固定 5 以平衡可讀性與寬度 */

const PROCESSES_PER_PAGE = 5;

/** 與後端 ProductProcessStatus.value 一致（用於篩選查詢） */
const PRODUCT_PROCESS_STATUS_FILTER_VALUES = [
  "pending",
  "in_progress",
  "stopped",
  "completed",
  "cancelled",
] as const;

/** 工單狀態儀表板專用文案（與全域 pending/in_progress 等區隔） */
const JOB_DASHBOARD_PP_STATUS_I18N: Record<
  (typeof PRODUCT_PROCESS_STATUS_FILTER_VALUES)[number],
  string
> = {
  pending: "Job dashboard PP status: pending",
  in_progress: "Job dashboard PP status: in_progress",
  stopped: "Job dashboard PP status: stopped",
  completed: "Job dashboard PP status: completed",
  cancelled: "Job dashboard PP status: cancelled",
};

/** 工序格僅顯示一類資訊（單行） */
type ProcessCellDetailMode = "time" | "processName" | "equipment" | "handler";

function parseTimeToDayjs(timeData: unknown): Dayjs | null {
  if (timeData == null) return null;

  if (Array.isArray(timeData)) {
    try {
      const parsed = arrayToDayjs(timeData, true);

      return parsed.isValid() ? parsed : null;
    } catch {
      return null;
    }
  }

  if (typeof timeData === "string") {
    const parsed = dayjs(timeData);

    return parsed.isValid() ? parsed : null;
  }

  return null;
}

const JobProcessStatus: React.FC = () => {
  const { t } = useTranslation(["common", "jo"]);

  const [data, setData] = useState<JobProcessStatusResponse[]>([]);

  const [loading, setLoading] = useState<boolean>(true);

  /** 每秒更新一次：剩餘時間、進行中耗時（與現有時鐘共用，成本可忽略） */

  const [currentTime, setCurrentTime] = useState(dayjs());

  const [selectedDate, setSelectedDate] = useState<Dayjs>(dayjs());

  /** 後端 ProductProcessStatus，空字串 = 不篩選 */
  const [productProcessStatusFilter, setProductProcessStatusFilter] =
    useState<string>("");

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

  const [processPage, setProcessPage] = useState(0);

  const [cellDetailMode, setCellDetailMode] =
    useState<ProcessCellDetailMode>("time");

  useEffect(() => {
    const timer = setInterval(() => {
      setCurrentTime(dayjs());
    }, 1000);

    return () => clearInterval(timer);
  }, []);

  const loadData = useCallback(async () => {
    setLoading(true);

    try {
      const result = await fetchJobProcessStatus(
        selectedDate.format("YYYY-MM-DD"),
        productProcessStatusFilter || undefined,
      );

      setData(result);

      setLastDataRefreshTime(dayjs());
    } catch (error) {
      console.error("Error fetching job process status:", error);

      setData([]);
    } finally {
      setLoading(false);
    }
  }, [selectedDate, productProcessStatusFilter]);

  useEffect(() => {
    loadData();

    const interval = setInterval(() => {
      loadData();
    }, REFRESH_INTERVAL);

    return () => clearInterval(interval);
  }, [loadData]);

  useEffect(() => {
    setProcessPage(0);
  }, [selectedDate, productProcessStatusFilter]);

  const formatTime = (timeData: unknown): string => {
    const parsed = parseTimeToDayjs(timeData);

    return parsed ? parsed.format("HH:mm") : "-";
  };

  const formatDurationMs = useCallback(
    (ms: number): string => {
      if (ms < 0) ms = 0;

      const totalSeconds = Math.floor(ms / 1000);

      const hours = Math.floor(totalSeconds / 3600);

      const minutes = Math.floor((totalSeconds % 3600) / 60);

      const seconds = totalSeconds % 60;

      const parts: string[] = [];

      if (hours > 0) {
        parts.push(t("Duration hours", { count: hours }));
      }

      if (minutes > 0) {
        parts.push(t("Duration minutes", { count: minutes }));
      }

      if (seconds > 0 || parts.length === 0) {
        parts.push(t("Duration seconds", { count: seconds }));
      }

      return parts.join(" ");
    },

    [t],
  );

  const calculateRemainingTime = (planEndTime: unknown): string => {
    if (!planEndTime) return "-";

    let endTime: Dayjs;

    if (Array.isArray(planEndTime)) {
      try {
        endTime = arrayToDayjs(planEndTime, true);
      } catch {
        return "-";
      }
    } else if (typeof planEndTime === "string") {
      endTime = dayjs(planEndTime);
    } else {
      return "-";
    }

    if (!endTime.isValid()) {
      return "-";
    }

    const diff = endTime.diff(currentTime, "minute");

    if (diff < 0) return "0";

    const hours = Math.floor(diff / 60);

    const minutes = diff % 60;

    return `${hours.toString().padStart(2, "0")}:${minutes

      .toString()

      .padStart(2, "0")}`;
  };

  const maxProcessSlots = useMemo(() => {
    if (data.length === 0) return 0;

    return Math.max(
      0,
      ...data.map((d) => d.processes?.length ?? 0),
    );
  }, [data]);

  const totalPages =
    maxProcessSlots > 0 ? Math.ceil(maxProcessSlots / PROCESSES_PER_PAGE) : 0;

  useEffect(() => {
    if (totalPages === 0) {
      setProcessPage(0);

      return;
    }

    setProcessPage((p) => Math.min(p, totalPages - 1));
  }, [totalPages]);

  const startSlotIndex = processPage * PROCESSES_PER_PAGE;

  const visibleCount =
    maxProcessSlots > 0
      ? Math.min(PROCESSES_PER_PAGE, maxProcessSlots - startSlotIndex)
      : 0;

  const rangeFrom = maxProcessSlots > 0 ? startSlotIndex + 1 : 0;

  const rangeTo = maxProcessSlots > 0 ? startSlotIndex + visibleCount : 0;

  const renderProcessCell = (row: JobProcessStatusResponse, index: number) => {
    const process = row.processes[index];

    if (!process) {
      return (
        <TableCell
          key={`empty-${row.jobOrderId}-${index}`}
          sx={{
            padding: "10px 8px",
            verticalAlign: "top",
            wordBreak: "break-word",
          }}
        >
          <Typography variant="body2" color="text.secondary">
            —
          </Typography>
        </TableCell>
      );
    }

    if (!process.isRequired) {
      return (
        <TableCell
          key={index}
          sx={{
            padding: "10px 8px",
            verticalAlign: "top",
            wordBreak: "break-word",
          }}
        >
          <Typography variant="body2">N/A</Typography>
        </TableCell>
      );
    }

    const startD = parseTimeToDayjs(process.startTime);
    const endD = parseTimeToDayjs(process.endTime);
    let durationLabel = "-";
    if (startD && endD) {
      durationLabel = formatDurationMs(endD.diff(startD));
    } else if (startD && !endD) {
      durationLabel = formatDurationMs(currentTime.diff(startD));
    }

    const equipmentLine = [
      process.equipmentName,
      process.equipmentDetailName ? `-${process.equipmentDetailName}` : "",
    ]
      .filter((s) => s != null && String(s).length > 0)
      .join("");

    let lineText = "—";
    let lineColor: "text.primary" | "info.main" = "text.primary";

    switch (cellDetailMode) {
      case "time": {
        const startStr = formatTime(process.startTime);
        const endStr = formatTime(process.endTime);
        if (startD && endD) {
          lineText = `${startStr} – ${endStr} · ${durationLabel}`;
        } else if (startD && !endD) {
          lineText = `${startStr} – … · ${durationLabel} · ${t("In progress")}`;
          lineColor = "info.main";
        } else {
          lineText = "—";
        }
        break;
      }
      case "processName":
        lineText = process.processName?.trim() || "—";
        break;
      case "equipment":
        lineText = equipmentLine.trim().length ? equipmentLine : "—";
        break;
      case "handler": {
        const h = process.handlerName?.trim();
        lineText = h?.length ? h : "—";
        break;
      }
      default:
        break;
    }

    const isTimeMode = cellDetailMode === "time";

    return (
      <TableCell
        key={index}
        sx={{
          padding: "10px 8px",
          verticalAlign: "top",
          // 時間欄內容較長，允許換行並顯示完整；其他模式維持單行省略
          ...(isTimeMode ? { minWidth: 0 } : { maxWidth: 0 }),
        }}
      >
        <Typography
          variant="body2"
          sx={{
            color: lineColor,
            ...(isTimeMode
              ? {
                  whiteSpace: "normal",
                  wordBreak: "break-word",
                  overflow: "visible",
                  lineHeight: 1.35,
                }
              : {
                  overflow: "hidden",
                  textOverflow: "ellipsis",
                  whiteSpace: "nowrap",
                }),
          }}
          title={!isTimeMode && lineText !== "—" ? lineText : undefined}
        >
          {lineText}
        </Typography>
      </TableCell>
    );
  };

  return (
    <Card sx={{ mb: 2 }}>
      <CardContent>
        <Typography variant="h5" sx={{ fontWeight: 600, mb: 2 }}>
          {t("Job Process Status Dashboard")}
        </Typography>

        <Stack
          direction="row"
          spacing={2}
          sx={{ mb: 3, flexWrap: "wrap", alignItems: "center", gap: 1 }}
        >
          <LocalizationProvider dateAdapter={AdapterDayjs}>
            <DatePicker
              label={t("Date")}
              value={selectedDate}
              onChange={(newValue) => {
                if (newValue) setSelectedDate(newValue);
              }}
              format="YYYY-MM-DD"
              slotProps={{
                textField: { size: "small", sx: { minWidth: 160 } },
              }}
            />
          </LocalizationProvider>

          <FormControl size="small" sx={{ minWidth: 200 }}>
            <InputLabel id="jp-pp-status-filter-label">
              {t("Product process status")}
            </InputLabel>
            <Select
              labelId="jp-pp-status-filter-label"
              id="jp-pp-status-filter"
              label={t("Product process status")}
              value={productProcessStatusFilter}
              onChange={(e) => {
                setProductProcessStatusFilter(
                  typeof e.target.value === "string" ? e.target.value : "",
                );
              }}
            >
              <MenuItem value="">
                <em>{t("All")}</em>
              </MenuItem>
              {PRODUCT_PROCESS_STATUS_FILTER_VALUES.map((v) => (
                <MenuItem key={v} value={v}>
                  {t(JOB_DASHBOARD_PP_STATUS_I18N[v])}
                </MenuItem>
              ))}
            </Select>
          </FormControl>

          <Box sx={{ flexGrow: 1 }} />

          <Stack direction="row" spacing={2} sx={{ alignSelf: "center" }}>
            <Typography
              variant="body2"
              sx={{ color: "text.secondary" }}
              suppressHydrationWarning
            >
              {t("Now")}: {currentTime.format("HH:mm")}
            </Typography>

            <Typography variant="body2" sx={{ color: "text.secondary" }}>
              {t("Auto-refresh every 10 minutes")} | {t("Last updated")}:{" "}
              {lastDataRefreshTime
                ? lastDataRefreshTime.format("HH:mm:ss")
                : "--:--:--"}
            </Typography>
          </Stack>
        </Stack>

        <Stack
          direction="row"
          alignItems="center"
          spacing={1}
          sx={{ mb: 2, flexWrap: "wrap", gap: 1 }}
        >
          <Typography variant="body2" color="text.secondary">
            {t("Job process detail mode label")}
          </Typography>
          <ToggleButtonGroup
            value={cellDetailMode}
            exclusive
            size="small"
            color="primary"
            onChange={(_, value: ProcessCellDetailMode | null) => {
              if (value != null) setCellDetailMode(value);
            }}
          >
            <ToggleButton value="time">
              {t("Job process detail: time")}
            </ToggleButton>
            <ToggleButton value="processName">
              {t("Job process detail: process name")}
            </ToggleButton>
            <ToggleButton value="equipment">
              {t("Job process detail: equipment")}
            </ToggleButton>
            <ToggleButton value="handler">
              {t("Job process detail: handler")}
            </ToggleButton>
          </ToggleButtonGroup>
        </Stack>

        {maxProcessSlots > 0 && (
          <Stack
            direction="row"
            spacing={2}
            alignItems="center"
            sx={{ mb: 2, flexWrap: "wrap", gap: 1 }}
          >
            <Button
              variant="outlined"
              size="small"
              disabled={processPage <= 0}
              onClick={() => setProcessPage((p) => Math.max(0, p - 1))}
            >
              {t("Previous page")}
            </Button>

            <Typography variant="body2" color="text.secondary">
              {t("Process page summary", {
                from: rangeFrom,

                to: rangeTo,

                total: maxProcessSlots,
              })}
            </Typography>

            <Button
              variant="outlined"
              size="small"
              disabled={processPage >= totalPages - 1}
              onClick={() =>
                setProcessPage((p) => Math.min(totalPages - 1, p + 1))
              }
            >
              {t("Next page")}
            </Button>
          </Stack>
        )}

        <Box sx={{ mt: 2 }}>
          {loading ? (
            <Box sx={{ display: "flex", justifyContent: "center", p: 3 }}>
              <CircularProgress />
            </Box>
          ) : (
            <TableContainer
              component={Paper}
              sx={{
                border: "3px solid #135fed",

                maxHeight: 540,

                overflow: "auto",

                overflowX: "hidden",
              }}
            >
              <Table
                size="small"
                sx={{
                  width: "100%",

                  tableLayout: "fixed",
                }}
              >
                <TableHead
                  sx={{
                    position: "sticky",

                    top: 0,

                    zIndex: 1,

                    backgroundColor: "grey.100",
                  }}
                >
                  <TableRow sx={{ backgroundColor: "grey.100" }}>
                    <TableCell
                      rowSpan={2}
                      sx={{
                        padding: "12px 10px",

                        width: "12%",

                        verticalAlign: "middle",
                      }}
                    >
                      <Typography variant="subtitle2" sx={{ fontWeight: 600 }}>
                        {t("Job Order No.")}
                      </Typography>
                    </TableCell>

                    <TableCell
                      rowSpan={2}
                      sx={{
                        padding: "12px 10px",

                        width: "18%",

                        verticalAlign: "middle",
                      }}
                    >
                      <Typography variant="subtitle2" sx={{ fontWeight: 600 }}>
                        {t("FG / WIP Item")}
                      </Typography>
                    </TableCell>

                    <TableCell
                      rowSpan={2}
                      sx={{
                        padding: "12px 10px",

                        width: "10%",

                        verticalAlign: "middle",
                      }}
                    >
                      <Typography variant="subtitle2" sx={{ fontWeight: 600 }}>
                        {t("Production Time Remaining")}
                      </Typography>
                    </TableCell>

                    {maxProcessSlots > 0 &&
                      Array.from({ length: visibleCount }, (_, i) => (
                        <TableCell
                          key={`h1-${startSlotIndex + i}`}
                          sx={{ padding: "10px 8px" }}
                          align="center"
                        >
                          <Typography
                            variant="subtitle2"
                            sx={{ fontWeight: 600 }}
                          >
                            {t("Process")} {startSlotIndex + i + 1}
                          </Typography>
                        </TableCell>
                      ))}
                  </TableRow>

                  <TableRow sx={{ backgroundColor: "grey.100" }}>
                    {maxProcessSlots > 0 &&
                      Array.from({ length: visibleCount }, (_, i) => (
                        <TableCell
                          key={`h3-${startSlotIndex + i}`}
                          sx={{ padding: "10px 8px" }}
                          align="center"
                        >
                          <Typography
                            variant="caption"
                            sx={{ fontWeight: 600 }}
                          >
                            {cellDetailMode === "time"
                              ? t("Job process detail: time")
                              : cellDetailMode === "processName"
                                ? t("Job process detail: process name")
                                : cellDetailMode === "equipment"
                                  ? t("Job process detail: equipment")
                                  : t("Job process detail: handler")}
                          </Typography>
                        </TableCell>
                      ))}
                  </TableRow>
                </TableHead>

                <TableBody>
                  {data.length === 0 ? (
                    <TableRow>
                      <TableCell
                        colSpan={Math.max(3, 3 + visibleCount)}
                        align="center"
                        sx={{ padding: "20px" }}
                      >
                        {t("No data available")}
                      </TableCell>
                    </TableRow>
                  ) : maxProcessSlots === 0 ? (
                    <TableRow>
                      <TableCell
                        colSpan={3}
                        align="center"
                        sx={{ padding: "20px" }}
                      >
                        {t("No data available")}
                      </TableCell>
                    </TableRow>
                  ) : (
                    data.map((row) => (
                      <TableRow key={row.jobOrderId}>
                        <TableCell
                          sx={{ padding: "10px", verticalAlign: "top" }}
                        >
                          {row.jobOrderCode || "-"}
                        </TableCell>

                        <TableCell
                          sx={{ padding: "10px", verticalAlign: "top" }}
                        >
                          <Box
                            sx={{
                              display: "flex",
                              flexDirection: "column",
                              gap: 0.5,
                            }}
                          >
                            {row.itemCode || "-"}
                          </Box>

                          <Box>{row.itemName || "-"}</Box>
                        </TableCell>

                        <TableCell
                          sx={{ padding: "10px", verticalAlign: "top" }}
                        >
                          {row.status === "pending"
                            ? "-"
                            : calculateRemainingTime(row.planEndTime)}
                        </TableCell>

                        {Array.from({ length: visibleCount }, (_, i) =>
                          renderProcessCell(row, startSlotIndex + i),
                        )}
                      </TableRow>
                    ))
                  )}
                </TableBody>
              </Table>
            </TableContainer>
          )}
        </Box>
      </CardContent>
    </Card>
  );
};

export default JobProcessStatus;
