"use client";

import React, { useCallback, useEffect, useRef, useState } from "react";
import {
  Alert,
  Box,
  Button,
  Chip,
  CircularProgress,
  Collapse,
  FormControl,
  FormControlLabel,
  Checkbox,
  InputLabel,
  MenuItem,
  Select,
  Tab,
  Tabs,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Typography,
} from "@mui/material";
import ExpandLess from "@mui/icons-material/ExpandLess";
import ExpandMore from "@mui/icons-material/ExpandMore";
import Refresh from "@mui/icons-material/Refresh";
import Search from "@mui/icons-material/Search";
import PageTitleBar from "@/components/PageTitleBar";
import { NEXT_PUBLIC_API_URL } from "@/config/api";
import { clientAuthFetch } from "@/app/utils/clientAuthFetch";
import {
  arrayToDateTimeString,
  OUTPUT_DATE_FORMAT,
  OUTPUT_TIME_FORMAT,
} from "@/app/utils/formatUtil";
import dayjs, { type Dayjs } from "dayjs";
import "dayjs/locale/zh-hk";
import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";

function formatApiDateTime(value: unknown): string {
  if (value == null) return "—";
  if (Array.isArray(value)) {
    return arrayToDateTimeString(value as (number | undefined)[]);
  }
  const d = dayjs(value as string | number);
  return d.isValid() ? d.format("YYYY-MM-DD HH:mm:ss") : "—";
}
import PrinterMonitorTab from "@/components/ClientMonitor/PrinterMonitorTab";
import LabelPrinterMonitorPanel from "@/components/ClientMonitor/LabelPrinterMonitorPanel";
import DeviceConnectivityHistoryChart from "@/components/ClientMonitor/DeviceConnectivityHistoryChart";
import {
  extractDeviceUniqueSuffix,
  formatClientIpDisplay,
  formatDeviceDisplayLabel,
} from "@/lib/devicePresence";

type ClientRow = {
  deviceId: string;
  username?: string;
  displayName?: string;
  currentPath?: string;
  clientType?: string;
  clientIp?: string;
  rttMs?: number;
  connectionQuality?: string;
  navigatorOnline?: boolean | number;
  lastHeartbeat?: string;
  lastActivity?: string;
  status: "online" | "idle" | "offline" | "poor";
  secondsSinceHeartbeat?: number;
};

type HistoryRow = {
  id?: number;
  deviceId: string;
  username?: string;
  displayName?: string;
  clientType?: string;
  clientIp?: string;
  status: string;
  rttMs?: number;
  currentPath?: string;
  recordedAt?: string;
};

type Summary = {
  total: number;
  offline: number;
  poor: number;
  online: number;
  idle: number;
};

type HistorySummary = {
  total: number;
  offline: number;
  poor: number;
  deviceCount: number;
};

type PrinterHistoryRow = {
  id?: number;
  printerId: number;
  printerCode?: string;
  printerName?: string;
  printerType?: string;
  brand?: string;
  ip?: string;
  port?: number;
  errorMessage?: string;
  recordedAt?: unknown;
};

type PrinterHistorySummary = {
  total: number;
};

const STATUS_LABEL: Record<string, { label: string; color: "success" | "warning" | "error" | "default" }> = {
  online: { label: "在線", color: "success" },
  idle: { label: "閒置", color: "warning" },
  poor: { label: "連線差", color: "warning" },
  offline: { label: "離線", color: "error" },
};

const CLIENT_TYPE_LABEL: Record<string, string> = {
  tablet: "平板",
  desktop: "電腦",
  mobile: "手機",
  unknown: "未知",
};

function formatAgo(seconds?: number): string {
  if (seconds == null) return "—";
  if (seconds < 60) return `${seconds} 秒前`;
  if (seconds < 3600) return `${Math.floor(seconds / 60)} 分鐘前`;
  return `${Math.floor(seconds / 3600)} 小時前`;
}

const HISTORY_DATETIME_FORMAT = `${OUTPUT_DATE_FORMAT} ${OUTPUT_TIME_FORMAT}`;

function toApiDateTime(value: Dayjs | null): string {
  if (value == null || !value.isValid()) return "";
  return value.format("YYYY-MM-DDTHH:mm:ss");
}

function defaultHistoryFrom(): Dayjs {
  return dayjs().subtract(6, "day").startOf("day");
}

function defaultHistoryTo(): Dayjs {
  return dayjs();
}

export default function ClientMonitorPage() {
  const [tab, setTab] = useState<"live" | "history" | "printers">("live");
  const [printerRefreshAt, setPrinterRefreshAt] = useState(0);

  const [clientTypeFilter, setClientTypeFilter] = useState<string>("all");
  const [rows, setRows] = useState<ClientRow[]>([]);
  const [summary, setSummary] = useState<Summary | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const fetchInFlightRef = useRef(false);

  const [historyFrom, setHistoryFrom] = useState(defaultHistoryFrom);
  const [historyTo, setHistoryTo] = useState(defaultHistoryTo);
  const [historyClientType, setHistoryClientType] = useState("all");
  const [historyIncludeOffline, setHistoryIncludeOffline] = useState(true);
  const [historyIncludePoor, setHistoryIncludePoor] = useState(true);
  const [historyIncludePrinter, setHistoryIncludePrinter] = useState(true);
  const [historyRows, setHistoryRows] = useState<HistoryRow[]>([]);
  const [historySummary, setHistorySummary] = useState<HistorySummary | null>(null);
  const [printerHistoryRows, setPrinterHistoryRows] = useState<PrinterHistoryRow[]>([]);
  const [printerHistorySummary, setPrinterHistorySummary] =
    useState<PrinterHistorySummary | null>(null);
  const [historyLoading, setHistoryLoading] = useState(false);
  const [historyError, setHistoryError] = useState<string | null>(null);
  const [historyQueried, setHistoryQueried] = useState(false);
  const [historyDefinitionsOpen, setHistoryDefinitionsOpen] = useState(false);
  const historyFetchInFlightRef = useRef(false);

  const fetchClients = useCallback(async () => {
    if (fetchInFlightRef.current) return;
    fetchInFlightRef.current = true;
    setLoading(true);
    setError(null);
    try {
      const params = new URLSearchParams();
      if (clientTypeFilter && clientTypeFilter !== "all") {
        params.set("clientType", clientTypeFilter);
      }
      const qs = params.toString();
      const response = await clientAuthFetch(
        `${NEXT_PUBLIC_API_URL}/device-presence/active${qs ? `?${qs}` : ""}`,
        { method: "GET", cache: "no-store" }
      );
      if (response.status === 401 || response.status === 403) return;
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }
      const data = await response.json();
      setRows(Array.isArray(data.clients) ? data.clients : []);
      setSummary(data.summary ?? null);
    } catch (e) {
      console.error("client monitor fetch", e);
      setError("無法載入裝置狀態");
    } finally {
      setLoading(false);
      fetchInFlightRef.current = false;
    }
  }, [clientTypeFilter]);

  const fetchHistory = useCallback(async () => {
    if (historyFetchInFlightRef.current) return;
    const from = toApiDateTime(historyFrom);
    const to = toApiDateTime(historyTo);
    if (!from || !to) {
      setHistoryError("請選擇開始與結束時間");
      return;
    }
    const fetchDevice = historyIncludeOffline || historyIncludePoor;
    if (!fetchDevice && !historyIncludePrinter) {
      setHistoryError("請至少勾選「裝置」或「印表機離線」記錄");
      return;
    }

    historyFetchInFlightRef.current = true;
    setHistoryLoading(true);
    setHistoryError(null);
    try {
      const devicePromise = fetchDevice
        ? (async () => {
            const statuses: string[] = [];
            if (historyIncludeOffline) statuses.push("offline");
            if (historyIncludePoor) statuses.push("poor");
            const params = new URLSearchParams({
              fromDateTime: from,
              toDateTime: to,
              status: statuses.join(","),
            });
            if (historyClientType && historyClientType !== "all") {
              params.set("clientType", historyClientType);
            }
            const response = await clientAuthFetch(
              `${NEXT_PUBLIC_API_URL}/device-presence/history?${params.toString()}`,
              { method: "GET", cache: "no-store" }
            );
            if (response.status === 401 || response.status === 403) return null;
            if (!response.ok) {
              const body = await response.json().catch(() => ({}));
              throw new Error(body?.error ?? `HTTP ${response.status}`);
            }
            return response.json();
          })()
        : Promise.resolve(null);

      const printerPromise = historyIncludePrinter
        ? (async () => {
            const params = new URLSearchParams({
              fromDateTime: from,
              toDateTime: to,
            });
            const response = await clientAuthFetch(
              `${NEXT_PUBLIC_API_URL}/printer-monitor/history?${params.toString()}`,
              { method: "GET", cache: "no-store" }
            );
            if (response.status === 401 || response.status === 403) return null;
            if (!response.ok) {
              const body = await response.json().catch(() => ({}));
              throw new Error(body?.error ?? `HTTP ${response.status}`);
            }
            return response.json();
          })()
        : Promise.resolve(null);

      const [deviceData, printerData] = await Promise.all([
        devicePromise,
        printerPromise,
      ]);

      if (fetchDevice) {
        setHistoryRows(
          Array.isArray(deviceData?.events) ? deviceData.events : []
        );
        setHistorySummary(deviceData?.summary ?? null);
      } else {
        setHistoryRows([]);
        setHistorySummary(null);
      }

      if (historyIncludePrinter) {
        setPrinterHistoryRows(
          Array.isArray(printerData?.events) ? printerData.events : []
        );
        setPrinterHistorySummary(printerData?.summary ?? null);
      } else {
        setPrinterHistoryRows([]);
        setPrinterHistorySummary(null);
      }
      setHistoryQueried(true);
    } catch (e) {
      console.error("client monitor history", e);
      setHistoryError(e instanceof Error ? e.message : "無法載入歷史記錄");
      setHistoryRows([]);
      setHistorySummary(null);
      setPrinterHistoryRows([]);
      setPrinterHistorySummary(null);
    } finally {
      setHistoryLoading(false);
      historyFetchInFlightRef.current = false;
    }
  }, [
    historyFrom,
    historyTo,
    historyClientType,
    historyIncludeOffline,
    historyIncludePoor,
    historyIncludePrinter,
  ]);

  const printerChartEvents = printerHistoryRows.map((row) => ({
    deviceId: `printer-${row.printerId}`,
    status: "offline",
    recordedAt: row.recordedAt,
  }));

  useEffect(() => {
    if (tab !== "live") return;
    void fetchClients();
    const id = window.setInterval(() => void fetchClients(), 10_000);
    return () => window.clearInterval(id);
  }, [fetchClients, tab]);

  useEffect(() => {
    if (tab !== "history") return;
    void fetchHistory();
    // Auto-load when opening the history tab; filter changes use the 查詢 button.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [tab]);

  const offlineCount = summary?.offline ?? 0;

  return (
    <div className="space-y-4">
      <PageTitleBar
        title="裝置連線監控"
        actions={
          tab === "live" ? (
            <button
              type="button"
              onClick={() => void fetchClients()}
              disabled={loading}
              className="inline-flex items-center gap-2 rounded-lg border border-slate-300 bg-white px-4 py-2 text-sm font-medium text-slate-700 shadow-sm hover:bg-slate-50 disabled:opacity-50 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-200"
            >
              {loading ? (
                <CircularProgress size={16} />
              ) : (
                <Refresh sx={{ fontSize: 18 }} />
              )}
              重新整理
            </button>
          ) : tab === "history" ? (
            <button
              type="button"
              onClick={() => void fetchHistory()}
              disabled={historyLoading}
              className="inline-flex items-center gap-2 rounded-lg border border-slate-300 bg-white px-4 py-2 text-sm font-medium text-slate-700 shadow-sm hover:bg-slate-50 disabled:opacity-50 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-200"
            >
              {historyLoading ? (
                <CircularProgress size={16} />
              ) : (
                <Search sx={{ fontSize: 18 }} />
              )}
              查詢
            </button>
          ) : (
            <button
              type="button"
              onClick={() => setPrinterRefreshAt(Date.now())}
              className="inline-flex items-center gap-2 rounded-lg border border-slate-300 bg-white px-4 py-2 text-sm font-medium text-slate-700 shadow-sm hover:bg-slate-50 disabled:opacity-50 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-200"
            >
              <Refresh sx={{ fontSize: 18 }} />
              立即檢查
            </button>
          )
        }
      />

      <Tabs
        value={tab}
        onChange={(_, v: "live" | "history" | "printers") => setTab(v)}
        sx={{ borderBottom: 1, borderColor: "divider" }}
      >
        <Tab label="即時狀態" value="live" />
        <Tab label="歷史記錄" value="history" />
        <Tab label="印表機" value="printers" />
      </Tabs>

      {tab === "live" && (
        <>
          <Typography variant="body2" color="text.secondary">
            顯示最近 7 天內有心跳的裝置（平板、電腦等）。超過約 90 秒無心跳視為離線；超過 5
            分鐘無頁面活動視為閒置。長期離線的舊紀錄會自動隱藏並清除。每 10 秒自動更新。
          </Typography>

          {offlineCount > 0 && (
            <Alert severity="warning">
              有 {offlineCount} 台裝置可能已斷線或關閉應用，請檢查倉庫平板/網路。
            </Alert>
          )}

          <Box className="flex flex-wrap items-center gap-4">
            <FormControl size="small" sx={{ minWidth: 160 }}>
              <InputLabel id="client-type-filter">裝置類型</InputLabel>
              <Select
                labelId="client-type-filter"
                label="裝置類型"
                value={clientTypeFilter}
                onChange={(e) => setClientTypeFilter(e.target.value)}
              >
                <MenuItem value="all">全部</MenuItem>
                <MenuItem value="tablet">平板</MenuItem>
                <MenuItem value="desktop">電腦</MenuItem>
                <MenuItem value="mobile">手機</MenuItem>
              </Select>
            </FormControl>
            {summary && (
              <Box className="flex flex-wrap gap-2">
                <Chip size="small" label={`總數 ${summary.total}`} />
                <Chip size="small" color="success" label={`在線 ${summary.online}`} />
                <Chip size="small" color="warning" label={`閒置 ${summary.idle}`} />
                <Chip size="small" color="warning" label={`連線差 ${summary.poor}`} />
                <Chip size="small" color="error" label={`離線 ${summary.offline}`} />
              </Box>
            )}
          </Box>

          {error && <Alert severity="error">{error}</Alert>}

          <TableContainer className="rounded-lg border border-slate-200 bg-white dark:border-slate-700 dark:bg-slate-800">
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell>狀態</TableCell>
                  <TableCell>裝置</TableCell>
                  <TableCell>類型</TableCell>
              <TableCell>帳號</TableCell>
              <TableCell>IP</TableCell>
              <TableCell>目前頁面</TableCell>
              <TableCell align="right">RTT (ms)</TableCell>
                  <TableCell>最後心跳</TableCell>
                  <TableCell>最後活動</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {loading && rows.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={9} align="center" sx={{ py: 4 }}>
                      <CircularProgress size={28} />
                    </TableCell>
                  </TableRow>
                ) : rows.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={9} align="center" sx={{ py: 4 }}>
                      目前沒有活躍裝置
                    </TableCell>
                  </TableRow>
                ) : (
                  rows.map((row) => {
                    const st = STATUS_LABEL[row.status] ?? STATUS_LABEL.offline;
                    return (
                      <TableRow key={row.deviceId} hover>
                        <TableCell>
                          <Chip size="small" color={st.color} label={st.label} />
                        </TableCell>
                        <TableCell>
                          <Typography variant="body2" fontWeight={600} title={row.deviceId}>
                            {formatDeviceDisplayLabel(row)}
                          </Typography>
                          <Typography variant="caption" color="text.secondary" title={row.deviceId}>
                            #{extractDeviceUniqueSuffix(row.deviceId)}
                          </Typography>
                        </TableCell>
                        <TableCell>
                          {CLIENT_TYPE_LABEL[row.clientType ?? ""] ??
                            row.clientType ??
                            "—"}
                        </TableCell>
                    <TableCell>{row.username ?? "—"}</TableCell>
                    <TableCell>
                      <Typography variant="body2" noWrap title={row.clientIp}>
                        {formatClientIpDisplay(row.clientIp)}
                      </Typography>
                    </TableCell>
                    <TableCell sx={{ maxWidth: 280 }}>
                      <Typography variant="body2" noWrap title={row.currentPath}>
                        {row.currentPath ?? "—"}
                      </Typography>
                    </TableCell>
                    <TableCell align="right">
                      {row.rttMs != null ? row.rttMs : "—"}
                    </TableCell>
                    <TableCell>
                      {formatAgo(row.secondsSinceHeartbeat)}
                      {row.lastHeartbeat && (
                        <Typography variant="caption" display="block" color="text.secondary">
                          {formatApiDateTime(row.lastHeartbeat).slice(11)}
                        </Typography>
                      )}
                        </TableCell>
                    <TableCell>
                      {row.lastActivity
                        ? formatApiDateTime(row.lastActivity).slice(11)
                        : "—"}
                    </TableCell>
                      </TableRow>
                    );
                  })
                )}
              </TableBody>
            </Table>
          </TableContainer>
        </>
      )}

      {tab === "printers" && (
        <>
          <PrinterMonitorTab
            active={tab === "printers"}
            refreshAt={printerRefreshAt}
          />
          <LabelPrinterMonitorPanel
            active={tab === "printers"}
            refreshAt={printerRefreshAt}
          />
        </>
      )}

      {tab === "history" && (
        <>
          <Typography variant="body2" color="text.secondary" sx={{ mb: 1 }}>
            查詢指定時間範圍內的<strong>裝置</strong>（平板／電腦）與<strong>印表機</strong>異常記錄（最長
            30 天）。僅記錄<strong>離線</strong>與<strong>連線差</strong>事件；在線或閒置不會出現在此。切換到此分頁會自動查詢最近
            7 天。
          </Typography>

          <Button
            size="small"
            color="info"
            onClick={() => setHistoryDefinitionsOpen((open) => !open)}
            endIcon={historyDefinitionsOpen ? <ExpandLess /> : <ExpandMore />}
            sx={{ mb: historyDefinitionsOpen ? 1 : 0, textTransform: "none", px: 0 }}
          >
            {historyDefinitionsOpen ? "收起狀態定義說明" : "查看狀態定義說明（離線／連線差／印表機）"}
          </Button>
          <Collapse in={historyDefinitionsOpen}>
            <Alert severity="info" sx={{ alignItems: "flex-start", mb: 1 }}>
            <Box component="div" sx={{ "& ul": { m: 0, pl: 2.5 }, "& li": { mb: 0.75 } }}>
              <Typography variant="subtitle2" fontWeight={600} gutterBottom>
                裝置（平板／電腦，約每 30 秒檢測）
              </Typography>
              <ul>
                <li>
                  <strong>離線</strong>：超過約 <strong>90 秒</strong>沒有收到心跳（關閉分頁、關機、斷網太久，或應用被關閉）。
                </li>
                <li>
                  <strong>連線差</strong>：仍有心跳，但符合以下<strong>任一</strong>情況：
                  <ul style={{ marginTop: 4 }}>
                    <li>
                      瀏覽器回報<strong>目前無網路</strong>（<code>navigator.onLine</code> 為 false，例如 Wi‑Fi 已斷但分頁尚未關閉）
                    </li>
                    <li>
                      至伺服器的往返時間 <strong>RTT ≥ 3 秒</strong>（ping API 過慢）
                    </li>
                    <li>
                      <strong>無法完成 ping</strong>（請求失敗或逾時，RTT 欄可能為「—」）
                    </li>
                  </ul>
                </li>
              </ul>
              <Typography variant="subtitle2" fontWeight={600} gutterBottom sx={{ mt: 1.5 }}>
                印表機（約每 2 分鐘掃描「設定」中的印表機 IP:Port）
              </Typography>
              <ul>
                <li>
                  <strong>離線／無法連線</strong>：伺服器無法在約 <strong>3 秒</strong>內以 TCP
                  連上該印表機的 IP 與 Port（預設 9100）；持續離線時約每{" "}
                  <strong>5 分鐘</strong>記錄一次。
                </li>
              </ul>
              <Typography variant="caption" color="text.secondary" display="block" sx={{ mt: 1 }}>
                裝置「連線差」為網路慢或不穩但仍有心跳；「離線」為長時間無心跳。印表機記錄僅包含無法連線事件，與即時「印表機」分頁的警告清單相同來源。
              </Typography>
            </Box>
          </Alert>
          </Collapse>

          <LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale="zh-hk">
            <Box className="flex flex-wrap items-end gap-4">
              <DateTimePicker
                label="開始時間"
                views={["year", "month", "day", "hours", "minutes", "seconds"]}
                format={HISTORY_DATETIME_FORMAT}
                value={historyFrom}
                onChange={(value) => {
                  if (value?.isValid()) setHistoryFrom(value);
                }}
                slotProps={{
                  textField: { size: "small", sx: { minWidth: 220 } },
                }}
              />
              <DateTimePicker
                label="結束時間"
                views={["year", "month", "day", "hours", "minutes", "seconds"]}
                format={HISTORY_DATETIME_FORMAT}
                value={historyTo}
                onChange={(value) => {
                  if (value?.isValid()) setHistoryTo(value);
                }}
                slotProps={{
                  textField: { size: "small", sx: { minWidth: 220 } },
                }}
              />
            <FormControl size="small" sx={{ minWidth: 160 }}>
              <InputLabel id="history-client-type">裝置類型</InputLabel>
              <Select
                labelId="history-client-type"
                label="裝置類型"
                value={historyClientType}
                onChange={(e) => setHistoryClientType(e.target.value)}
              >
                <MenuItem value="all">全部</MenuItem>
                <MenuItem value="tablet">平板</MenuItem>
                <MenuItem value="desktop">電腦</MenuItem>
                <MenuItem value="mobile">手機</MenuItem>
              </Select>
            </FormControl>
            <Box className="flex flex-col gap-0.5">
              <FormControlLabel
                control={
                  <Checkbox
                    size="small"
                    checked={historyIncludeOffline}
                    onChange={(e) => setHistoryIncludeOffline(e.target.checked)}
                  />
                }
                label="離線"
              />
              <FormControlLabel
                control={
                  <Checkbox
                    size="small"
                    checked={historyIncludePoor}
                    onChange={(e) => setHistoryIncludePoor(e.target.checked)}
                  />
                }
                label="連線差"
              />
              <FormControlLabel
                control={
                  <Checkbox
                    size="small"
                    checked={historyIncludePrinter}
                    onChange={(e) => setHistoryIncludePrinter(e.target.checked)}
                  />
                }
                label="印表機離線"
              />
            </Box>
            </Box>
          </LocalizationProvider>

          {(historySummary || printerHistorySummary) && (
            <Box className="flex flex-wrap gap-2">
              {historySummary && (
                <>
                  <Chip size="small" variant="outlined" label="裝置" />
                  <Chip size="small" label={`事件 ${historySummary.total}`} />
                  <Chip size="small" color="error" label={`離線 ${historySummary.offline}`} />
                  <Chip size="small" color="warning" label={`連線差 ${historySummary.poor}`} />
                  <Chip size="small" label={`裝置數 ${historySummary.deviceCount}`} />
                </>
              )}
              {printerHistorySummary && (
                <>
                  <Chip size="small" variant="outlined" label="印表機" />
                  <Chip
                    size="small"
                    color="error"
                    label={`離線記錄 ${printerHistorySummary.total}`}
                  />
                </>
              )}
            </Box>
          )}

          {historyError && <Alert severity="error">{historyError}</Alert>}

          {(historyIncludeOffline || historyIncludePoor) && (
            <>
              <Typography variant="subtitle1" fontWeight={600} sx={{ mt: 1 }}>
                裝置記錄
              </Typography>
              <DeviceConnectivityHistoryChart
                events={historyRows}
                fromLocal={historyFrom.format("YYYY-MM-DDTHH:mm:ss")}
                toLocal={historyTo.format("YYYY-MM-DDTHH:mm:ss")}
                queried={historyQueried && !historyLoading}
              />
            </>
          )}

          {(historyIncludeOffline || historyIncludePoor) && (
          <TableContainer className="rounded-lg border border-slate-200 bg-white dark:border-slate-700 dark:bg-slate-800">
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell>時間</TableCell>
                  <TableCell>狀態</TableCell>
                  <TableCell>裝置</TableCell>
                  <TableCell>類型</TableCell>
                  <TableCell>帳號</TableCell>
                  <TableCell>IP</TableCell>
                  <TableCell>頁面</TableCell>
                  <TableCell align="right">RTT (ms)</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {historyLoading &&
                historyRows.length === 0 &&
                printerHistoryRows.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={8} align="center" sx={{ py: 4 }}>
                      <CircularProgress size={28} />
                    </TableCell>
                  </TableRow>
                ) : historyRows.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={8} align="center" sx={{ py: 4 }}>
                      此時間範圍內沒有裝置離線或連線差記錄
                    </TableCell>
                  </TableRow>
                ) : (
                  historyRows.map((row) => {
                    const st = STATUS_LABEL[row.status] ?? STATUS_LABEL.offline;
                    return (
                      <TableRow key={`${row.id ?? row.recordedAt}-${row.deviceId}`} hover>
                        <TableCell>{formatApiDateTime(row.recordedAt)}</TableCell>
                        <TableCell>
                          <Chip size="small" color={st.color} label={st.label} />
                        </TableCell>
                        <TableCell>
                          <Typography variant="body2" fontWeight={600} title={row.deviceId}>
                            {formatDeviceDisplayLabel(row)}
                          </Typography>
                          <Typography variant="caption" color="text.secondary" title={row.deviceId}>
                            #{extractDeviceUniqueSuffix(row.deviceId)}
                          </Typography>
                        </TableCell>
                        <TableCell>
                          {CLIENT_TYPE_LABEL[row.clientType ?? ""] ??
                            row.clientType ??
                            "—"}
                        </TableCell>
                        <TableCell>{row.username ?? "—"}</TableCell>
                        <TableCell>{formatClientIpDisplay(row.clientIp)}</TableCell>
                        <TableCell sx={{ maxWidth: 240 }}>
                          <Typography variant="body2" noWrap title={row.currentPath}>
                            {row.currentPath ?? "—"}
                          </Typography>
                        </TableCell>
                        <TableCell align="right">
                          {row.rttMs != null ? row.rttMs : "—"}
                        </TableCell>
                      </TableRow>
                    );
                  })
                )}
              </TableBody>
            </Table>
          </TableContainer>
          )}

          {historyIncludePrinter && (
            <>
              <Typography variant="subtitle1" fontWeight={600} sx={{ mt: 3 }}>
                印表機離線記錄
              </Typography>
              <DeviceConnectivityHistoryChart
                events={printerChartEvents}
                fromLocal={historyFrom.format("YYYY-MM-DDTHH:mm:ss")}
                toLocal={historyTo.format("YYYY-MM-DDTHH:mm:ss")}
                title="印表機離線狀況圖"
                variant="printer"
                queried={historyQueried && !historyLoading}
              />
              <TableContainer className="rounded-lg border border-slate-200 bg-white dark:border-slate-700 dark:bg-slate-800">
                <Table size="small">
                  <TableHead>
                    <TableRow>
                      <TableCell>時間</TableCell>
                      <TableCell>印表機</TableCell>
                      <TableCell>類型</TableCell>
                      <TableCell>IP:Port</TableCell>
                      <TableCell>錯誤</TableCell>
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    {historyLoading && printerHistoryRows.length === 0 ? (
                      <TableRow>
                        <TableCell colSpan={5} align="center" sx={{ py: 4 }}>
                          <CircularProgress size={28} />
                        </TableCell>
                      </TableRow>
                    ) : printerHistoryRows.length === 0 ? (
                      <TableRow>
                        <TableCell colSpan={5} align="center" sx={{ py: 4 }}>
                          此時間範圍內沒有印表機離線記錄
                        </TableCell>
                      </TableRow>
                    ) : (
                      printerHistoryRows.map((row) => (
                        <TableRow
                          key={`${row.id ?? row.recordedAt}-printer-${row.printerId}`}
                          hover
                        >
                          <TableCell>
                            {formatApiDateTime(row.recordedAt)}
                          </TableCell>
                          <TableCell>
                            <Typography variant="body2" fontWeight={600}>
                              {row.printerName || row.printerCode || `#${row.printerId}`}
                            </Typography>
                            {row.printerCode && row.printerName && (
                              <Typography variant="caption" color="text.secondary">
                                {row.printerCode}
                              </Typography>
                            )}
                          </TableCell>
                          <TableCell>
                            {[row.printerType, row.brand].filter(Boolean).join(" / ") ||
                              "—"}
                          </TableCell>
                          <TableCell>
                            {row.ip ? `${row.ip}:${row.port ?? 9100}` : "—"}
                          </TableCell>
                          <TableCell>
                            <Typography variant="body2" color="error.main">
                              {row.errorMessage ?? "無法連線"}
                            </Typography>
                          </TableCell>
                        </TableRow>
                      ))
                    )}
                  </TableBody>
                </Table>
              </TableContainer>
            </>
          )}
        </>
      )}
    </div>
  );
}
