import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { auth } from "@/auth";
import { NotAuthorized } from "@/components/ShellEmpty";
import { formatDateTime, formatRelative, truncate } from "@/lib/format";
import type { SessionWithExtras } from "@/lib/session";
import { canSee } from "@/lib/session";
import {
  createAPIKey,
  fetchAPIKeys,
  fetchCatalog,
  fetchTenantBySlug,
  revokeAPIKey,
  type APIKey,
} from "@/lib/tenant-registry";

export default async function APIKeysPage({
  params,
  searchParams,
}: {
  params: Promise<{ slug: string }>;
  searchParams: Promise<{ plaintext?: string; err?: string }>;
}) {
  const { slug } = await params;
  const flash = await searchParams;
  const session = (await auth()) as SessionWithExtras | null;
  if (!canSee(session, "api-keys")) return <NotAuthorized />;

  const tenant = await fetchTenantBySlug(slug);
  if (!tenant) redirect(`/${slug}/dashboard`);

  const [keys, catalog] = await Promise.all([
    fetchAPIKeys(tenant.id),
    fetchCatalog(),
  ]);
  const active = keys.filter((k) => !k.revoked_at);
  const revoked = keys.filter((k) => k.revoked_at);

  async function doCreate(formData: FormData) {
    "use server";
    const name = String(formData.get("name") ?? "").trim();
    const product = String(formData.get("product") ?? "").trim();
    const tenantId = String(formData.get("tenant_id"));
    const slugV = String(formData.get("slug"));
    if (!name) redirect(`/${slugV}/settings/api-keys?err=missing_name`);

    const res = await createAPIKey({
      tenant_id: tenantId,
      name,
      product: product || undefined,
    });
    if (!res.ok) {
      redirect(`/${slugV}/settings/api-keys?err=${res.error}`);
    }
    revalidatePath(`/${slugV}/settings/api-keys`);
    redirect(`/${slugV}/settings/api-keys?plaintext=${encodeURIComponent(res.plaintext)}`);
  }

  async function doRevoke(formData: FormData) {
    "use server";
    const id = String(formData.get("id"));
    const slugV = String(formData.get("slug"));
    const res = await revokeAPIKey(id);
    if (!res.ok) {
      redirect(`/${slugV}/settings/api-keys?err=${res.error}`);
    }
    revalidatePath(`/${slugV}/settings/api-keys`);
    redirect(`/${slugV}/settings/api-keys`);
  }

  return (
    <section>
      <h1 style={{ fontSize: 28, marginBottom: 8 }}>API keys</h1>
      <p style={{ color: "#444", marginBottom: 16 }}>
        Per-tenant keys for headless product calls. Hashed with argon2id;
        the plaintext is shown <strong>once</strong> on creation.
      </p>

      {flash.plaintext && <PlaintextBanner plaintext={flash.plaintext} />}
      {flash.err && <ErrorBanner err={flash.err} />}

      <h2 style={{ fontSize: 18, marginTop: 24, marginBottom: 8 }}>Create a new key</h2>
      <form action={doCreate} style={{ display: "grid", gap: 8, maxWidth: 480 }}>
        <input type="hidden" name="tenant_id" value={tenant.id} />
        <input type="hidden" name="slug" value={slug} />
        <label style={{ display: "grid", gap: 4, fontSize: 14 }}>
          <span>Name</span>
          <input name="name" required maxLength={100} placeholder="ci-bot" style={inputStyle} />
        </label>
        <label style={{ display: "grid", gap: 4, fontSize: 14 }}>
          <span>Product scope (optional)</span>
          <select name="product" defaultValue="" style={inputStyle}>
            <option value="">All products</option>
            {catalog.map((p) => (
              <option key={p.key} value={p.key}>
                {p.name}
              </option>
            ))}
          </select>
        </label>
        <button type="submit" style={btnPrimary}>
          Create key
        </button>
      </form>

      <h2 style={{ fontSize: 18, marginTop: 32, marginBottom: 8 }}>
        Active keys ({active.length})
      </h2>
      {active.length === 0 ? (
        <p style={{ color: "#666", fontSize: 14 }}>No active keys.</p>
      ) : (
        <KeyTable keys={active} doRevoke={doRevoke} slug={slug} canRevoke />
      )}

      {revoked.length > 0 && (
        <>
          <h2 style={{ fontSize: 18, marginTop: 32, marginBottom: 8 }}>
            Revoked ({revoked.length})
          </h2>
          <KeyTable keys={revoked} doRevoke={doRevoke} slug={slug} canRevoke={false} />
        </>
      )}
    </section>
  );
}

function PlaintextBanner({ plaintext }: { plaintext: string }) {
  return (
    <div
      role="status"
      style={{
        padding: 12,
        marginTop: 8,
        marginBottom: 8,
        borderRadius: 8,
        background: "#e6f7ec",
        border: "1px solid #a4d8b8",
      }}
    >
      <strong style={{ color: "#0a6e2a", fontSize: 14 }}>Key created</strong>
      <p style={{ margin: "8px 0", fontSize: 13, color: "#444" }}>
        Store this value — it cannot be retrieved later.
      </p>
      <code
        style={{
          display: "block",
          padding: "8px 10px",
          background: "white",
          border: "1px solid #ddd",
          borderRadius: 6,
          fontSize: 13,
          wordBreak: "break-all",
        }}
      >
        {plaintext}
      </code>
    </div>
  );
}

function ErrorBanner({ err }: { err: string }) {
  return (
    <div
      role="status"
      style={{
        padding: 12,
        marginTop: 8,
        marginBottom: 8,
        borderRadius: 8,
        background: "#fdecea",
        border: "1px solid #e8a5a5",
        color: "#a82626",
        fontSize: 14,
      }}
    >
      {err === "name_taken" && "A key with that name already exists."}
      {err === "missing_name" && "Name is required."}
      {err === "invalid_input" && "Input failed validation."}
      {!["name_taken", "missing_name", "invalid_input"].includes(err) && `Error: ${err}`}
    </div>
  );
}

function KeyTable({
  keys,
  doRevoke,
  slug,
  canRevoke,
}: {
  keys: APIKey[];
  doRevoke: (fd: FormData) => Promise<void>;
  slug: string;
  canRevoke: boolean;
}) {
  return (
    <div style={{ overflow: "auto" }}>
      <table style={{ width: "100%", fontSize: 13, borderCollapse: "collapse" }}>
        <thead>
          <tr style={{ textAlign: "left", borderBottom: "1px solid #eaeaea" }}>
            <th style={th}>Name</th>
            <th style={th}>Prefix</th>
            <th style={th}>Product</th>
            <th style={th}>Created</th>
            <th style={th}>Last used</th>
            {canRevoke && <th style={th}></th>}
          </tr>
        </thead>
        <tbody>
          {keys.map((k) => (
            <tr key={k.id} style={{ borderBottom: "1px solid #f0f0f0" }}>
              <td style={td}>{truncate(k.name, 30)}</td>
              <td style={{ ...td, fontFamily: "ui-monospace, monospace" }}>{k.prefix}…</td>
              <td style={td}>{k.product || <em style={{ color: "#999" }}>all</em>}</td>
              <td style={td} title={formatDateTime(k.created_at)}>
                {formatRelative(k.created_at)}
              </td>
              <td style={td}>
                {k.last_used_at ? formatRelative(k.last_used_at) : <em style={{ color: "#999" }}>never</em>}
              </td>
              {canRevoke && (
                <td style={td}>
                  <form action={doRevoke}>
                    <input type="hidden" name="id" value={k.id} />
                    <input type="hidden" name="slug" value={slug} />
                    <button type="submit" style={btnDanger}>
                      Revoke
                    </button>
                  </form>
                </td>
              )}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

const inputStyle: React.CSSProperties = {
  padding: "8px 10px",
  border: "1px solid #ddd",
  borderRadius: 6,
  fontSize: 14,
};
const btnPrimary: React.CSSProperties = {
  marginTop: 4,
  padding: "8px 14px",
  background: "#0070f3",
  color: "white",
  border: "none",
  borderRadius: 6,
  fontSize: 14,
  cursor: "pointer",
  justifySelf: "start",
};
const btnDanger: React.CSSProperties = {
  padding: "4px 8px",
  background: "white",
  color: "#a82626",
  border: "1px solid #e8a5a5",
  borderRadius: 4,
  fontSize: 12,
  cursor: "pointer",
};
const th: React.CSSProperties = { padding: "8px 10px", color: "#666", fontWeight: 500 };
const td: React.CSSProperties = { padding: "8px 10px" };
