"use client";

import React, { useCallback, useEffect, useRef, useState } from "react";
import {
  Alert,
  Box,
  Button,
  Chip,
  CircularProgress,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Tooltip,
  Typography,
} from "@mui/material";
import InfoOutlined from "@mui/icons-material/InfoOutlined";
import Search from "@mui/icons-material/Search";
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") : "—";
}

type LabelPrinterRow = {
  id: number;
  code?: string;
  name?: string;
  type?: string;
  brand?: string;
  ip?: string;
  port?: number;
  status: "online" | "offline" | "unconfigured" | "unchecked";
  latencyMs?: number;
  errorMessage?: string;
  odometerTotal?: number | null;
  deltaSincePrevious?: number | null;
  hostStatusSnippet?: string;
  zebraOdometerEnabled?: boolean;
  lastCheckAt?: string;
};

type LabelPrinterSummary = {
  total: number;
  online: number;
  offline: number;
  unconfigured: number;
  unchecked: number;
};

type OdometerPrinterRow = {
  printerId: number;
  code?: string;
  name?: string;
  brand?: string;
  startAt?: string | null;
  startOdometer?: number | null;
  endAt?: string | null;
  endOdometer?: number | null;
  delta?: number | null;
};

type OdometerStats = {
  from?: string;
  to?: string;
  printers?: OdometerPrinterRow[];
};

const STATS_DATETIME_FORMAT = `${OUTPUT_DATE_FORMAT} ${OUTPUT_TIME_FORMAT}`;
const STATS_MAX_RANGE_DAYS = 30;

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

function defaultStatsFrom(): Dayjs {
  return dayjs().startOf("day");
}

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

const STATUS_LABEL: Record<
  string,
  { label: string; color: "success" | "warning" | "error" | "default" }
> = {
  online: { label: "連線正常", color: "success" },
  offline: { label: "離線", color: "error" },
  unconfigured: { label: "未設定 IP", color: "warning" },
  unchecked: { label: "未檢查", color: "default" },
};

type Props = {
  active: boolean;
  refreshAt?: number;
};

export default function LabelPrinterMonitorPanel({
  active,
  refreshAt = 0,
}: Props) {
  const [printers, setPrinters] = useState<LabelPrinterRow[]>([]);
  const [summary, setSummary] = useState<LabelPrinterSummary | null>(null);
  const [odometerStats, setOdometerStats] = useState<OdometerStats | null>(
    null,
  );
  const [statsFrom, setStatsFrom] = useState(defaultStatsFrom);
  const [statsTo, setStatsTo] = useState(defaultStatsTo);
  const [loading, setLoading] = useState(false);
  const [statsLoading, setStatsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [statsError, setStatsError] = useState<string | null>(null);
  const checkInFlightRef = useRef(false);
  const statsInFlightRef = useRef(false);

  const fetchOdometerStats = useCallback(async (from: Dayjs, to: Dayjs) => {
    if (statsInFlightRef.current) return;
    const fromApi = toApiDateTime(from);
    const toApi = toApiDateTime(to);
    if (!fromApi || !toApi) {
      setStatsError("請選擇開始與結束時間");
      return;
    }
    if (from.isAfter(to)) {
      setStatsError("開始時間必須早於結束時間");
      return;
    }
    if (to.diff(from, "day") > STATS_MAX_RANGE_DAYS) {
      setStatsError(`查詢區間不可超過 ${STATS_MAX_RANGE_DAYS} 天`);
      return;
    }

    statsInFlightRef.current = true;
    setStatsLoading(true);
    setStatsError(null);
    try {
      const statsRes = await clientAuthFetch(
        `${NEXT_PUBLIC_API_URL}/label-printer-monitor/odometer-stats?fromDateTime=${encodeURIComponent(
          fromApi,
        )}&toDateTime=${encodeURIComponent(toApi)}`,
        { method: "GET", cache: "no-store" },
      );
      if (statsRes.status === 401 || statsRes.status === 403) return;
      if (!statsRes.ok) {
        const body = await statsRes.json().catch(() => ({}));
        throw new Error(body?.error ?? `HTTP ${statsRes.status}`);
      }
      setOdometerStats(await statsRes.json());
    } catch (e) {
      console.error("label printer odometer stats", e);
      setStatsError(
        e instanceof Error ? e.message : "無法載入 Zebra 里程表區間統計",
      );
      setOdometerStats(null);
    } finally {
      setStatsLoading(false);
      statsInFlightRef.current = false;
    }
  }, []);

  const runPrinterCheck = useCallback(async () => {
    if (checkInFlightRef.current) return;
    checkInFlightRef.current = true;
    setLoading(true);
    setError(null);
    try {
      const checkRes = await clientAuthFetch(
        `${NEXT_PUBLIC_API_URL}/label-printer-monitor/check`,
        { method: "POST" },
      );
      if (checkRes.status === 401 || checkRes.status === 403) return;
      if (checkRes.status === 404) {
        throw new Error(
          "標籤印表機監控 API 未啟用，請重新啟動後端並確認已部署最新版本"
        );
      }
      if (!checkRes.ok) {
        throw new Error(`check HTTP ${checkRes.status}`);
      }
      const checkData = await checkRes.json();
      setPrinters(Array.isArray(checkData.printers) ? checkData.printers : []);
      setSummary(checkData.summary ?? null);
    } catch (e) {
      console.error("label printer monitor check", e);
      setError(
        e instanceof Error ? e.message : "無法檢查標籤印表機狀態"
      );
    } finally {
      setLoading(false);
      checkInFlightRef.current = false;
    }
  }, []);

  const runFullRefresh = useCallback(async () => {
    await Promise.all([
      runPrinterCheck(),
      fetchOdometerStats(statsFrom, statsTo),
    ]);
  }, [runPrinterCheck, fetchOdometerStats, statsFrom, statsTo]);

  useEffect(() => {
    if (!active) return;
    void runPrinterCheck();
    void fetchOdometerStats(defaultStatsFrom(), defaultStatsTo());
    const id = window.setInterval(() => void runPrinterCheck(), 120_000);
    return () => window.clearInterval(id);
  }, [active, runPrinterCheck, fetchOdometerStats]);

  useEffect(() => {
    if (!active || refreshAt <= 0) return;
    void runFullRefresh();
  }, [refreshAt, active, runFullRefresh]);

  const offlineCount = summary?.offline ?? 0;
  const isZebra = (brand?: string) =>
    (brand ?? "").toLowerCase().includes("zebra");

  return (
    <div className="space-y-4 mt-6">
      <Typography variant="h6" fontWeight={600}>
        標籤印表機監控（In Development）
      </Typography>
      <Typography variant="body2" color="text.secondary">
        監控「印表機」設定中 type=Label 的設備：TCP 連線檢測，Zebra
        機型另讀取內建里程表（odometer）。
      </Typography>

      {offlineCount > 0 && (
        <Alert severity="warning">
          有 {offlineCount} 台標籤印表機無法連線，請檢查電源、網路或 IP/Port。
        </Alert>
      )}

      {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="error" label={`離線 ${summary.offline}`} />
          <Chip
            size="small"
            color="warning"
            label={`未設定 IP ${summary.unconfigured}`}
          />
          {summary.unchecked > 0 && (
            <Chip size="small" label={`未檢查 ${summary.unchecked}`} />
          )}
        </Box>
      )}

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

      <Typography variant="subtitle2" fontWeight={600}>
        標籤印表機狀態
      </Typography>
      <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 align="right">
                <Box
                  component="span"
                  sx={{
                    display: "inline-flex",
                    alignItems: "center",
                    gap: 0.5,
                  }}
                >
                  累計里程
                  <Tooltip title="Zebra 印表機透過 TCP 9100 讀取 odometer.total_label_count">
                    <InfoOutlined
                      sx={{ fontSize: 16, color: "text.secondary" }}
                    />
                  </Tooltip>
                </Box>
              </TableCell>
              <TableCell align="right">
                <Box
                  component="span"
                  sx={{
                    display: "inline-flex",
                    alignItems: "center",
                    gap: 0.5,
                  }}
                >
                  自上次檢查
                  <Tooltip title="本次 odometer 與上次記錄的差值（實際出標張數估算）">
                    <InfoOutlined
                      sx={{ fontSize: 16, color: "text.secondary" }}
                    />
                  </Tooltip>
                </Box>
              </TableCell>
              <TableCell align="right">延遲 (ms)</TableCell>
              <TableCell>最後檢查</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {loading && printers.length === 0 ? (
              <TableRow>
                <TableCell colSpan={8} align="center" sx={{ py: 4 }}>
                  <CircularProgress size={28} />
                </TableCell>
              </TableRow>
            ) : printers.length === 0 ? (
              <TableRow>
                <TableCell colSpan={8} align="center" sx={{ py: 4 }}>
                  沒有 Label 類型印表機
                </TableCell>
              </TableRow>
            ) : (
              printers.map((row) => {
                const st = STATUS_LABEL[row.status] ?? STATUS_LABEL.unchecked;
                const showOdometer = isZebra(row.brand);
                return (
                  <TableRow key={row.id} hover>
                    <TableCell>
                      <Chip size="small" color={st.color} label={st.label} />
                    </TableCell>
                    <TableCell>
                      <Typography variant="body2" fontWeight={600}>
                        {row.name || row.code || `#${row.id}`}
                      </Typography>
                      {row.code && row.name && (
                        <Typography variant="caption" color="text.secondary">
                          {row.code}
                        </Typography>
                      )}
                      {row.errorMessage && (
                        <Typography
                          variant="caption"
                          display="block"
                          color="error"
                        >
                          {row.errorMessage}
                        </Typography>
                      )}
                    </TableCell>
                    <TableCell>{row.brand ?? "—"}</TableCell>
                    <TableCell>
                      {row.ip ? `${row.ip}:${row.port ?? 9100}` : "—"}
                    </TableCell>
                    <TableCell align="right">
                      {showOdometer
                        ? row.odometerTotal != null
                          ? row.odometerTotal.toLocaleString()
                          : "—"
                        : "—"}
                    </TableCell>
                    <TableCell align="right">
                      {showOdometer && row.deltaSincePrevious != null
                        ? row.deltaSincePrevious.toLocaleString()
                        : "—"}
                    </TableCell>
                    <TableCell align="right">
                      {row.latencyMs != null ? row.latencyMs : "—"}
                    </TableCell>
                    <TableCell>{formatApiDateTime(row.lastCheckAt)}</TableCell>
                  </TableRow>
                );
              })
            )}
          </TableBody>
        </Table>
      </TableContainer>

      <Typography variant="subtitle2" fontWeight={600} sx={{ mt: 2 }}>
        Zebra 里程表區間印量（估算）
      </Typography>
      <Typography variant="body2" color="text.secondary" sx={{ mb: 1 }}>
        依監控掃描寫入的 odometer 快照估算（最長 {STATS_MAX_RANGE_DAYS} 天）。非
        Zebra 機型不提供區間印量。
      </Typography>
      <LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale="zh-hk">
        <Box className="flex flex-wrap items-end gap-3 mb-2">
          <DateTimePicker
            label="開始時間"
            views={["year", "month", "day", "hours", "minutes", "seconds"]}
            format={STATS_DATETIME_FORMAT}
            value={statsFrom}
            onChange={(value) => {
              if (value?.isValid()) setStatsFrom(value);
            }}
            slotProps={{
              textField: { size: "small", sx: { minWidth: 220 } },
            }}
          />
          <DateTimePicker
            label="結束時間"
            views={["year", "month", "day", "hours", "minutes", "seconds"]}
            format={STATS_DATETIME_FORMAT}
            value={statsTo}
            onChange={(value) => {
              if (value?.isValid()) setStatsTo(value);
            }}
            slotProps={{
              textField: { size: "small", sx: { minWidth: 220 } },
            }}
          />
          <Button
            variant="outlined"
            size="small"
            startIcon={
              statsLoading ? <CircularProgress size={16} /> : <Search />
            }
            disabled={statsLoading}
            onClick={() => void fetchOdometerStats(statsFrom, statsTo)}
            sx={{ mb: 0.25 }}
          >
            查詢統計
          </Button>
        </Box>
      </LocalizationProvider>
      {statsError && (
        <Alert severity="error" sx={{ mb: 1 }}>
          {statsError}
        </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 align="right">區間印量（估算）</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {statsLoading && !odometerStats?.printers?.length ? (
              <TableRow>
                <TableCell colSpan={4} align="center" sx={{ py: 3 }}>
                  <CircularProgress size={24} />
                </TableCell>
              </TableRow>
            ) : !odometerStats?.printers?.length ? (
              <TableRow>
                <TableCell colSpan={4} align="center" sx={{ py: 3 }}>
                  此區間內尚無 Zebra 里程表記錄
                </TableCell>
              </TableRow>
            ) : (
              odometerStats.printers.map((row) => (
                <TableRow key={row.printerId} hover>
                  <TableCell>
                    <Typography variant="body2" fontWeight={600}>
                      {row.name || row.code || `#${row.printerId}`}
                    </Typography>
                    {row.code && row.name && (
                      <Typography variant="caption" color="text.secondary">
                        {row.code}
                      </Typography>
                    )}
                  </TableCell>
                  <TableCell>
                    {row.startAt && row.startOdometer != null
                      ? `${formatApiDateTime(
                          row.startAt,
                        )} · ${row.startOdometer.toLocaleString()}`
                      : "—"}
                  </TableCell>
                  <TableCell>
                    {row.endAt && row.endOdometer != null
                      ? `${formatApiDateTime(
                          row.endAt,
                        )} · ${row.endOdometer.toLocaleString()}`
                      : "—"}
                  </TableCell>
                  <TableCell align="right">
                    {row.delta != null ? row.delta.toLocaleString() : "—"}
                  </TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
      </TableContainer>

      {loading && printers.length > 0 && (
        <Box className="flex justify-center py-2">
          <CircularProgress size={24} />
        </Box>
      )}
    </div>
  );
}
