// ---------------------------------------------------------------------------
// Live-tail status pill (sub-project 5, Phase 5 Task 21).
//
// Tiny presentational component used in the toolbar of `Claims`,
// `Remittances`, and `ActivityLog` to surface the connection status of
// `useTailStream`. Renders the existing `<Badge>` (variants from
// `src/components/ui/badge.tsx`) plus a "Last event: 12s ago" subtitle
// that re-ticks every second, plus a "↻ Reconnect" button that only
// appears when the connection has visibly failed (`stalled` or `error`).
//
// Variant mapping (per spec):
//   live            → success
//   connecting      → warning
//   reconnecting    → warning
//   closed          → destructive
//   stalled         → destructive
//   error           → destructive
// ---------------------------------------------------------------------------

import { useEffect, useState } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import type { TailStatus } from "@/hooks/useTailStream";

export interface TailStatusPillProps {
  status: TailStatus;
  lastEventAt: Date | null;
  onReconnect: () => void;
}

const STATUS_LABEL: Record<TailStatus, string> = {
  connecting: "Connecting…",
  live: "Live",
  reconnecting: "Reconnecting…",
  closed: "Closed",
  stalled: "Stalled",
  error: "Error",
};

type BadgeVariant = "success" | "warning" | "destructive";

const STATUS_VARIANT: Record<TailStatus, BadgeVariant> = {
  live: "success",
  connecting: "warning",
  reconnecting: "warning",
  closed: "destructive",
  stalled: "destructive",
  error: "destructive",
};

/**
 * Render a duration in seconds as a compact human label. We deliberately
 * keep the units small — under a minute is the common case for a healthy
 * tail (the stall detector fires at 30s, so anything beyond is a real
 * outage the user will want to investigate).
 */
function formatAge(seconds: number): string {
  if (seconds < 0) return "0s";
  if (seconds < 60) return `${seconds}s`;
  const m = Math.floor(seconds / 60);
  const s = seconds % 60;
  if (m < 60) return s === 0 ? `${m}m` : `${m}m ${s}s`;
  const h = Math.floor(m / 60);
  return `${h}h ${m % 60}m`;
}

export function TailStatusPill({
  status,
  lastEventAt,
  onReconnect,
}: TailStatusPillProps): React.JSX.Element {
  // Re-tick every second so the "Last event: 12s ago" subtitle stays
  // current without the parent having to re-render. We mount the
  // interval only once per pill instance.
  const [now, setNow] = useState<number>(() => Date.now());
  useEffect(() => {
    const id = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(id);
  }, []);

  const ageSeconds = lastEventAt
    ? Math.max(0, Math.floor((now - lastEventAt.getTime()) / 1000))
    : null;

  const subtitle =
    ageSeconds === null
      ? "Last event: never"
      : `Last event: ${formatAge(ageSeconds)} ago`;

  // Only show the manual reconnect affordance when the connection has
  // visibly failed. `closed` is reserved for the post-unmount state and
  // is intentionally not actionable — the component is about to vanish.
  const showReconnect = status === "stalled" || status === "error";

  return (
    <div
      className="inline-flex items-center gap-2"
      data-testid="tail-status-pill"
    >
      <Badge variant={STATUS_VARIANT[status]} aria-label={`tail status: ${status}`}>
        {STATUS_LABEL[status]}
      </Badge>
      <span
        className="text-xs text-muted-foreground"
        data-testid="tail-status-pill-subtitle"
      >
        {subtitle}
      </span>
      {showReconnect && (
        <Button
          type="button"
          variant="outline"
          size="sm"
          onClick={onReconnect}
          data-testid="tail-status-pill-reconnect"
        >
          ↻ Reconnect
        </Button>
      )}
    </div>
  );
}
