"use client";

export const dynamic = "force-dynamic";

import { useCallback, useEffect, useState } from "react";
import {
  Bot,
  CheckCircle2,
  ChevronDown,
  ChevronUp,
  HelpCircle,
  KeyRound,
  Loader2,
  Pencil,
  Plus,
  RefreshCw,
  Server,
  Sparkles,
  Trash2,
  X,
} from "lucide-react";

import { useAuth } from "@/auth/clerk";
import { DashboardPageLayout } from "@/components/templates/DashboardPageLayout";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { ConfirmActionDialog } from "@/components/ui/confirm-action-dialog";
import { useOrganizationMembership } from "@/lib/use-organization-membership";
import type {
  ProviderCredentialRead,
  ProviderUsageLiveRead,
} from "@/api/generated/model";
import { customFetch } from "@/api/mutator";
import {
  listProviderCredentialsApiV1ProviderCredentialsGet,
  createProviderCredentialApiV1ProviderCredentialsPost,
  updateProviderCredentialApiV1ProviderCredentialsCredentialIdPatch,
  deleteProviderCredentialApiV1ProviderCredentialsCredentialIdDelete,
  getProviderUsageLiveApiV1ProviderCredentialsCredentialIdUsageGet,
} from "@/api/generated/provider-credentials/provider-credentials";

// ---------------------------------------------------------------------------
// Provider metadata
// ---------------------------------------------------------------------------

type ProviderId = "anthropic" | "openai" | "ollama";

interface ProviderConfig {
  id: ProviderId;
  label: string;
  icon: React.ComponentType<{ className?: string }>;
  description: string;
  keyLabel: string;
  keyPlaceholder: string;
  showBaseUrl: boolean;
  allowMultiple: boolean;
  accountKeyDefault: string;
  showSessionKey: boolean;
  sessionKeyLabel: string;
  sessionKeyPlaceholder: string;
  /** Step-by-step instructions shown in an expandable help section next to the API key field. */
  apiKeyHelp?: readonly string[];
  /** Step-by-step instructions shown next to the session / subscription token field. */
  sessionKeyHelp?: readonly string[];
  /**
   * When set, a green callout is shown above the session key field explaining that this
   * credential is auto-detected so manual entry is optional.
   */
  autoDetectedNote?: string;
}

const PROVIDERS: ProviderConfig[] = [
  {
    id: "anthropic",
    label: "Claude (Anthropic)",
    icon: Bot,
    description:
      "Anthropic Claude API key. Add multiple accounts to track separate keys or billing profiles.",
    keyLabel: "API Key",
    keyPlaceholder: "sk-ant-api03-…",
    showBaseUrl: false,
    allowMultiple: true,
    accountKeyDefault: "default",
    apiKeyHelp: [
      "Go to console.anthropic.com and sign in",
      "Navigate to Settings → API Keys",
      'Click "Create Key" and give it a name',
      "Copy the key — it starts with sk-ant-api03-",
      "It is only shown once, so store it in a password manager",
    ],
    showSessionKey: true,
    sessionKeyLabel: "Subscription token (optional — auto-detected via Claude Code)",
    sessionKeyPlaceholder: "sk-ant-oat01-… (leave blank to auto-detect)",
    autoDetectedNote:
      "Subscription usage (current session %, weekly %) is auto-detected from your local Claude Code login at ~/.claude/.credentials.json. You only need to fill this in if you are running Pipeline on a different machine from Claude Code, or want to override with a specific account.",
    sessionKeyHelp: [
      "Open a terminal and run: cat ~/.claude/.credentials.json",
      'Copy the value of the "accessToken" field — it starts with sk-ant-oat01-',
      "Paste it here. The token expires after ~10 hours; Claude Code renews it automatically when you next use it",
    ],
  },
  {
    id: "openai",
    label: "Codex / OpenAI",
    icon: Sparkles,
    description:
      "OpenAI API key. Add multiple accounts to track usage separately.",
    keyLabel: "API Key",
    keyPlaceholder: "sk-proj-…",
    showBaseUrl: false,
    allowMultiple: true,
    accountKeyDefault: "",
    apiKeyHelp: [
      "Go to platform.openai.com and sign in",
      "Click your org name → API Keys",
      'Click "Create new secret key"',
      "Copy the key — it starts with sk-proj- or sk-",
      "It is only shown once, so store it in a password manager",
    ],
    showSessionKey: true,
    sessionKeyLabel: "Subscription token (optional — auto-detected via Codex CLI)",
    sessionKeyPlaceholder: "eyJhbGc… (leave blank to auto-detect)",
    autoDetectedNote:
      "Subscription usage (current 5h window %, weekly %) is auto-detected from your local Codex CLI login at ~/.codex/auth.json. You only need to fill this in if Pipeline is running on a different machine from the Codex CLI, or the auto-detected token is not working.",
    sessionKeyHelp: [
      "Install the Codex CLI: npm install -g @openai/codex",
      "Run: codex login",
      "This stores a JWT at ~/.codex/auth.json — Pipeline reads it automatically",
      "If you prefer to paste a token manually: sign in to chatgpt.com, open DevTools (F12), Network tab, filter to backend-api, click any request, find the Authorization header, copy the token after \"Bearer \"",
    ],
  },
  {
    id: "ollama",
    label: "Ollama",
    icon: Server,
    description:
      "Ollama instance — local, on-prem, or cloud. Add the base URL; API key only needed for authenticated deployments.",
    keyLabel: "API Key (optional)",
    keyPlaceholder: "Leave blank for unauthenticated",
    showBaseUrl: true,
    allowMultiple: true,
    accountKeyDefault: "default",
    showSessionKey: false,
    sessionKeyLabel: "",
    sessionKeyPlaceholder: "",
    apiKeyHelp: [
      "Most local Ollama deployments do not require an API key",
      "For cloud-hosted or authenticated Ollama instances, paste the Bearer token here",
      'The base URL is the important part — typically http://localhost:11434 for local installs',
    ],
  },
];

function announceProviderCredentialsUpdated() {
  window.dispatchEvent(new Event("provider-credentials-updated"));
}

// ---------------------------------------------------------------------------
// Help toggle — collapsible inline instructions
// ---------------------------------------------------------------------------

function HelpSection({ steps }: { steps: readonly string[] }) {
  return (
    <div className="mt-1.5 rounded-lg border border-[color:rgba(99,102,241,0.25)] bg-[color:rgba(99,102,241,0.06)] px-3 py-2.5">
      <ol className="list-inside list-decimal space-y-1 text-[11px] leading-relaxed text-muted">
        {steps.map((step, i) => (
          <li key={i}>{step}</li>
        ))}
      </ol>
    </div>
  );
}

function HelpToggle({
  steps,
  open,
  onToggle,
}: {
  steps: readonly string[];
  open: boolean;
  onToggle: () => void;
}) {
  if (steps.length === 0) return null;
  return (
    <button
      type="button"
      onClick={onToggle}
      className="flex items-center gap-1 text-[11px] text-[color:var(--accent)] opacity-70 hover:opacity-100 transition-opacity"
    >
      <HelpCircle className="h-3 w-3" />
      {open ? "Hide" : "Where do I find this?"}
      {open ? <ChevronUp className="h-2.5 w-2.5" /> : <ChevronDown className="h-2.5 w-2.5" />}
    </button>
  );
}

// ---------------------------------------------------------------------------
// Add/Edit form
// ---------------------------------------------------------------------------

type CredentialFormData = {
  account_key: string;
  display_name: string;
  api_key: string;
  session_key: string;
  base_url: string;
};

type ProviderCredentialUpdateWithSession = {
  display_name?: string | null;
  api_key?: string | null;
  session_key?: string | null;
  base_url?: string | null;
  active?: boolean | null;
};

interface CredentialFormProps {
  mode?: "create" | "edit";
  initialCredential?: ProviderCredentialRead;
  allowMultiple: boolean;
  showBaseUrl: boolean;
  showSessionKey: boolean;
  sessionKeyLabel: string;
  sessionKeyPlaceholder: string;
  keyLabel: string;
  keyPlaceholder: string;
  accountKeyDefault: string;
  apiKeyHelp?: readonly string[];
  sessionKeyHelp?: readonly string[];
  autoDetectedNote?: string;
  onSave: (data: CredentialFormData) => Promise<void>;
  onTest: (data: CredentialFormData) => Promise<ProviderUsageLiveRead>;
  onCancel: () => void;
  isSaving: boolean;
  error: string | null;
}

function CredentialForm({
  mode = "create",
  initialCredential,
  allowMultiple,
  showBaseUrl,
  showSessionKey,
  sessionKeyLabel,
  sessionKeyPlaceholder,
  keyLabel,
  keyPlaceholder,
  accountKeyDefault,
  apiKeyHelp,
  sessionKeyHelp,
  autoDetectedNote,
  onSave,
  onTest,
  onCancel,
  isSaving,
  error,
}: CredentialFormProps) {
  const isEditMode = mode === "edit";
  const [accountKey, setAccountKey] = useState(
    initialCredential?.account_key ?? accountKeyDefault,
  );
  const [displayName, setDisplayName] = useState(
    initialCredential?.display_name ?? "",
  );
  const [apiKey, setApiKey] = useState("");
  const [sessionKey, setSessionKey] = useState("");
  const [baseUrl, setBaseUrl] = useState(initialCredential?.base_url ?? "");
  const [isTesting, setIsTesting] = useState(false);
  const [testResult, setTestResult] = useState<ProviderUsageLiveRead | null>(null);
  const [testError, setTestError] = useState<string | null>(null);
  const [showApiHelp, setShowApiHelp] = useState(false);
  const [showSessionHelp, setShowSessionHelp] = useState(false);
  const canTest = showBaseUrl
    ? Boolean(baseUrl.trim())
    : Boolean(apiKey.trim() || (showSessionKey && sessionKey.trim()));
  const existingApiKeyLabel =
    isEditMode && initialCredential?.has_api_key
      ? `Stored API key ${initialCredential.api_key_last_four ? `ending ${initialCredential.api_key_last_four}` : "is set"}. Leave blank to keep it.`
      : null;
  const existingSessionKeyLabel =
    isEditMode && initialCredential?.has_session_key
      ? `Stored subscription token ${initialCredential.session_key_last_four ? `ending ${initialCredential.session_key_last_four}` : "is set"}. Leave blank to keep it.`
      : null;

  const runTest = async () => {
    setIsTesting(true);
    setTestResult(null);
    setTestError(null);
    try {
      const result = await onTest({
        account_key: accountKey.trim() || accountKeyDefault || "test",
        display_name: displayName.trim(),
        api_key: apiKey.trim(),
        session_key: sessionKey.trim(),
        base_url: baseUrl.trim(),
      });
      setTestResult(result);
    } catch (err) {
      setTestError(err instanceof Error ? err.message : "Test failed.");
    } finally {
      setIsTesting(false);
    }
  };

  return (
    <div className="mt-3 rounded-xl border border-[color:var(--border)] bg-[color:var(--surface-muted)] p-4">
      <div className="space-y-3">
        {allowMultiple && (
          <div>
            <label className="mb-1 block text-xs font-medium text-muted">
              Account name <span className="text-[color:var(--danger)]">*</span>
            </label>
            <Input
              value={accountKey}
              onChange={(e) => setAccountKey(e.target.value)}
              placeholder="e.g. work, personal, gpu-box"
              disabled={isSaving || isEditMode}
            />
            <p className="mt-1 text-[11px] text-muted">
              {isEditMode
                ? "Account keys are fixed after creation."
                : "Used to tell accounts apart in cost reports."}
            </p>
          </div>
        )}
        <div>
          <label className="mb-1 block text-xs font-medium text-muted">
            {isEditMode ? "Display name" : "Display name (optional)"}
          </label>
          <Input
            value={displayName}
            onChange={(e) => setDisplayName(e.target.value)}
            placeholder={accountKey || "My account"}
            disabled={isSaving}
          />
        </div>
        {showBaseUrl && (
          <div>
            <div className="mb-1 flex items-center justify-between">
              <label className="text-xs font-medium text-muted">
                Base URL <span className="text-[color:var(--danger)]">*</span>
              </label>
              {apiKeyHelp?.length && (
                <HelpToggle
                  steps={apiKeyHelp}
                  open={showApiHelp}
                  onToggle={() => setShowApiHelp((v) => !v)}
                />
              )}
            </div>
            <Input
              value={baseUrl}
              onChange={(e) => setBaseUrl(e.target.value)}
              placeholder="http://localhost:11434"
              disabled={isSaving}
            />
            {showApiHelp && apiKeyHelp?.length ? (
              <HelpSection steps={apiKeyHelp} />
            ) : null}
          </div>
        )}
        <div>
          <div className="mb-1 flex items-center justify-between">
            <label className="text-xs font-medium text-muted">{keyLabel}</label>
            {!showBaseUrl && apiKeyHelp?.length ? (
              <HelpToggle
                steps={apiKeyHelp}
                open={showApiHelp}
                onToggle={() => setShowApiHelp((v) => !v)}
              />
            ) : null}
          </div>
          <Input
            type="password"
            value={apiKey}
            onChange={(e) => setApiKey(e.target.value)}
            placeholder={keyPlaceholder}
            disabled={isSaving}
            autoComplete="new-password"
          />
          {existingApiKeyLabel && (
            <p className="mt-1 text-[11px] text-muted">{existingApiKeyLabel}</p>
          )}
          {showApiHelp && !showBaseUrl && apiKeyHelp?.length ? (
            <HelpSection steps={apiKeyHelp} />
          ) : null}
        </div>
        {showSessionKey && (
          <div>
            {autoDetectedNote && (
              <div className="mb-2 flex items-start gap-2 rounded-lg border border-[color:rgba(52,211,153,0.3)] bg-[color:rgba(52,211,153,0.07)] px-3 py-2.5">
                <CheckCircle2 className="mt-0.5 h-3.5 w-3.5 shrink-0 text-[color:var(--success)]" />
                <p className="text-[11px] leading-relaxed text-muted">{autoDetectedNote}</p>
              </div>
            )}
            <div className="mb-1 flex items-center justify-between">
              <label className="text-xs font-medium text-muted">{sessionKeyLabel}</label>
              {sessionKeyHelp?.length ? (
                <HelpToggle
                  steps={sessionKeyHelp}
                  open={showSessionHelp}
                  onToggle={() => setShowSessionHelp((v) => !v)}
                />
              ) : null}
            </div>
            <Input
              type="password"
              value={sessionKey}
              onChange={(e) => setSessionKey(e.target.value)}
              placeholder={sessionKeyPlaceholder}
              disabled={isSaving}
              autoComplete="new-password"
            />
            {existingSessionKeyLabel && (
              <p className="mt-1 text-[11px] text-muted">
                {existingSessionKeyLabel}
              </p>
            )}
            {showSessionHelp && sessionKeyHelp?.length ? (
              <HelpSection steps={sessionKeyHelp} />
            ) : null}
          </div>
        )}
        {error && (
          <p className="text-sm text-[color:var(--danger)]">{error}</p>
        )}
        <div className="flex gap-2">
          <Button
            variant="outline"
            size="sm"
            disabled={isSaving || isTesting || !canTest}
            onClick={runTest}
          >
            {isTesting ? (
              <Loader2 className="mr-1.5 h-3.5 w-3.5 animate-spin" />
            ) : (
              <RefreshCw className="mr-1.5 h-3.5 w-3.5" />
            )}
            {isTesting ? "Testing…" : "Test connection"}
          </Button>
          <Button
            size="sm"
            disabled={isSaving || !accountKey.trim() || (showBaseUrl && !baseUrl.trim())}
            onClick={() =>
              onSave({
                account_key: accountKey.trim(),
                display_name: displayName.trim(),
                api_key: apiKey.trim(),
                session_key: sessionKey.trim(),
                base_url: baseUrl.trim(),
              })
            }
          >
            {isSaving ? (
              <Loader2 className="mr-1.5 h-3.5 w-3.5 animate-spin" />
            ) : (
              <KeyRound className="mr-1.5 h-3.5 w-3.5" />
            )}
            {isSaving ? "Saving…" : "Save"}
          </Button>
          <Button variant="outline" size="sm" onClick={onCancel} disabled={isSaving}>
            <X className="mr-1.5 h-3.5 w-3.5" />
            Cancel
          </Button>
        </div>
        {testError && (
          <p className="text-sm text-[color:var(--danger)]">{testError}</p>
        )}
        {testResult && (
          <div
            className={`rounded-lg border p-3 text-xs ${
              testResult.reachable
                ? "border-[color:rgba(52,211,153,0.35)] bg-[color:rgba(52,211,153,0.08)]"
                : "border-[color:rgba(248,113,113,0.35)] bg-[color:rgba(248,113,113,0.08)]"
            }`}
          >
            <p
              className={`font-medium ${
                testResult.reachable
                  ? "text-[color:var(--success)]"
                  : "text-[color:var(--danger)]"
              }`}
            >
              {testResult.reachable ? "Connection successful" : "Connection failed"}
            </p>
            <p className="mt-1 text-muted">
              {testResult.error ??
                (testResult.sample_input_tokens != null ||
                testResult.sample_output_tokens != null
                  ? `Usage probe: in ${fmtTokens(testResult.sample_input_tokens)} · out ${fmtTokens(testResult.sample_output_tokens)}`
                  : "Connected.")}
            </p>
            {testResult.sample_latency_ms != null && (
              <p className="mt-1 text-muted">
                Probe time: {fmtLatencyMs(testResult.sample_latency_ms)}
              </p>
            )}
          </div>
        )}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Usage strip — live token data fetched from the provider
// ---------------------------------------------------------------------------

function fmtTokens(n: number | null | undefined): string {
  if (n == null) return "—";
  if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
  if (n >= 1_000) return `${(n / 1_000).toFixed(0)}k`;
  return n.toString();
}

function fmtResetMs(ms: number | null | undefined): string {
  if (ms == null || ms <= 0) return "< 1m";
  const totalMinutes = Math.floor(ms / 60000);
  const d = Math.floor(totalMinutes / (60 * 24));
  const h = Math.floor((totalMinutes % (60 * 24)) / 60);
  const m = totalMinutes % 60;
  const parts: string[] = [];
  if (d > 0) parts.push(`${d}d`);
  if (h > 0) parts.push(`${h}hrs`);
  if (m > 0 || parts.length === 0) parts.push(`${m}m`);
  return parts.join(" ");
}

function fmtResetDate(ms: number | null | undefined): string | null {
  if (ms == null || ms <= 0) return null;
  const resetAt = new Date(Date.now() + ms);
  return resetAt.toLocaleString(undefined, {
    month: "short",
    day: "numeric",
    hour: "numeric",
    minute: "2-digit",
  });
}

function fmtLatencyMs(ms: number | null | undefined): string {
  if (ms == null || ms < 0) return "—";
  if (ms < 1000) return `${ms}ms`;
  return `${(ms / 1000).toFixed(2)}s`;
}

function usageBarColor(pct: number): string {
  if (pct > 90) return "bg-[color:var(--danger)]";
  if (pct > 75) return "bg-[color:var(--warning)]";
  return "bg-[color:var(--success)]";
}

function fmtPct(pct: number): string {
  return `${Math.max(0, Math.min(100, pct)).toFixed(0)}%`;
}

interface UsageWindowBarProps {
  label: string;
  pct: number;
  resetInMs?: number | null;
  badge?: string;
}

function UsageWindowBar({ label, pct, resetInMs, badge }: UsageWindowBarProps) {
  const clamped = Math.max(0, Math.min(100, pct));
  const resetDate = fmtResetDate(resetInMs);
  return (
    <div className="space-y-1">
      <div className="flex items-center justify-between text-[11px]">
        <span className="flex items-center gap-1.5 font-medium text-muted">
          {label}
          {badge && (
            <span className="rounded-full bg-[color:rgba(99,102,241,0.15)] px-1.5 py-px text-[10px] font-medium text-[color:var(--accent)]">
              {badge}
            </span>
          )}
        </span>
        <span className="tabular-nums text-strong">{fmtPct(clamped)} used</span>
      </div>
      <div className="h-1.5 overflow-hidden rounded-full bg-[color:var(--surface-strong)]">
        <div
          className={`h-full rounded-full transition-all ${usageBarColor(clamped)}`}
          style={{ width: `${clamped}%` }}
        />
      </div>
      <p className="text-[11px] text-muted">
        Resets in {fmtResetMs(resetInMs)}
        {resetDate && (
          <span className="ml-1 text-[color:var(--text-quiet)]">· Full reset at {resetDate}</span>
        )}
      </p>
    </div>
  );
}

function fmtElapsed(since: Date, now: number): string {
  const s = Math.round((now - since.getTime()) / 1000);
  if (s < 60) return `${s}s ago`;
  return `${Math.floor(s / 60)}m ago`;
}

function UsageStrip({ credentialId, provider }: { credentialId: string; provider: string }) {
  const [usage, setUsage] = useState<ProviderUsageLiveRead | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [lastFetched, setLastFetched] = useState<Date | null>(null);
  const [now, setNow] = useState(Date.now());

  useEffect(() => {
    const id = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(id);
  }, []);

  const fetchUsage = useCallback(
    async (refresh = false) => {
      setLoading(true);
      setError(null);
      try {
        if (refresh && provider !== "ollama") {
          await customFetch<unknown>(
            "/api/v1/provider-credentials/rescan-local",
            { method: "POST" },
          );
        }
        const res = await getProviderUsageLiveApiV1ProviderCredentialsCredentialIdUsageGet(
          credentialId,
          refresh ? { refresh: true } : undefined,
        );
        if (res.status === 200) {
          setUsage(res.data);
          setLastFetched(new Date());
        }
      } catch (err) {
        setError(err instanceof Error ? err.message : "Failed to fetch usage.");
      } finally {
        setLoading(false);
      }
    },
    [credentialId, provider],
  );

  useEffect(() => {
    void fetchUsage();
  }, [fetchUsage]);

  if (loading && !usage) {
    return (
      <div className="mt-2 flex items-center gap-2 text-xs text-muted">
        <Loader2 className="h-3 w-3 animate-spin" />
        Fetching live usage…
      </div>
    );
  }

  if (!usage?.reachable) {
    return (
      <div className="mt-2 flex items-center gap-2 text-xs text-[color:var(--danger)]">
        <span>{usage?.error ?? error ?? "Provider unreachable."}</span>
        <button
          type="button"
          onClick={() => fetchUsage(true)}
          className="ml-1 underline hover:opacity-70"
        >
          Retry
        </button>
      </div>
    );
  }

  const tok = usage.tokens;
  const inputTok = usage.input_tokens;
  const outputTok = usage.output_tokens;
  const req = usage.requests;
  const subWindows = usage.subscription_windows ?? [];
  const isOllama = provider === "ollama";

  const sourceLabel: Record<string, string> = {
    provider_native: "Provider native",
    provider_api_rate_limit: "API rate limit",
    local_jsonl_estimate: "Local estimate",
    configured_limit: "Configured limit",
  };

  // output_tokens is the tightest Anthropic limit (90k/min vs 540k combined)
  const usageBars: UsageWindowBarProps[] = [];
  if (outputTok?.pct_used != null) {
    usageBars.push({
      label: "Output tokens",
      pct: outputTok.pct_used,
      resetInMs: outputTok.reset_in_ms,
      badge: "rate limit",
    });
  }
  if (inputTok.pct_used != null) {
    usageBars.push({
      label: "Input tokens",
      pct: inputTok.pct_used,
      resetInMs: inputTok.reset_in_ms,
      badge: "rate limit",
    });
  }
  if (tok.pct_used != null) {
    usageBars.push({
      label: "Tokens combined",
      pct: tok.pct_used,
      resetInMs: tok.reset_in_ms,
      badge: "rate limit",
    });
  }
  if (usageBars.length === 0 && req.limit != null && req.remaining != null && req.limit > 0) {
    usageBars.push({
      label: "Requests",
      pct: ((req.limit - req.remaining) / req.limit) * 100,
      resetInMs: req.reset_in_ms,
      badge: "rate limit",
    });
  }

  // Only show rate-limit bars when something is actually being consumed.
  // 0% bars with "resets in < 1m" are meaningless noise when idle.
  const activeBars = usageBars.filter((b) => b.pct > 0);

  return (
    <div className="mt-2 rounded-lg border border-[color:var(--border)] bg-[color:var(--surface)] p-2.5">
      {usage.error && (
        <div className="mb-2 rounded border border-[color:rgba(248,113,113,0.35)] bg-[color:rgba(248,113,113,0.08)] px-2 py-1.5 text-xs text-[color:var(--danger)]">
          {usage.error}
        </div>
      )}

      {/* ── Subscription usage windows (plan-level usage from OAuth) ── */}
      {subWindows.length > 0 && (
        <div className="mb-3 space-y-2.5">
          <div className="flex items-center gap-1.5 text-[11px] text-muted">
            <CheckCircle2 className="h-3 w-3 text-[color:var(--success)]" />
            <span className="font-medium">Subscription usage</span>
            {usage.subscription_plan && (
              <span className="rounded-full bg-[color:rgba(52,211,153,0.15)] px-1.5 py-px text-[10px] font-medium text-[color:var(--success)]">
                {usage.subscription_plan}
              </span>
            )}
          </div>
          {subWindows.map((w) => (
            <UsageWindowBar
              key={w.key}
              label={w.label}
              pct={w.pct_used}
              resetInMs={w.reset_in_ms}
            />
          ))}
        </div>
      )}

      {isOllama ? (
        <div className="space-y-1.5">
          <div className="flex items-center gap-3 text-xs text-muted">
            <span className="flex items-center gap-1 text-[color:var(--success)]">
              <span className="inline-block h-1.5 w-1.5 rounded-full bg-[color:var(--success)]" />
              Connected
            </span>
            {(usage.models?.length ?? 0) > 0 && (
              <span>
                {usage.models!.length} model{usage.models!.length !== 1 ? "s" : ""} available
              </span>
            )}
            <button
              type="button"
              onClick={() => fetchUsage(true)}
              className="ml-auto text-muted hover:text-strong"
            >
              <RefreshCw className={`h-3 w-3 ${loading ? "animate-spin" : ""}`} />
            </button>
          </div>
          {(usage.sample_input_tokens != null || usage.sample_output_tokens != null) && (
            <div className="flex items-center justify-between text-[11px] text-muted">
              <span>Usage (last probe)</span>
              <span className="tabular-nums text-strong">
                in {fmtTokens(usage.sample_input_tokens)} · out{" "}
                {fmtTokens(usage.sample_output_tokens)}
              </span>
            </div>
          )}
          {usage.sample_latency_ms != null && (
            <div className="flex items-center justify-between text-[11px] text-muted">
              <span>Time (last probe)</span>
              <span className="tabular-nums text-strong">
                {fmtLatencyMs(usage.sample_latency_ms)}
              </span>
            </div>
          )}
          <div className="flex items-center justify-between text-[11px] text-muted">
            {lastFetched && (
              <span>Updated {fmtElapsed(lastFetched, now)}</span>
            )}
          </div>
        </div>
      ) : (
        <div className="space-y-1.5">
          {/* API rate-limit diagnostic bars — only shown when actively consuming the limit */}
          {activeBars.length > 0 ? (
            <>
              <div className="text-[11px] text-muted">
                {sourceLabel[usage.source] ?? usage.source} · {usage.confidence} confidence
              </div>
              <div className="space-y-2">
                {activeBars.map((bar) => (
                  <UsageWindowBar
                    key={bar.label}
                    label={bar.label}
                    pct={bar.pct}
                    resetInMs={bar.resetInMs}
                    badge={bar.badge}
                  />
                ))}
              </div>
            </>
          ) : subWindows.length === 0 ? (
            <>
              {(usage.sample_input_tokens != null || usage.sample_output_tokens != null) && (
                <div className="flex items-center justify-between text-[11px] text-muted">
                  <span>Usage (last probe)</span>
                  <span className="tabular-nums text-strong">
                    in {fmtTokens(usage.sample_input_tokens)} · out{" "}
                    {fmtTokens(usage.sample_output_tokens)}
                  </span>
                </div>
              )}
              {usage.sample_latency_ms != null && (
                <div className="flex items-center justify-between text-[11px] text-muted">
                  <span>Time (last probe)</span>
                  <span className="tabular-nums text-strong">
                    {fmtLatencyMs(usage.sample_latency_ms)}
                  </span>
                </div>
              )}
              <p className="text-[11px] text-muted">
                Connected — no rate-limit window data returned by provider.
              </p>
            </>
          ) : null}

          <div className="flex items-center justify-between text-[11px] text-muted">
            {lastFetched && (
              <span>Updated {fmtElapsed(lastFetched, now)}</span>
            )}
            <button
              type="button"
              onClick={() => fetchUsage(true)}
              className="ml-auto flex items-center gap-1 hover:text-strong"
            >
              <RefreshCw className={`h-3 w-3 ${loading ? "animate-spin" : ""}`} />
              Refresh
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Credential row
// ---------------------------------------------------------------------------

interface CredentialRowProps {
  cred: ProviderCredentialRead;
  isAdmin: boolean;
  onEdit: (cred: ProviderCredentialRead) => void;
  onDelete: (cred: ProviderCredentialRead) => void;
  onToggle: (cred: ProviderCredentialRead) => Promise<void>;
  showUsage?: boolean;
}

function CredentialRow({
  cred,
  isAdmin,
  onEdit,
  onDelete,
  onToggle,
  showUsage = true,
}: CredentialRowProps) {
  const [toggling, setToggling] = useState(false);
  return (
    <div
      className={`rounded-lg border px-3 py-2.5 ${
        cred.active
          ? "border-[color:var(--border)] bg-[color:var(--surface-muted)]"
          : "border-[color:var(--border)] bg-[color:var(--surface)] opacity-60"
      }`}
    >
      <div className="flex min-w-0 items-center gap-3">
        <div className="min-w-0 flex-1">
          <p className="truncate text-sm font-medium text-strong">
            {cred.display_name || cred.account_key}
          </p>
          <div className="mt-0.5 flex flex-wrap gap-x-3 gap-y-0 text-[11px] text-muted">
            <span>key: {cred.account_key}</span>
            {cred.has_api_key && cred.api_key_last_four ? (
              <span className="flex items-center gap-1">
                <KeyRound className="h-3 w-3" />
                ••••{cred.api_key_last_four}
              </span>
            ) : cred.has_api_key ? (
              <span className="flex items-center gap-1">
                <KeyRound className="h-3 w-3" />
                set
              </span>
            ) : (
              <span className="text-[color:var(--warning)]">no API key</span>
            )}
            {cred.has_session_key && (
              <span className="flex items-center gap-1 text-[color:var(--success)]">
                <CheckCircle2 className="h-3 w-3" />
                subscription token ••••{cred.session_key_last_four ?? ""}
              </span>
            )}
            {cred.base_url && (
              <span className="max-w-[200px] truncate">{cred.base_url}</span>
            )}
          </div>
        </div>
        {isAdmin && (
          <div className="flex shrink-0 items-center gap-1.5">
            {cred.active && (
              <Button
                variant="ghost"
                size="sm"
                className="h-7 w-7 p-0"
                onClick={() => onEdit(cred)}
                aria-label={`Edit ${cred.display_name || cred.account_key}`}
                title="Edit provider"
              >
                <Pencil className="h-3.5 w-3.5" />
              </Button>
            )}
            <button
              type="button"
              onClick={async () => {
                setToggling(true);
                await onToggle(cred);
                setToggling(false);
              }}
              disabled={toggling}
              className={`rounded-full px-2 py-0.5 text-[11px] font-medium transition ${
                cred.active
                  ? "bg-[color:rgba(52,211,153,0.15)] text-[color:var(--success)] hover:opacity-80"
                  : "bg-[color:var(--surface-strong)] text-muted hover:opacity-80"
              }`}
            >
              {toggling ? "…" : cred.active ? "Active" : "Inactive"}
            </button>
            <Button
              variant="ghost"
              size="sm"
              className="h-7 w-7 p-0 text-[color:var(--danger)] hover:bg-[color:var(--danger-soft)]"
              onClick={() => onDelete(cred)}
            >
              <Trash2 className="h-3.5 w-3.5" />
            </Button>
          </div>
        )}
      </div>
      {showUsage && cred.active && (cred.has_api_key || cred.base_url) && (
        <UsageStrip credentialId={cred.id} provider={cred.provider} />
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Provider section
// ---------------------------------------------------------------------------

interface ProviderSectionProps {
  provider: ProviderConfig;
  credentials: ProviderCredentialRead[];
  isAdmin: boolean;
  onAdd: (
    providerId: ProviderId,
    data: CredentialFormData,
  ) => Promise<void>;
  onUpdate: (
    providerId: ProviderId,
    cred: ProviderCredentialRead,
    data: CredentialFormData,
  ) => Promise<void>;
  onTest: (
    providerId: ProviderId,
    data: CredentialFormData,
  ) => Promise<ProviderUsageLiveRead>;
  onDelete: (cred: ProviderCredentialRead) => void;
  onToggle: (cred: ProviderCredentialRead) => Promise<void>;
}

function ProviderSection({
  provider,
  credentials,
  isAdmin,
  onAdd,
  onUpdate,
  onTest,
  onDelete,
  onToggle,
}: ProviderSectionProps) {
  const Icon = provider.icon;
  const [showForm, setShowForm] = useState(false);
  const [editingCredentialId, setEditingCredentialId] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  const [saveError, setSaveError] = useState<string | null>(null);

  const canAdd = isAdmin && (provider.allowMultiple || credentials.length === 0);
  const editingCredential = credentials.find((cred) => cred.id === editingCredentialId);

  return (
    <section className="rounded-xl border border-[color:var(--border)] bg-[color:var(--surface)] p-4 shadow-lush md:p-5">
      <div className="flex items-start justify-between gap-3">
        <div className="flex min-w-0 items-start gap-3">
          <div className="rounded-lg border border-[color:var(--border)] bg-[color:var(--surface-muted)] p-2 text-[color:var(--accent)] shrink-0">
            <Icon className="h-4 w-4" />
          </div>
          <div className="min-w-0">
            <h2 className="text-base font-semibold text-strong">{provider.label}</h2>
            <p className="mt-0.5 text-sm text-muted">{provider.description}</p>
          </div>
        </div>
        {canAdd && !showForm && (
          <Button
            size="sm"
            variant="outline"
            onClick={() => {
              setShowForm(true);
              setEditingCredentialId(null);
              setSaveError(null);
            }}
          >
            <Plus className="h-3.5 w-3.5" />
            Add
          </Button>
        )}
      </div>

      {showForm && (
        <CredentialForm
          allowMultiple={provider.allowMultiple}
          showBaseUrl={provider.showBaseUrl}
          showSessionKey={provider.showSessionKey}
          sessionKeyLabel={provider.sessionKeyLabel}
          sessionKeyPlaceholder={provider.sessionKeyPlaceholder}
          keyLabel={provider.keyLabel}
          keyPlaceholder={provider.keyPlaceholder}
          accountKeyDefault={provider.accountKeyDefault}
          apiKeyHelp={provider.apiKeyHelp}
          sessionKeyHelp={provider.sessionKeyHelp}
          autoDetectedNote={provider.autoDetectedNote}
          onSave={async (data) => {
            setSaving(true);
            setSaveError(null);
            try {
              await onAdd(provider.id, data);
              setShowForm(false);
            } catch (err) {
              setSaveError(err instanceof Error ? err.message : "Save failed.");
            } finally {
              setSaving(false);
            }
          }}
          onTest={(data) => onTest(provider.id, data)}
          onCancel={() => setShowForm(false)}
          isSaving={saving}
          error={saveError}
        />
      )}

      {credentials.length > 0 && (
        <div className="mt-3 space-y-2">
          {credentials.map((cred) => (
            <div key={cred.id} className="space-y-2">
              <CredentialRow
                cred={cred}
                isAdmin={isAdmin}
                onEdit={(target) => {
                  setShowForm(false);
                  setSaveError(null);
                  setEditingCredentialId(target.id);
                }}
                onDelete={onDelete}
                onToggle={onToggle}
              />
              {cred.active && editingCredential?.id === cred.id && (
                <CredentialForm
                  mode="edit"
                  initialCredential={cred}
                  allowMultiple={provider.allowMultiple}
                  showBaseUrl={provider.showBaseUrl}
                  showSessionKey={provider.showSessionKey}
                  sessionKeyLabel={provider.sessionKeyLabel}
                  sessionKeyPlaceholder={provider.sessionKeyPlaceholder}
                  keyLabel={provider.keyLabel}
                  keyPlaceholder={provider.keyPlaceholder}
                  accountKeyDefault={provider.accountKeyDefault}
                  apiKeyHelp={provider.apiKeyHelp}
                  sessionKeyHelp={provider.sessionKeyHelp}
                  autoDetectedNote={provider.autoDetectedNote}
                  onSave={async (data) => {
                    setSaving(true);
                    setSaveError(null);
                    try {
                      await onUpdate(provider.id, cred, data);
                      setEditingCredentialId(null);
                    } catch (err) {
                      setSaveError(err instanceof Error ? err.message : "Save failed.");
                    } finally {
                      setSaving(false);
                    }
                  }}
                  onTest={(data) => onTest(provider.id, data)}
                  onCancel={() => setEditingCredentialId(null)}
                  isSaving={saving}
                  error={saveError}
                />
              )}
            </div>
          ))}
        </div>
      )}

      {credentials.length === 0 && !showForm && (
        <p className="mt-3 text-sm text-muted">
          No {provider.label} accounts configured.
          {isAdmin ? " Click Add to set one up." : ""}
        </p>
      )}
    </section>
  );
}

// ---------------------------------------------------------------------------
// Page
// ---------------------------------------------------------------------------

export default function AIProvidersSettingsPage() {
  const { isSignedIn } = useAuth();
  const { isAdmin } = useOrganizationMembership(isSignedIn);
  const [credentials, setCredentials] = useState<ProviderCredentialRead[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<ProviderCredentialRead | null>(null);
  const [isDeleting, setIsDeleting] = useState(false);
  const [deleteError, setDeleteError] = useState<string | null>(null);

  const load = useCallback(async () => {
    try {
      setIsLoading(true);
      const res = await listProviderCredentialsApiV1ProviderCredentialsGet();
      if (res.status === 200) setCredentials(res.data);
      setError(null);
    } catch (err) {
      setError(
        err instanceof Error ? err.message : "Could not load provider settings.",
      );
    } finally {
      setIsLoading(false);
    }
  }, []);

  useEffect(() => {
    if (isSignedIn) void load();
  }, [isSignedIn, load]);

  const handleAdd = async (
    providerId: ProviderId,
    data: CredentialFormData,
  ) => {
    const res = await createProviderCredentialApiV1ProviderCredentialsPost({
      provider: providerId,
      account_key: data.account_key,
      display_name: data.display_name || data.account_key,
      api_key: data.api_key || undefined,
      session_key: data.session_key || undefined,
      base_url: data.base_url || undefined,
    });
    if (res.status === 201) {
      setCredentials((prev) => [...prev, res.data]);
      announceProviderCredentialsUpdated();
    } else {
      throw new Error("Failed to save credential.");
    }
  };

  const handleTest = async (
    providerId: ProviderId,
    data: CredentialFormData,
  ): Promise<ProviderUsageLiveRead> => {
    const response = await customFetch<{
      data: ProviderUsageLiveRead;
      status: number;
      headers: Headers;
    }>("/api/v1/provider-credentials/test", {
      method: "POST",
      body: JSON.stringify({
        provider: providerId,
        account_key: data.account_key || "test",
        api_key: data.api_key || undefined,
        session_key: data.session_key || undefined,
        base_url: data.base_url || undefined,
      }),
    });
    return response.data;
  };

  const handleUpdate = async (
    providerId: ProviderId,
    cred: ProviderCredentialRead,
    data: CredentialFormData,
  ) => {
    const provider = PROVIDERS.find((item) => item.id === providerId);
    const displayName = data.display_name.trim() || cred.account_key;
    const apiKey = data.api_key.trim();
    const sessionKey = data.session_key.trim();
    const baseUrl = data.base_url.trim();
    const payload: ProviderCredentialUpdateWithSession = {};

    if (displayName !== cred.display_name) {
      payload.display_name = displayName;
    }
    if (apiKey) {
      payload.api_key = apiKey;
    }
    if (sessionKey) {
      payload.session_key = sessionKey;
    }
    if (provider?.showBaseUrl && baseUrl !== (cred.base_url ?? "")) {
      payload.base_url = baseUrl;
    }

    const res = await updateProviderCredentialApiV1ProviderCredentialsCredentialIdPatch(
      cred.id,
      payload,
    );
    if (res.status === 200) {
      setCredentials((prev) => prev.map((c) => (c.id === cred.id ? res.data : c)));
      announceProviderCredentialsUpdated();
    } else {
      throw new Error("Failed to update credential.");
    }
  };

  const handleToggle = async (cred: ProviderCredentialRead) => {
    const res = await updateProviderCredentialApiV1ProviderCredentialsCredentialIdPatch(
      cred.id,
      { active: !cred.active },
    );
    if (res.status === 200) {
      setCredentials((prev) => prev.map((c) => (c.id === cred.id ? res.data : c)));
      announceProviderCredentialsUpdated();
    }
  };

  const handleDelete = async () => {
    if (!deleteTarget) return;
    setIsDeleting(true);
    setDeleteError(null);
    try {
      await deleteProviderCredentialApiV1ProviderCredentialsCredentialIdDelete(deleteTarget.id);
      setCredentials((prev) => prev.filter((c) => c.id !== deleteTarget.id));
      announceProviderCredentialsUpdated();
      setDeleteTarget(null);
    } catch (err) {
      setDeleteError(err instanceof Error ? err.message : "Delete failed.");
    } finally {
      setIsDeleting(false);
    }
  };

  return (
    <>
      <DashboardPageLayout
        signedOut={{
          message: "Sign in to manage AI provider settings.",
          forceRedirectUrl: "/settings/ai-providers",
          signUpForceRedirectUrl: "/settings/ai-providers",
        }}
        title="AI Providers"
        description="Configure API keys and subscription tokens for the AI providers your gateway uses."
      >
        {isLoading ? (
          <div className="flex items-center gap-2 rounded-xl border border-[color:var(--border)] bg-[color:var(--surface)] p-6 text-sm text-muted">
            <Loader2 className="h-4 w-4 animate-spin" />
            Loading provider settings…
          </div>
        ) : error ? (
          <div className="rounded-xl border border-[color:rgba(248,113,113,0.35)] bg-[color:rgba(248,113,113,0.08)] p-4 text-sm text-[color:var(--danger)]">
            {error}
          </div>
        ) : (
          <div className="space-y-4">
            {!isAdmin && (
              <div className="rounded-xl border border-[color:var(--border)] bg-[color:var(--surface-muted)] p-3 text-sm text-muted">
                You can view provider settings. Only org admins can add or change credentials.
              </div>
            )}
            {PROVIDERS.map((provider) => (
              <ProviderSection
                key={provider.id}
                provider={provider}
                credentials={credentials.filter((c) => c.provider === provider.id)}
                isAdmin={isAdmin}
                onAdd={handleAdd}
                onUpdate={handleUpdate}
                onTest={handleTest}
                onDelete={setDeleteTarget}
                onToggle={handleToggle}
              />
            ))}
          </div>
        )}
      </DashboardPageLayout>

      <ConfirmActionDialog
        open={Boolean(deleteTarget)}
        onOpenChange={(open) => {
          if (!open) setDeleteTarget(null);
        }}
        title="Remove provider account"
        description={
          deleteTarget
            ? `Remove "${deleteTarget.display_name || deleteTarget.account_key}" (${deleteTarget.provider})? The stored key will be deleted and cannot be recovered.`
            : ""
        }
        onConfirm={handleDelete}
        isConfirming={isDeleting}
        errorMessage={deleteError}
        confirmLabel="Remove account"
        confirmingLabel="Removing…"
        confirmClassName="bg-destructive text-destructive-foreground hover:bg-destructive/90"
        cancelLabel="Keep it"
      />
    </>
  );
}
