"use client";

import React, { memo, useCallback, useEffect, useMemo, useState } from "react";
import {
  Alert,
  Box,
  Button,
  Chip,
  CircularProgress,
  Collapse,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  IconButton,
  Stack,
  TextField,
  Typography,
} from "@mui/material";
import {
  AlertCircle,
  AlertTriangle,
  Ban,
  Calendar,
  Check,
  CheckCircle2,
  ChevronDown,
  ChevronUp,
  ClipboardList,
  Clock,
  FileText,
  EyeOff,
  Play,
  RotateCcw,
  X,
} from "lucide-react";
import { useTranslation } from "react-i18next";
import {
  applyNowTruckLaneScheduleClient,
  cancelTruckLaneScheduleClient,
  createTruckLaneScheduleClient,
  reactivateCancelledTruckLaneScheduleClient,
  getTruckLaneScheduleClient,
  ignoreTruckLaneScheduleClient,
  listTruckLaneSchedulesClient,
  retryFailedTruckLaneScheduleClient,
  type TruckLaneScheduleLineRequest,
  type TruckLaneScheduleLineResponse,
  type TruckLaneScheduleResponse,
} from "@/app/api/shop/client";
import type { ScheduleLaneOption } from "@/components/Shop/ScheduleChangeModal";
import { extractApiErrorMessage } from "@/components/Shop/scheduleClientHelpers";
import {
  buildExecuteAtIso,
  isExecuteAtTooEarly,
  resolveRescheduleExecuteAt,
  formatScheduleDisplayDateTime,
} from "@/components/Shop/scheduleExecuteAt";
import {
  buildScheduleLineDescription,
} from "@/components/Shop/scheduleLineDisplay";

type UiFilter = "all" | "pending" | "success" | "failed";

type UiTaskStatus = "pending" | "success" | "failed" | "cancelled" | "ignored";

function uiStatusFromLineCounts(
  counts: NonNullable<TruckLaneScheduleResponse["lineCounts"]>,
): UiTaskStatus | null {
  const { total, applied, failed, pending } = counts;
  if (failed > 0) return "failed";
  if (pending === 0 && applied > 0) return "success";
  if (pending === 0 && failed > 0 && applied === 0) return "failed";
  if (applied > 0 || failed > 0) return failed > 0 ? "failed" : "success";
  if (total > 0 && pending === total) return "pending";
  return null;
}

function uiStatusFromLines(
  lines: TruckLaneScheduleLineResponse[],
): UiTaskStatus | null {
  if (lines.length === 0) return null;
  const failed = lines.filter((l) => l.lineStatus === "FAILED").length;
  const applied = lines.filter((l) => l.lineStatus === "APPLIED").length;
  const pending = lines.filter((l) => l.lineStatus === "PENDING").length;
  if (failed > 0) return "failed";
  if (pending === 0 && applied > 0) return "success";
  if (pending > 0 && (applied > 0 || failed > 0)) {
    return failed > 0 ? "failed" : "pending";
  }
  if (pending === lines.length) return "pending";
  return null;
}

/** Prefer fresh list aggregates over cached detail lines (detail can be stale after mutations). */
function resolveUiStatus(
  task: TruckLaneScheduleResponse,
  detail?: TruckLaneScheduleResponse | null,
): UiTaskStatus {
  const st = String(task.status ?? "").toUpperCase();
  if (st === "CANCELLED") return "cancelled";
  if (st === "IGNORED") return "ignored";

  if (task.lineCounts) {
    const fromCounts = uiStatusFromLineCounts(task.lineCounts);
    if (fromCounts) return fromCounts;
  }

  if (st === "APPLIED") return "success";
  if (st === "FAILED") return "failed";
  if (st === "PARTIAL") {
    return (task.lineCounts?.failed ?? 0) > 0 ? "failed" : "success";
  }

  const fromDetailLines = detail?.lines?.length
    ? uiStatusFromLines(detail.lines)
    : null;
  if (fromDetailLines) return fromDetailLines;

  if (st === "PENDING" || st === "APPLYING") return "pending";
  return "pending";
}

function canManagePendingSchedule(
  task: TruckLaneScheduleResponse,
  detail?: TruckLaneScheduleResponse | null,
): boolean {
  const st = String(task.status ?? "").toUpperCase();
  if (st !== "PENDING" && st !== "APPLYING") return false;
  const c = task.lineCounts;
  if (c) {
    return c.pending > 0 && c.applied === 0 && c.failed === 0;
  }
  const lines = detail?.lines ?? [];
  if (lines.length > 0) {
    return lines.every((l) => l.lineStatus === "PENDING");
  }
  return true;
}

function scheduleLinesToRequests(
  lines: TruckLaneScheduleLineResponse[],
): TruckLaneScheduleLineRequest[] {
  return lines
    .filter((l) => l.lineStatus !== "APPLIED")
    .map((l) => ({
      action: l.action,
      truckRowId: l.truckRowId,
      toTruckLanceCode: l.toTruckLanceCode,
      toRemark: l.toRemark,
      toStoreId: l.toStoreId,
      toLoadingSequence: l.toLoadingSequence ?? 0,
      toDistrictReference: l.toDistrictReference ?? null,
      shopCode: l.shopCode,
      shopName: l.shopName,
      departureTime: l.departureTime,
    }));
}

function splitExecuteAt(executeAt: string): { date: string; time: string } {
  const raw = executeAt.trim();
  if (!raw) return { date: "-", time: "-" };
  const tIdx = raw.indexOf("T");
  if (tIdx < 0) return { date: raw, time: "" };
  return {
    date: raw.slice(0, tIdx),
    time: raw.slice(tIdx + 1, tIdx + 6),
  };
}

type Props = {
  open: boolean;
  onClose: () => void;
  lanes: ScheduleLaneOption[];
  onAfterChange?: () => void | Promise<void>;
};

const ScheduleTaskHistoryModal: React.FC<Props> = ({
  open,
  onClose,
  lanes,
  onAfterChange,
}) => {
  const { t } = useTranslation("shop");
  const [filter, setFilter] = useState<UiFilter>("all");
  const [loading, setLoading] = useState(false);
  const [tasks, setTasks] = useState<TruckLaneScheduleResponse[]>([]);
  const [expandedId, setExpandedId] = useState<number | null>(null);
  const [detailById, setDetailById] = useState<
    Record<number, TruckLaneScheduleResponse>
  >({});
  const [detailLoadingId, setDetailLoadingId] = useState<number | null>(null);
  const [actionId, setActionId] = useState<number | null>(null);
  const [actionError, setActionError] = useState<string | null>(null);
  const [actionNotice, setActionNotice] = useState<string | null>(null);
  const [redoTarget, setRedoTarget] = useState<TruckLaneScheduleResponse | null>(
    null,
  );
  const [redoDate, setRedoDate] = useState("");
  const [redoTime, setRedoTime] = useState("");
  const [redoSubmitting, setRedoSubmitting] = useState(false);

  const laneById = useMemo(
    () => new Map(lanes.map((l) => [l.id, l])),
    [lanes],
  );

  const loadTasks = useCallback(async () => {
    setLoading(true);
    try {
      const list = await listTruckLaneSchedulesClient(
        ["PENDING", "APPLYING", "APPLIED", "PARTIAL", "FAILED", "CANCELLED", "IGNORED"],
        200,
      );
      const sorted = [...list].sort((a, b) =>
        String(b.created ?? b.executeAt).localeCompare(
          String(a.created ?? a.executeAt),
        ),
      );
      setTasks(sorted);

      // Warm detail cache so badges match expanded view (and line-level errors are available).
      const warmTargets = sorted
        .filter((task) => {
          const st = String(task.status ?? "").toUpperCase();
          if (st === "CANCELLED" || st === "APPLIED" || st === "IGNORED") return false;
          if (task.lineCounts) return false;
          return true;
        })
        .slice(0, 30);
      if (warmTargets.length > 0) {
        const warmed = await Promise.all(
          warmTargets.map((task) =>
            getTruckLaneScheduleClient(task.id).catch(() => null),
          ),
        );
        const next: Record<number, TruckLaneScheduleResponse> = {};
        for (const d of warmed) {
          if (d?.id) next[d.id] = d;
        }
        if (Object.keys(next).length > 0) {
          setDetailById((prev) => ({ ...prev, ...next }));
        }
      }
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    if (!open) return;
    setFilter("all");
    setExpandedId(null);
    setDetailById({});
    setActionError(null);
    setActionNotice(null);
    setRedoTarget(null);
    setRedoDate("");
    setRedoTime("");
    void loadTasks();
  }, [open, loadTasks]);

  const counts = useMemo(() => {
    let pending = 0;
    let success = 0;
    let failed = 0;
    for (const task of tasks) {
      const ui = resolveUiStatus(task, detailById[task.id]);
      if (ui === "pending") pending++;
      else if (ui === "success") success++;
      else if (ui === "failed") failed++;
    }
    return { pending, success, failed, all: tasks.length };
  }, [tasks, detailById]);

  const filteredTasks = useMemo(() => {
    return tasks.filter((task) => {
      const detail = detailById[task.id];
      const ui = resolveUiStatus(task, detail);
      if (filter === "all") return true;
      if (filter === "pending") return ui === "pending";
      if (filter === "success") return ui === "success";
      return ui === "failed";
    });
  }, [tasks, filter, detailById]);

  const invalidateTaskDetail = useCallback((id: number) => {
    setDetailById((prev) => {
      if (!prev[id]) return prev;
      const { [id]: _removed, ...rest } = prev;
      return rest;
    });
  }, []);

  const refreshTaskDetail = useCallback(async (id: number) => {
    setDetailLoadingId(id);
    try {
      const detail = await getTruckLaneScheduleClient(id);
      setDetailById((prev) => ({ ...prev, [id]: detail }));
      return detail;
    } finally {
      setDetailLoadingId(null);
    }
  }, []);

  const ensureDetail = async (id: number) => {
    if (detailById[id]) return detailById[id];
    return refreshTaskDetail(id);
  };

  const reloadAfterMutation = useCallback(
    async (id: number) => {
      invalidateTaskDetail(id);
      await onAfterChange?.();
      await loadTasks();
      if (expandedId === id) {
        await refreshTaskDetail(id);
      }
    },
    [
      expandedId,
      invalidateTaskDetail,
      loadTasks,
      onAfterChange,
      refreshTaskDetail,
    ],
  );

  const toggleExpand = async (id: number) => {
    if (expandedId === id) {
      setExpandedId(null);
      return;
    }
    setExpandedId(id);
    await ensureDetail(id);
  };

  const handleCancel = async (id: number) => {
    setActionId(id);
    setActionError(null);
    try {
      await cancelTruckLaneScheduleClient(id);
      await reloadAfterMutation(id);
    } catch (err: unknown) {
      setActionError(extractApiErrorMessage(err) ?? t("schedule_err_generic"));
    } finally {
      setActionId(null);
    }
  };

  const handleApplyNow = async (id: number) => {
    setActionId(id);
    setActionError(null);
    try {
      await applyNowTruckLaneScheduleClient(id);
      await reloadAfterMutation(id);
    } catch (err: unknown) {
      setActionError(extractApiErrorMessage(err) ?? t("schedule_err_generic"));
    } finally {
      setActionId(null);
    }
  };

  const openRedoDialog = (task: TruckLaneScheduleResponse) => {
    const { executeAt } = resolveRescheduleExecuteAt(task.executeAt);
    const { date, time } = splitExecuteAt(executeAt);
    setRedoTarget(task);
    setRedoDate(date !== "-" ? date : "");
    setRedoTime(time && time !== "-" ? time : "");
    setActionError(null);
  };

  const closeRedoDialog = () => {
    if (redoSubmitting) return;
    setRedoTarget(null);
    setRedoDate("");
    setRedoTime("");
  };

  const handleConfirmRedo = async () => {
    if (!redoTarget) return;
    const executeAt = buildExecuteAtIso(redoDate, redoTime);
    if (!executeAt) {
      setActionError(t("schedule_err_execute_at_past"));
      return;
    }
    if (isExecuteAtTooEarly(executeAt)) {
      setActionError(t("schedule_err_execute_at_past"));
      return;
    }

    setRedoSubmitting(true);
    setActionId(redoTarget.id);
    setActionError(null);
    setActionNotice(null);
    try {
      const updated = await reactivateCancelledTruckLaneScheduleClient(
        redoTarget.id,
        { executeAt },
      );
      setActionNotice(
        t("schedule_reschedule_created", {
          id: updated.id,
          at: formatScheduleDisplayDateTime(executeAt),
        }),
      );
      closeRedoDialog();
      await reloadAfterMutation(redoTarget.id);
    } catch (err: unknown) {
      setActionError(extractApiErrorMessage(err) ?? t("schedule_err_generic"));
    } finally {
      setRedoSubmitting(false);
      setActionId(null);
    }
  };

  const handleReschedule = async (task: TruckLaneScheduleResponse) => {
    if (String(task.status ?? "").toUpperCase() === "PARTIAL") {
      setActionError(t("schedule_retry_rejects_partial"));
      return;
    }
    setActionId(task.id);
    setActionError(null);
    setActionNotice(null);
    try {
      const { executeAt, adjusted } = resolveRescheduleExecuteAt(task.executeAt);
      try {
        await retryFailedTruckLaneScheduleClient(task.id, { executeAt });
      } catch (retryErr: unknown) {
        let detail = detailById[task.id];
        if (!detail?.lines?.length) {
          detail = (await ensureDetail(task.id)) ?? undefined;
        }
        const retryLines = (detail?.lines ?? []).filter(
          (l) => l.lineStatus === "FAILED" || l.lineStatus === "PENDING",
        );
        if (retryLines.length === 0) throw retryErr;
        const lines = scheduleLinesToRequests(retryLines);
        await createTruckLaneScheduleClient({ executeAt, lines });
      }
      if (adjusted) {
        setActionNotice(
          t("schedule_reschedule_time_adjusted", { at: executeAt }),
        );
      }
      await reloadAfterMutation(task.id);
    } catch (err: unknown) {
      setActionError(extractApiErrorMessage(err) ?? t("schedule_err_generic"));
    } finally {
      setActionId(null);
    }
  };

  const handleIgnore = async (id: number) => {
    setActionId(id);
    setActionError(null);
    try {
      await ignoreTruckLaneScheduleClient(id);
      await reloadAfterMutation(id);
    } catch (err: unknown) {
      setActionError(extractApiErrorMessage(err) ?? t("schedule_err_generic"));
    } finally {
      setActionId(null);
    }
  };

  const resolveActionLabel = useCallback(
    (action: string) => {
      switch (action) {
        case "MOVE":
          return t("schedule_action_move");
        case "CREATE":
          return t("schedule_action_create");
        case "DELETE":
          return t("schedule_action_delete");
        case "ENSURE_LANE":
          return t("schedule_action_ensure_lane");
        default:
          return action;
      }
    },
    [t],
  );

  const resolveActionChipColor = useCallback(
    (
      action: string,
    ): "default" | "primary" | "success" | "warning" | "info" | "error" => {
      switch (action) {
        case "MOVE":
          return "primary";
        case "CREATE":
          return "success";
        case "DELETE":
          return "warning";
        case "ENSURE_LANE":
          return "info";
        default:
          return "default";
      }
    },
    [],
  );

  const statusBadge = (
    task: TruckLaneScheduleResponse,
    ui: UiTaskStatus,
  ) => {
    if (ui === "pending") {
      return (
        <Chip
          size="small"
          icon={<Clock size={12} />}
          label={t("schedule_history_status_pending")}
          sx={{
            fontWeight: 700,
            bgcolor: "warning.50",
            color: "warning.dark",
            border: 1,
            borderColor: "warning.200",
            "@keyframes schedulePulse": {
              "0%, 100%": { opacity: 1 },
              "50%": { opacity: 0.65 },
            },
            animation: "schedulePulse 2s ease-in-out infinite",
          }}
        />
      );
    }
    if (ui === "success") {
      return (
        <Chip
          size="small"
          icon={<Check size={12} />}
          label={t("schedule_history_status_success")}
          sx={{
            fontWeight: 700,
            bgcolor: "success.50",
            color: "success.dark",
            border: 1,
            borderColor: "success.200",
          }}
        />
      );
    }
    if (ui === "ignored") {
      return (
        <Chip
          size="small"
          icon={<EyeOff size={12} />}
          label={t("schedule_history_status_ignored")}
          sx={{
            fontWeight: 700,
            bgcolor: "grey.100",
            color: "text.secondary",
            border: 1,
            borderColor: "grey.300",
          }}
        />
      );
    }
    if (ui === "cancelled") {
      return (
        <Chip
          size="small"
          icon={<Ban size={12} />}
          label={t("schedule_history_status_cancelled")}
          sx={{
            fontWeight: 700,
            bgcolor: "grey.100",
            color: "text.secondary",
            border: 1,
            borderColor: "grey.400",
          }}
        />
      );
    }
    return (
      <Chip
        size="small"
        icon={<AlertTriangle size={12} />}
        label={t("schedule_history_status_failed")}
        sx={{
          fontWeight: 700,
          bgcolor: "error.50",
          color: "error.dark",
          border: 1,
          borderColor: "error.200",
        }}
      />
    );
  };

  const filterBtn = (
    key: UiFilter,
    label: string,
    count: number,
    selectedBg?: string,
    selectedColor?: string,
  ) => (
    <Button
      size="small"
      variant={filter === key ? "contained" : "text"}
      onClick={() => setFilter(key)}
      sx={{
        textTransform: "none",
        fontWeight: 700,
        minWidth: 0,
        px: 1.75,
        py: 0.75,
        borderRadius: 1.5,
        boxShadow: filter === key ? 1 : 0,
        ...(filter === key && selectedBg
          ? { bgcolor: selectedBg, color: selectedColor ?? "white", "&:hover": { bgcolor: selectedBg } }
          : { color: "text.secondary" }),
      }}
    >
      {label} ({count})
    </Button>
  );

  return (
    <Dialog
      open={open}
      onClose={onClose}
      maxWidth="lg"
      fullWidth
      keepMounted={false}
      PaperProps={{
        sx: { maxHeight: "95vh", display: "flex", flexDirection: "column" },
      }}
    >
      <DialogTitle
        sx={{
          display: "flex",
          alignItems: "flex-start",
          justifyContent: "space-between",
          gap: 1,
          bgcolor: "grey.50",
          borderBottom: 1,
          borderColor: "divider",
        }}
      >
        <Stack direction="row" spacing={1.5} alignItems="flex-start">
          <Box
            sx={{
              p: 1,
              borderRadius: 1,
              bgcolor: "primary.50",
              color: "primary.main",
              display: "flex",
            }}
          >
            <FileText size={20} />
          </Box>
          <Box>
            <Typography variant="h6" sx={{ fontWeight: 800, lineHeight: 1.2 }}>
              {t("schedule_history_title")}
            </Typography>
            <Typography variant="caption" color="text.secondary">
              {t("schedule_history_subtitle")}
            </Typography>
          </Box>
        </Stack>
        <IconButton size="small" onClick={onClose} aria-label={t("cancel")}>
          <X size={20} />
        </IconButton>
      </DialogTitle>

      <DialogContent
        dividers
        sx={{
          display: "flex",
          flexDirection: "column",
          gap: 2,
          overflow: "hidden",
          flex: 1,
          minHeight: 0,
        }}
      >
        <Box
          sx={{
            display: "flex",
            flexWrap: "wrap",
            gap: 0.5,
            p: 0.5,
            bgcolor: "grey.100",
            borderRadius: 1,
          }}
        >
          {filterBtn("all", t("schedule_history_filter_all"), counts.all)}
          {filterBtn(
            "pending",
            t("schedule_history_filter_pending"),
            counts.pending,
            "warning.main",
          )}
          {filterBtn(
            "success",
            t("schedule_history_filter_success"),
            counts.success,
            "success.main",
          )}
          {filterBtn(
            "failed",
            t("schedule_history_filter_failed"),
            counts.failed,
            "error.main",
          )}
        </Box>

        {actionError && (
          <Alert severity="error" onClose={() => setActionError(null)}>
            {actionError}
          </Alert>
        )}
        {actionNotice && (
          <Alert severity="info" onClose={() => setActionNotice(null)}>
            {actionNotice}
          </Alert>
        )}

        <Box
          sx={{
            flex: 1,
            minHeight: 280,
            overflow: "auto",
            border: 1,
            borderColor: "divider",
            borderRadius: 2,
            bgcolor: "grey.50",
          }}
        >
          {loading ? (
            <Box sx={{ display: "flex", justifyContent: "center", py: 6 }}>
              <CircularProgress />
            </Box>
          ) : filteredTasks.length === 0 ? (
            <Stack alignItems="center" justifyContent="center" sx={{ py: 6 }}>
              <ClipboardList size={40} color="#cbd5e1" />
              <Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>
                {t("schedule_history_empty")}
              </Typography>
            </Stack>
          ) : (
            filteredTasks.map((task) => {
              const expanded = expandedId === task.id;
              const detail = detailById[task.id];
              const ui = resolveUiStatus(task, detail);
              const { date, time } = splitExecuteAt(task.executeAt);
              const lines = detail?.lines ?? [];
              const failedLines = lines.filter((l) => l.lineStatus === "FAILED");
              const appliedLines = lines.filter(
                (l) => l.lineStatus === "APPLIED",
              );
              const busy = actionId === task.id;
              const showPendingActions = canManagePendingSchedule(task, detail);

              return (
                <Box
                  key={task.id}
                  sx={{
                    p: 2,
                    bgcolor: "background.paper",
                    borderBottom: 1,
                    borderColor: "divider",
                    "&:hover": { bgcolor: "action.hover" },
                  }}
                >
                  <Stack
                    direction={{ xs: "column", md: "row" }}
                    spacing={2}
                    justifyContent="space-between"
                    alignItems={{ md: "center" }}
                  >
                    <Box sx={{ flex: 1, minWidth: 0 }}>
                      <Stack
                        direction="row"
                        spacing={1}
                        alignItems="center"
                        flexWrap="wrap"
                        sx={{ mb: 1 }}
                      >
                        <Typography
                          variant="caption"
                          sx={{ fontWeight: 800, color: "text.secondary" }}
                        >
                          #{task.id}
                        </Typography>
                        {statusBadge(task, ui)}
                        {task.created && (
                          <Typography variant="caption" color="text.secondary">
                            {t("schedule_history_created", {
                              at: formatScheduleDisplayDateTime(task.created),
                              by:
                                task.createdBy?.trim() ||
                                task.modifiedBy?.trim() ||
                                t("schedule_history_unknown_user"),
                            })}
                          </Typography>
                        )}
                      </Stack>

                      <Stack
                        direction="row"
                        spacing={1}
                        alignItems="center"
                        flexWrap="wrap"
                        sx={{ mb: 1 }}
                      >
                        <Chip
                          size="small"
                          icon={<Calendar size={12} />}
                          label={`${date} ${time}`}
                          sx={{ fontWeight: 700 }}
                        />
                        {task.lineCounts && (
                          <Typography variant="caption" color="text.secondary">
                            {t("schedule_history_line_counts", {
                              total: task.lineCounts.total,
                              applied: task.lineCounts.applied,
                              failed: task.lineCounts.failed,
                              pending: task.lineCounts.pending,
                            })}
                          </Typography>
                        )}
                      </Stack>

                      {ui === "success" && task.appliedAt && (
                        <Typography
                          variant="caption"
                          sx={{
                            color: "success.main",
                            fontWeight: 700,
                            display: "flex",
                            alignItems: "center",
                            gap: 0.5,
                          }}
                        >
                          <CheckCircle2 size={12} />
                          {t("schedule_history_applied_at", {
                            at: formatScheduleDisplayDateTime(task.appliedAt),
                          })}
                        </Typography>
                      )}

                      <Button
                        size="small"
                        endIcon={
                          expanded ? (
                            <ChevronUp size={14} />
                          ) : (
                            <ChevronDown size={14} />
                          )
                        }
                        onClick={() => void toggleExpand(task.id)}
                        sx={{ mt: 0.5, textTransform: "none", fontWeight: 700 }}
                      >
                        {t("schedule_history_view_lines")}
                      </Button>

                      <Collapse in={expanded}>
                        <Box sx={{ mt: 1.5, pl: 0.5 }}>
                          {detailLoadingId === task.id && !detail ? (
                            <CircularProgress size={20} />
                          ) : lines.length === 0 ? (
                            <Typography variant="caption" color="text.secondary">
                              {t("schedule_history_no_lines")}
                            </Typography>
                          ) : (
                            <Stack spacing={1}>
                              {lines.map((line) => {
                                const shopLabel =
                                  [line.shopCode, line.shopName]
                                    .filter(Boolean)
                                    .join(" — ") ||
                                  (line.truckRowId != null
                                    ? `#${line.truckRowId}`
                                    : resolveActionLabel(line.action));
                                const { headline, details } =
                                  buildScheduleLineDescription(
                                    line,
                                    laneById,
                                    t,
                                  );
                                const lineOk = line.lineStatus === "APPLIED";
                                const linePending =
                                  line.lineStatus === "PENDING" ||
                                  line.lineStatus === "APPLYING";
                                const lineFailed = line.lineStatus === "FAILED";
                                const lineChipColor = lineOk
                                  ? "success"
                                  : linePending
                                    ? "warning"
                                    : lineFailed
                                      ? "error"
                                      : "default";
                                return (
                                  <Box
                                    key={line.id}
                                    sx={{
                                      p: 1,
                                      borderRadius: 1,
                                      border: 1,
                                      borderColor: lineOk
                                        ? "success.200"
                                        : linePending
                                          ? "warning.200"
                                          : lineFailed
                                            ? "error.200"
                                            : "divider",
                                      bgcolor: lineOk
                                        ? "success.50"
                                        : linePending
                                          ? "warning.50"
                                          : lineFailed
                                            ? "error.50"
                                            : "background.paper",
                                    }}
                                  >
                                    <Stack
                                      direction="row"
                                      spacing={0.5}
                                      alignItems="center"
                                      flexWrap="wrap"
                                    >
                                      <Chip
                                        size="small"
                                        label={resolveActionLabel(line.action)}
                                        color={resolveActionChipColor(line.action)}
                                        sx={{
                                          height: 18,
                                          fontSize: "0.65rem",
                                          fontWeight: 700,
                                        }}
                                      />
                                      <Typography
                                        variant="caption"
                                        sx={{ fontWeight: 800 }}
                                      >
                                        {shopLabel}
                                      </Typography>
                                      <Chip
                                        size="small"
                                        label={t(line.lineStatus)}
                                        color={lineChipColor}
                                        sx={{ height: 18, fontSize: "0.65rem" }}
                                      />
                                    </Stack>
                                    <Typography
                                      variant="caption"
                                      sx={{ fontWeight: 700, display: "block", mt: 0.25 }}
                                    >
                                      {headline}
                                      {details.length > 0
                                        ? ` · ${details.join(" · ")}`
                                        : ""}
                                    </Typography>
                                    {line.errorMessage && (
                                      <Typography
                                        variant="caption"
                                        color="error.dark"
                                        display="block"
                                        sx={{ mt: 0.5 }}
                                      >
                                        {line.errorMessage}
                                      </Typography>
                                    )}
                                  </Box>
                                );
                              })}
                            </Stack>
                          )}
                          {!detailLoadingId &&
                            detail &&
                            failedLines.length > 0 && (
                              <Typography
                                variant="caption"
                                color="error.main"
                                sx={{ mt: 1, display: "block", fontWeight: 700 }}
                              >
                                {t("schedule_history_failed_lines", {
                                  count: failedLines.length,
                                })}
                              </Typography>
                            )}
                          {detail && appliedLines.length > 0 && (
                            <Typography
                              variant="caption"
                              color="success.main"
                              sx={{ display: "block", fontWeight: 700 }}
                            >
                              {t("schedule_history_success_lines", {
                                count: appliedLines.length,
                              })}
                            </Typography>
                          )}
                        </Box>
                      </Collapse>
                    </Box>

                    <Stack direction="row" spacing={1} flexShrink={0}>
                      {showPendingActions && (
                        <>
                          <Button
                            size="small"
                            variant="contained"
                            color="success"
                            disabled={busy}
                            startIcon={
                              busy ? (
                                <CircularProgress size={14} color="inherit" />
                              ) : (
                                <Play size={14} />
                              )
                            }
                            onClick={() => void handleApplyNow(task.id)}
                            sx={{ fontWeight: 700 }}
                          >
                            {t("schedule_history_apply_now")}
                          </Button>
                          <Button
                            size="small"
                            variant="outlined"
                            disabled={busy}
                            startIcon={<Ban size={14} />}
                            onClick={() => void handleCancel(task.id)}
                            sx={{ fontWeight: 700 }}
                          >
                            {t("schedule_history_cancel")}
                          </Button>
                        </>
                      )}
                      {ui === "success" && (
                        <Typography
                          variant="caption"
                          color="text.disabled"
                          sx={{ fontStyle: "italic", px: 1 }}
                        >
                          {t("schedule_history_archived")}
                        </Typography>
                      )}
                      {ui === "failed" && (
                        <>
                          <Button
                            size="small"
                            variant="contained"
                            disabled={busy}
                            startIcon={
                              busy ? (
                                <CircularProgress size={14} color="inherit" />
                              ) : (
                                <RotateCcw size={14} />
                              )
                            }
                            onClick={() => void handleReschedule(task)}
                            sx={{ fontWeight: 700 }}
                          >
                            {t("schedule_history_reschedule")}
                          </Button>
                          <Button
                            size="small"
                            variant="outlined"
                            color="inherit"
                            disabled={busy}
                            startIcon={<EyeOff size={14} />}
                            onClick={() => void handleIgnore(task.id)}
                            sx={{ fontWeight: 700 }}
                          >
                            {t("schedule_history_ignore")}
                          </Button>
                          {!showPendingActions && (
                            <Typography
                              variant="caption"
                              color="error.main"
                              sx={{ px: 0.5, fontWeight: 600 }}
                            >
                              {t("schedule_history_needs_attention")}
                            </Typography>
                          )}
                        </>
                      )}
                      {ui === "ignored" && (
                        <Typography
                          variant="caption"
                          color="text.disabled"
                          sx={{ fontStyle: "italic", px: 1 }}
                        >
                          {t("schedule_history_status_ignored")}
                        </Typography>
                      )}
                      {ui === "cancelled" && (
                        <Button
                          size="small"
                          variant="contained"
                          disabled={busy}
                          startIcon={
                            busy ? (
                              <CircularProgress size={14} color="inherit" />
                            ) : (
                              <RotateCcw size={14} />
                            )
                          }
                          onClick={() => openRedoDialog(task)}
                          sx={{ fontWeight: 700 }}
                        >
                          {t("schedule_history_reschedule")}
                        </Button>
                      )}
                    </Stack>
                  </Stack>
                </Box>
              );
            })
          )}
        </Box>
      </DialogContent>

      <DialogActions sx={{ px: 2, py: 1.5, bgcolor: "grey.50" }}>
        <Button
          size="small"
          onClick={() => void loadTasks()}
          disabled={loading}
          sx={{ mr: "auto" }}
        >
          {t("btn_refresh")}
        </Button>
        <Button variant="contained" onClick={onClose} sx={{ fontWeight: 700 }}>
          {t("schedule_history_close")}
        </Button>
      </DialogActions>

      <Dialog
        open={redoTarget != null}
        onClose={closeRedoDialog}
        maxWidth="xs"
        fullWidth
      >
        <DialogTitle sx={{ fontWeight: 800 }}>
          {t("schedule_reschedule_dialog_title")}
        </DialogTitle>
        <DialogContent>
          <Stack direction={{ xs: "column", sm: "row" }} spacing={2}>
            <TextField
              label={t("schedule_exec_date")}
              type="date"
              size="small"
              fullWidth
              value={redoDate}
              onChange={(e) => setRedoDate(e.target.value)}
              InputLabelProps={{ shrink: true }}
            />
            <TextField
              label={t("schedule_exec_time")}
              type="time"
              size="small"
              fullWidth
              value={redoTime}
              onChange={(e) => setRedoTime(e.target.value)}
              InputLabelProps={{ shrink: true }}
            />
          </Stack>
        </DialogContent>
        <DialogActions sx={{ px: 2, pb: 2 }}>
          <Button onClick={closeRedoDialog} disabled={redoSubmitting}>
            {t("cancel")}
          </Button>
          <Button
            variant="contained"
            disabled={
              redoSubmitting || !redoDate.trim() || !redoTime.trim()
            }
            onClick={() => void handleConfirmRedo()}
            sx={{ fontWeight: 700 }}
          >
            {redoSubmitting ? (
              <CircularProgress size={18} color="inherit" />
            ) : (
              t("schedule_reschedule_dialog_confirm")
            )}
          </Button>
        </DialogActions>
      </Dialog>
    </Dialog>
  );
};

export default memo(ScheduleTaskHistoryModal);
