import { useEffect, useState } from "react";
import { Activity, AlertTriangle, WifiOff } from "lucide-react";
import type { TickerState } from "@/hooks/use-delta-tickers";
import type { ConnectionState } from "@/lib/delta-ws";

/** Re-render every `intervalMs` so "Ns ago" strings stay fresh. */
export function useNow(intervalMs = 1000) {
  const [now, setNow] = useState(() => Date.now());
  useEffect(() => {
    const iv = window.setInterval(() => setNow(Date.now()), intervalMs);
    return () => window.clearInterval(iv);
  }, [intervalMs]);
  return now;
}

export function fmtAge(ms: number): string {
  if (!Number.isFinite(ms) || ms < 0) return "—";
  if (ms < 1000) return `${ms}ms`;
  const s = ms / 1000;
  if (s < 60) return `${s < 10 ? s.toFixed(1) : Math.floor(s)}s`;
  const m = s / 60;
  if (m < 60) return `${Math.floor(m)}m`;
  return `${Math.floor(m / 60)}h`;
}

export function fmtSpreadBps(bps?: number): string {
  if (bps == null || !Number.isFinite(bps)) return "—";
  if (bps >= 100) return `${bps.toFixed(0)} bps`;
  if (bps >= 10) return `${bps.toFixed(1)} bps`;
  return `${bps.toFixed(2)} bps`;
}

type Tier = "healthy" | "lagging" | "stale" | "offline";

/**
 * Overall feed-health pill. Combines the raw WS state with tick-latency
 * evidence across every subscribed symbol so users see the real UX-visible
 * health, not just "socket open".
 *
 * Tiers:
 *  - healthy: WS open, median tick age < 3s and no stale symbols
 *  - lagging: WS open but median age 3–10s, or a few stale symbols
 *  - stale:   WS open but most symbols haven't updated in >10s
 *  - offline: WS not open
 */
export function FeedHealth({
  tickers,
  connectionState,
}: {
  tickers: Record<string, TickerState>;
  connectionState: ConnectionState;
}) {
  const now = useNow(1000);
  const ages: number[] = [];
  let staleCount = 0;
  let symbolCount = 0;
  for (const s in tickers) {
    symbolCount += 1;
    const t = tickers[s];
    const age = now - t.lastUpdate;
    ages.push(age);
    if (age > 10_000) staleCount += 1;
  }
  ages.sort((a, b) => a - b);
  const median = ages.length ? ages[Math.floor(ages.length / 2)] : 0;
  const worst = ages.length ? ages[ages.length - 1] : 0;

  const socketDown = connectionState !== "open";
  const tier: Tier = socketDown
    ? "offline"
    : symbolCount === 0
      ? "lagging"
      : staleCount >= Math.max(2, Math.ceil(symbolCount * 0.5))
        ? "stale"
        : median > 3_000 || staleCount > 0
          ? "lagging"
          : "healthy";

  const cfg = {
    healthy: {
      cls: "border-bull/40 bg-bull-soft text-bull",
      Icon: Activity,
      label: "Feed healthy",
    },
    lagging: {
      cls: "border-warning/40 bg-warning/10 text-warning",
      Icon: Activity,
      label: "Feed lagging",
    },
    stale: {
      cls: "border-warning/60 bg-warning/15 text-warning",
      Icon: AlertTriangle,
      label: "Feed stale",
    },
    offline: {
      cls: "border-bear/40 bg-bear-soft text-bear",
      Icon: WifiOff,
      label: "Feed offline",
    },
  }[tier];

  const Icon = cfg.Icon;
  const title =
    symbolCount === 0
      ? cfg.label
      : `${cfg.label} · median ${fmtAge(median)} · worst ${fmtAge(worst)} · ${staleCount}/${symbolCount} stale`;

  return (
    <span
      className={`inline-flex items-center gap-1.5 rounded-md border px-2 py-1 text-[10px] font-semibold uppercase tracking-wider ${cfg.cls}`}
      title={title}
      role="status"
      aria-label={title}
    >
      <Icon className={`h-3 w-3 ${tier === "healthy" ? "animate-pulse" : ""}`} />
      <span>{cfg.label}</span>
      {symbolCount > 0 && (
        <span className="num opacity-80">· {fmtAge(median)}</span>
      )}
    </span>
  );
}

/** Tiny per-symbol latency chip: green <3s, amber 3–10s, red >10s. */
export function TickLatency({ lastUpdate }: { lastUpdate?: number }) {
  const now = useNow(1000);
  if (!lastUpdate) return <span className="text-muted-foreground">—</span>;
  const age = Math.max(0, now - lastUpdate);
  const tone =
    age > 10_000 ? "text-bear" : age > 3_000 ? "text-warning" : "text-bull";
  const dot =
    age > 10_000 ? "bg-bear" : age > 3_000 ? "bg-warning" : "bg-bull";
  return (
    <span
      className={`inline-flex items-center gap-1 num ${tone}`}
      title={`Last tick ${fmtAge(age)} ago`}
    >
      <span className={`inline-block h-1.5 w-1.5 rounded-full ${dot}`} />
      {fmtAge(age)}
    </span>
  );
}
