"use client";

// Top-bar widget — renders active grants as chips with a revoke
// button, and a "Request access" link to /access. Polls every 30s so
// the countdown stays roughly fresh and the chip disappears when a
// grant expires server-side. Optimistic on revoke.

import { useCallback, useEffect, useState } from "react";
import Link from "next/link";

type Grant = {
  id: string;
  roleName: string;
  grantedAt: string;
  expiresAt: string;
};

function fmtRemaining(expiresAt: string): string {
  const diffMs = new Date(expiresAt).getTime() - Date.now();
  if (diffMs <= 0) return "expired";
  const h = Math.floor(diffMs / 3_600_000);
  const m = Math.floor((diffMs % 3_600_000) / 60_000);
  if (h > 0) return `${h}h${m.toString().padStart(2, "0")}`;
  return `${m}m`;
}

export default function ActiveGrantsWidget() {
  const [grants, setGrants] = useState<Grant[]>([]);
  const [, setTick] = useState(0);                  // forces re-render for countdown

  const load = useCallback(async () => {
    try {
      const r = await fetch("/api/pam/active", { cache: "no-store" });
      if (!r.ok) return;
      const j = await r.json();
      setGrants(j.active ?? []);
    } catch {
      /* network blip — try again on next tick */
    }
  }, []);

  useEffect(() => {
    void load();
    const refresh = setInterval(load, 30_000);
    const countdown = setInterval(() => setTick((n) => n + 1), 30_000);
    return () => {
      clearInterval(refresh);
      clearInterval(countdown);
    };
  }, [load]);

  const revoke = async (id: string) => {
    setGrants((g) => g.filter((x) => x.id !== id));   // optimistic
    try {
      await fetch(`/api/pam/revoke/${encodeURIComponent(id)}`, { method: "POST" });
    } finally {
      void load();
    }
  };

  return (
    <div className="d-flex align-items-center gap-2">
      {grants.map((g) => (
        <span
          key={g.id}
          className="badge bg-warning-subtle text-warning-emphasis d-inline-flex align-items-center gap-1"
          title={`Active until ${new Date(g.expiresAt).toLocaleString()}`}
          style={{ paddingLeft: 8 }}
        >
          <i className="ph ph-shield-check" aria-hidden="true"></i>
          <span style={{ fontFamily: "var(--bs-font-monospace, monospace)" }}>{g.roleName}</span>
          <span className="text-muted small">·</span>
          <span className="small">{fmtRemaining(g.expiresAt)}</span>
          <button
            type="button"
            className="btn btn-sm btn-link p-0 ms-1 text-warning-emphasis"
            aria-label="Revoke"
            onClick={() => revoke(g.id)}
            title="Revoke now"
          >
            <i className="ph ph-x"></i>
          </button>
        </span>
      ))}
      <Link href="/access" className="btn btn-sm btn-outline-secondary">
        <i className="ph ph-key" aria-hidden="true"></i>
        <span className="ms-1 d-none d-md-inline">Access</span>
      </Link>
    </div>
  );
}
