/* StatusIndicator — top-bar status pill with inline issue summary.
 *
 * Click to open a Popover that lists what's wrong (failed integrations,
 * expiring/expired tokens, recent sync failures) with deep-links to the
 * relevant tools.  When everything is healthy the popover just confirms
 * "All systems operational".  A "View full status" link at the bottom
 * routes to /status.
 *
 * Polls /api/dashboard/integration-health every 60 s.  Rolls up the
 * summary into a single StatusLight color in the trigger so the visual
 * hint is visible without opening the popover. */

'use client';

import { useEffect, useState } from 'react';
import Link from 'next/link';
import { ArrowRight, KeyRound, Power, ShieldCheck, XCircle } from 'lucide-react';
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover';
import { StatusLight, type StatusLightState } from '@/components/ui/status-light';
import { Separator } from '@/components/ui/separator';

interface IntegrationHealthItem {
  key: string;
  name: string;
  status: 'ok' | 'auth_failed' | 'unreachable' | 'not_configured' | 'unknown' | 'disabled';
  error?: string | null;
  tokenExpiry?: { envVar: string; daysRemaining: number } | null;
}

interface HealthSummary {
  total: number;
  ok: number;
  failed: number;
  notConfigured: number;
  disabled: number;
  expiringWithin14Days: number;
  expired: number;
  hasIssues: boolean;
}

interface HealthResponse {
  items: IntegrationHealthItem[];
  summary: HealthSummary;
}

const POLL_MS = 60_000;

export function StatusIndicator() {
  const [data, setData] = useState<HealthResponse | null>(null);

  useEffect(() => {
    let cancelled = false;
    async function load() {
      try {
        const res = await fetch('/api/dashboard/integration-health', { cache: 'no-store' });
        if (!res.ok || cancelled) return;
        const j = (await res.json()) as HealthResponse;
        if (!cancelled) setData(j);
      } catch {
        /* leave null — trigger renders idle */
      }
    }
    void load();
    const id = setInterval(() => void load(), POLL_MS);
    return () => {
      cancelled = true;
      clearInterval(id);
    };
  }, []);

  const summary = data?.summary;
  const state: StatusLightState = !summary
    ? 'idle'
    : summary.failed > 0 || summary.expired > 0
      ? 'error'
      : summary.expiringWithin14Days > 0
        ? 'warn'
        : 'ok';

  const triggerTitle = !summary
    ? 'System status'
    : state === 'error'
      ? `${summary.failed + summary.expired} integration issue(s)`
      : state === 'warn'
        ? `${summary.expiringWithin14Days} token(s) expiring soon`
        : 'All systems operational';

  return (
    <Popover>
      <PopoverTrigger
        title={triggerTitle}
        aria-label={triggerTitle}
        className="inline-flex h-9 w-9 items-center justify-center rounded-md hover:bg-accent/40 transition-colors"
      >
        <StatusLight state={state} size="md" label={triggerTitle} />
      </PopoverTrigger>
      <PopoverContent align="end" className="w-80 p-0">
        <StatusSummary data={data} />
      </PopoverContent>
    </Popover>
  );
}

function StatusSummary({ data }: { data: HealthResponse | null }) {
  if (!data) {
    return (
      <div className="px-4 py-3">
        <p className="text-sm text-muted-foreground">Loading system status…</p>
      </div>
    );
  }

  const failing = data.items.filter(
    (i) => i.status === 'auth_failed' || i.status === 'unreachable',
  );
  const expired = data.items.filter(
    (i) => i.tokenExpiry && i.tokenExpiry.daysRemaining <= 0,
  );
  const expiring = data.items.filter(
    (i) =>
      i.tokenExpiry &&
      i.tokenExpiry.daysRemaining > 0 &&
      i.tokenExpiry.daysRemaining <= 14,
  );

  const allOk = failing.length === 0 && expired.length === 0 && expiring.length === 0;

  return (
    <>
      <div className="px-4 pt-3 pb-2">
        <div className="flex items-center gap-2">
          {allOk ? (
            <>
              <ShieldCheck className="h-4 w-4 text-emerald-600 dark:text-emerald-400" />
              <p className="text-sm font-medium">All systems operational</p>
            </>
          ) : (
            <>
              <Power className="h-4 w-4 text-destructive" />
              <p className="text-sm font-medium">
                {failing.length + expired.length + expiring.length} item(s) need attention
              </p>
            </>
          )}
        </div>
        <p className="text-xs text-muted-foreground mt-1">
          <span className="num">{data.summary.ok}</span> healthy ·{' '}
          <span className="num">{data.summary.disabled}</span> disabled ·{' '}
          <span className="num">{data.summary.notConfigured}</span> unconfigured
        </p>
      </div>

      {failing.length > 0 && (
        <>
          <Separator />
          <IssueGroup
            title="Failing"
            icon={<XCircle className="h-3.5 w-3.5 text-destructive" />}
          >
            {failing.map((i) => (
              <IssueRow
                key={i.key}
                primary={i.name}
                secondary={
                  i.status === 'auth_failed' ? 'authentication failed' : 'unreachable'
                }
                tone="error"
              />
            ))}
          </IssueGroup>
        </>
      )}

      {expired.length > 0 && (
        <>
          <Separator />
          <IssueGroup
            title="Expired tokens"
            icon={<KeyRound className="h-3.5 w-3.5 text-destructive" />}
          >
            {expired.map((i) => (
              <IssueRow
                key={i.key}
                primary={i.name}
                secondary={`expired ${Math.abs(i.tokenExpiry!.daysRemaining).toFixed(0)} d ago`}
                tone="error"
              />
            ))}
          </IssueGroup>
        </>
      )}

      {expiring.length > 0 && (
        <>
          <Separator />
          <IssueGroup
            title="Expiring soon"
            icon={<KeyRound className="h-3.5 w-3.5 text-amber-500" />}
          >
            {expiring.map((i) => (
              <IssueRow
                key={i.key}
                primary={i.name}
                secondary={`expires in ${i.tokenExpiry!.daysRemaining.toFixed(0)} d`}
                tone="warn"
              />
            ))}
          </IssueGroup>
        </>
      )}

      <Separator />
      <Link
        href="/status"
        className="flex items-center justify-between px-4 py-2.5 text-sm hover:bg-accent/40 transition-colors"
      >
        <span>View full status</span>
        <ArrowRight className="h-3.5 w-3.5 text-muted-foreground" />
      </Link>
    </>
  );
}

function IssueGroup({
  title,
  icon,
  children,
}: {
  title: string;
  icon: React.ReactNode;
  children: React.ReactNode;
}) {
  return (
    <div className="px-4 py-2 space-y-1">
      <p className="metric-label flex items-center gap-1.5">
        {icon}
        {title}
      </p>
      <ul className="space-y-0.5 mt-1">{children}</ul>
    </div>
  );
}

function IssueRow({
  primary,
  secondary,
  tone,
}: {
  primary: string;
  secondary: string;
  tone: 'error' | 'warn';
}) {
  const toneClass =
    tone === 'error'
      ? 'text-destructive'
      : 'text-amber-700 dark:text-amber-400';
  return (
    <li className="flex items-center justify-between text-sm">
      <span className="font-medium truncate">{primary}</span>
      <span className={`text-xs num ${toneClass}`}>{secondary}</span>
    </li>
  );
}
