"use client";

import Link from "next/link";
import { useMemo } from "react";

import { AgentFeatures } from "@/components/AgentFeatures";
import { CheckEventsLink } from "@/components/CheckEventsLink";
import { Td, Th } from "@/components/DataPanel";
import { LabelChips } from "@/components/Labels";
import { DateTime } from "@/components/TimeZoneControls";
import type { components } from "@/lib/api-types";
import { withLivenessChecks } from "@/lib/check-groups";
import { statusBadgeClass } from "@/lib/format";
import { usePolling } from "@/lib/usePolling";

type Agent = components["schemas"]["Agent"];
type CheckState = components["schemas"]["CheckState"];
type StoredEvent = components["schemas"]["StoredCheckResultEvent"];
type SortKey = "severity" | "check_id" | "last_seen";
type TabKey = "checks" | "events";
type AgentDetailData = {
  agent: Agent;
  checks: CheckState[];
  events: StoredEvent[];
};

const severityRank: Record<CheckState["status"], number> = {
  critical: 0,
  warning: 1,
  unknown: 2,
  ok: 3,
};

export function AgentDetailBrowser({
  initialData,
  sort,
  tab,
}: {
  initialData: AgentDetailData;
  sort: SortKey;
  tab: TabKey;
}) {
  const { data } = usePolling(
    initialData,
    `/api/poll/agent?agent_id=${encodeURIComponent(initialData.agent.agent_id)}`,
  );
  const { agent, events } = data;
  const checks = useMemo(
    () => sortChecks(withLivenessChecks([agent], data.checks), sort),
    [agent, data.checks, sort],
  );

  return (
    <div className="space-y-6">
      <div>
        <Link href="/agents" className="text-sm text-blue-300 hover:text-blue-200">
          ← agents
        </Link>
        <h1 className="mt-2 text-lg font-semibold">{agent.agent_id}</h1>
      </div>
      <dl className="grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1 text-sm">
        <dt className="text-neutral-400">hostname</dt>
        <dd>{agent.hostname}</dd>
        <dt className="text-neutral-400">status</dt>
        <dd className={statusBadgeClass(agent.status)}>{agent.status}</dd>
        <dt className="text-neutral-400">last_seen_at</dt>
        <dd>
          <DateTime iso={agent.last_seen_at} />
        </dd>
        <dt className="text-neutral-400">features</dt>
        <dd>
          <AgentFeatures features={agent.features} />
        </dd>
        <dt className="text-neutral-400">labels</dt>
        <dd>
          <LabelChips labels={agent.labels} />
        </dd>
      </dl>
      <TabNav agentId={agent.agent_id} current={tab} sort={sort} />
      {tab === "checks" ? <ChecksTable agentId={agent.agent_id} checks={checks} sort={sort} /> : <EventsTable events={events} />}
    </div>
  );
}

function TabNav({ agentId, current, sort }: { agentId: string; current: TabKey; sort: SortKey }) {
  const base = `/agents/${encodeURIComponent(agentId)}`;
  return (
    <div className="flex gap-4 border-b border-neutral-800 text-sm">
      <Link
        href={`${base}?tab=checks&sort=${sort}`}
        className={`pb-2 ${current === "checks" ? "border-b border-neutral-200 text-neutral-100" : "text-neutral-400 hover:text-neutral-200"}`}
      >
        Checks
      </Link>
      <Link
        href={`${base}?tab=events&sort=${sort}`}
        className={`pb-2 ${current === "events" ? "border-b border-neutral-200 text-neutral-100" : "text-neutral-400 hover:text-neutral-200"}`}
      >
        Events
      </Link>
    </div>
  );
}

function ChecksTable({
  agentId,
  checks,
  sort,
}: {
  agentId: string;
  checks: CheckState[];
  sort: SortKey;
}) {
  if (checks.length === 0) return <div className="text-sm text-neutral-500">No checks.</div>;
  return (
    <section>
      <table className="w-full text-sm">
        <thead>
          <tr>
            <Th>
              <SortLink agentId={agentId} sort="check_id" current={sort}>
                check_id
              </SortLink>
            </Th>
            <Th>
              <SortLink agentId={agentId} sort="severity" current={sort}>
                status
              </SortLink>
            </Th>
            <Th>
              <SortLink agentId={agentId} sort="last_seen" current={sort}>
                last_observed_at
              </SortLink>
            </Th>
            <Th>summary</Th>
          </tr>
        </thead>
        <tbody>
          {checks.map((c) => (
            <tr key={c.check_id}>
              <Td>
                <CheckEventsLink agentId={agentId} checkId={c.check_id} />
              </Td>
              <Td className={statusBadgeClass(c.status)}>{c.status}</Td>
              <Td>
                <DateTime iso={c.last_observed_at} />
              </Td>
              <Td className="max-w-md truncate text-xs text-neutral-400">{c.summary ?? "—"}</Td>
            </tr>
          ))}
        </tbody>
      </table>
    </section>
  );
}

function EventsTable({ events }: { events: StoredEvent[] }) {
  if (events.length === 0) return <div className="text-sm text-neutral-500">No events.</div>;
  return (
    <section>
      <table className="w-full text-sm">
        <thead>
          <tr>
            <Th>observed_at</Th>
            <Th>check_id</Th>
            <Th>status</Th>
            <Th>duration_ms</Th>
          </tr>
        </thead>
        <tbody>
          {events.map((e) => (
            <tr key={e.event_id}>
              <Td>
                <DateTime iso={e.observed_at} />
              </Td>
              <Td>
                <CheckEventsLink agentId={e.agent_id} checkId={e.check_id} />
              </Td>
              <Td className={statusBadgeClass(e.status)}>{e.status}</Td>
              <Td>{e.duration_ms}</Td>
            </tr>
          ))}
        </tbody>
      </table>
    </section>
  );
}

function SortLink({
  agentId,
  sort,
  current,
  children,
}: {
  agentId: string;
  sort: SortKey;
  current: SortKey;
  children: React.ReactNode;
}) {
  return (
    <Link
      href={`/agents/${encodeURIComponent(agentId)}?tab=checks&sort=${sort}`}
      className={sort === current ? "text-neutral-100" : "text-neutral-400 hover:text-neutral-200"}
    >
      {children}
    </Link>
  );
}

function sortChecks(checks: CheckState[], sort: SortKey): CheckState[] {
  return [...checks].sort((a, b) => {
    if (sort === "check_id") return a.check_id.localeCompare(b.check_id);
    if (sort === "last_seen") return b.last_observed_at.localeCompare(a.last_observed_at);
    return severityRank[a.status] - severityRank[b.status] || a.check_id.localeCompare(b.check_id);
  });
}
