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

import { api, type GateDiagnosticsResponse, type GateDiagnosticsRow } from "../services/api/client";
import { formatBeijingTime, toneClass } from "../utils";

export interface GateDiagnosticsState {
  loading: boolean;
  payload: GateDiagnosticsResponse | null;
  rows: NormalizedGateRow[];
  loadedAt: string | null;
  error: string | null;
  sourceKind: string;
  observedAt: string | null;
  serviceId: string | null;
  rawResponse: GateDiagnosticsResponse | null;
}

export interface NormalizedGateRow {
  category: string;
  check: string;
  status: string;
  statusKey: string;
  owner: string;
  detail: string;
  evidence: string[];
  updatedAt: string;
  next: string;
  sourceKind: string;
}

const INITIAL_STATE: GateDiagnosticsState = {
  loading: false,
  payload: null,
  rows: [],
  loadedAt: null,
  error: null,
  sourceKind: "",
  observedAt: null,
  serviceId: null,
  rawResponse: null
};

export function useGateDiagnostics(): {
  state: GateDiagnosticsState;
  refresh(): Promise<void>;
} {
  const [state, setState] = useState<GateDiagnosticsState>(INITIAL_STATE);

  const refresh = useCallback(async () => {
    if (state.loading) return;
    setState((previous) => ({ ...previous, loading: true, error: null }));
    const response = await api.gateDiagnostics();
    if (response.ok && response.data && Array.isArray(response.data.rows)) {
      const rows = response.data.rows.map(normalizeGateRow);
      setState({
        loading: false,
        payload: response.data,
        rows,
        loadedAt: new Date().toISOString(),
        error: null,
        sourceKind: response.data.sourceKind ?? "",
        observedAt: response.data.observedAt ?? null,
        serviceId: response.data.serviceId ?? null,
        rawResponse: response.data
      });
    } else {
      setState({
        loading: false,
        payload: null,
        rows: [liveBlockerRow(response)],
        loadedAt: new Date().toISOString(),
        error: response.error ?? "内部复核 live 后端聚合不可用",
        sourceKind: response.data?.sourceKind ?? "",
        observedAt: response.data?.observedAt ?? null,
        serviceId: response.data?.serviceId ?? null,
        rawResponse: response.data ?? null
      });
    }
  }, [state.loading]);

  useEffect(() => {
    void refresh();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return { state, refresh };
}

function normalizeGateRow(row: GateDiagnosticsRow): NormalizedGateRow {
  const statusKey = String(row.statusKey ?? row.status ?? "source").toLowerCase();
  return {
    category: oneLine(row.category ?? "内部复核"),
    check: oneLine(row.check ?? "未命名检查项"),
    status: gateStatusLabel(row.status, statusKey),
    statusKey,
    owner: oneLine(row.owner ?? "未标明"),
    detail: oneLine(row.detail ?? "live 后端未返回关键细节"),
    evidence: Array.isArray(row.evidence) ? row.evidence.map((item) => String(item)) : [],
    updatedAt: row.updatedAt ?? new Date().toISOString(),
    next: oneLine(row.next ?? "等待维护者补充下一步。"),
    sourceKind: String(row.sourceKind ?? "")
  };
}

function oneLine(value: string): string {
  return value.replace(/\s+/gu, " ").trim();
}

function gateStatusLabel(status: string | undefined, statusKey: string): string {
  if (status) return status;
  const map: Record<string, string> = { pass: "通过", blocked: "阻塞", fail: "失败", warn: "待验证", info: "信息" };
  return map[statusKey] ?? statusKey;
}

function liveBlockerRow(response: { error: string | null; status: number }): NormalizedGateRow {
  return {
    category: "内部复核",
    check: "live 后端聚合不可用",
    status: "阻塞",
    statusKey: "blocked",
    owner: "hwlab-cloud-api /v1/diagnostics/gate",
    detail: response.error ?? `HTTP ${response.status}`,
    evidence: ["GET /v1/diagnostics/gate"],
    updatedAt: new Date().toISOString(),
    next: "等待 cloud-api live 聚合恢复，或检查路由表。",
    sourceKind: "BLOCKED"
  };
}

export function filterGateRows(rows: NormalizedGateRow[], statusFilter: string, search: string): NormalizedGateRow[] {
  const query = search.trim().toLowerCase();
  return rows.filter((row) => {
    if (statusFilter !== "all" && row.statusKey !== statusFilter) return false;
    if (!query) return true;
    return [row.category, row.check, row.status, row.owner, row.detail, ...row.evidence, row.updatedAt, row.next].join(" ").toLowerCase().includes(query);
  });
}

export function gatePayloadTone(payload: GateDiagnosticsResponse | null, error: string | null): "ok" | "blocked" | "warn" | "source" {
  if (error) return "blocked";
  if (!payload) return "source";
  const status = String(payload.status ?? "");
  if (status === "blocked" || status === "blocked" || payload.rowCount === 0) return "warn";
  if (status === "ok" || status === "ready") return "ok";
  return "source";
}

export function gateStatusBadge(row: NormalizedGateRow): { label: string; tone: ReturnType<typeof toneClass> } {
  const tone = toneClass(row.statusKey);
  return { label: row.status, tone };
}

export { formatBeijingTime };
