// ============================================
// Reliq — Settings / API & Webhooks page
// Step 7 — API key + webhook mock lifecycle
// ============================================

// ── Module-level constants ────────────────────────────────────────────────────
const API_KEYS_STORE   = "reliq_api_keys";
const WEBHOOKS_STORE   = "reliq_webhook_endpoints";
const DELIVERIES_STORE = "reliq_webhook_deliveries";

// All 10 supported webhook event types
const WEBHOOK_EVENTS = [
  { id: "scan.completed",         label: "Scan completed" },
  { id: "scan.failed",            label: "Scan failed" },
  { id: "report.generated",       label: "Report generated" },
  { id: "report.shared",          label: "Report shared" },
  { id: "finding.critical",       label: "Critical finding detected" },
  { id: "api.key.created",        label: "API key created" },
  { id: "api.key.revoked",        label: "API key revoked" },
  { id: "billing.trial_ending",   label: "Trial ending soon" },
  { id: "billing.payment_failed", label: "Payment failed" },
  { id: "github.check_failed",    label: "GitHub check failed" },
];

// ── Helper functions ──────────────────────────────────────────────────────────
const apiRandHex = (n) =>
  Array.from({ length: n }, () => "0123456789abcdef"[Math.floor(Math.random() * 16)]).join("");

const generateKeyValue = (env) => `rq_${env}_mock_${apiRandHex(12)}`;

const maskKey = (full) => {
  // rq_live_mock_xxxxxxxx  →  rq_live_mock_••••••••xxxx
  const lastUnderscore = full.lastIndexOf("_");
  return `${full.slice(0, lastUnderscore + 1)}${"•".repeat(8)}${full.slice(-4)}`;
};

const generateSecret = () => `whsec_mock_${apiRandHex(12)}`;

const maskSecret = (s) => `${s.slice(0, 12)}${"•".repeat(10)}${s.slice(-4)}`;

const loadStore = (key, initial) => {
  try {
    const raw = localStorage.getItem(key);
    if (raw) return JSON.parse(raw);
  } catch (_) {}
  return initial;
};

const saveStore = (key, val) => {
  try { localStorage.setItem(key, JSON.stringify(val)); } catch (_) {}
};

// ── Initial mock data ─────────────────────────────────────────────────────────
const INITIAL_API_KEYS = [
  {
    id: "key_1",
    name: "Production CI",
    prefix: "rq_live",
    maskedValue: "rq_live_mock_••••••••n9pa",
    fullValue: null,
    environment: "live",
    createdAt: "2025-08-14",
    lastUsedAt: "2 min ago",
    status: "active",
    scopes: ["scan:write", "report:read"],
    createdBy: "zola@holt.africa",
    isMock: true,
  },
  {
    id: "key_2",
    name: "Local development",
    prefix: "rq_test",
    maskedValue: "rq_test_mock_••••••••h2kq",
    fullValue: null,
    environment: "test",
    createdAt: "2025-08-02",
    lastUsedAt: "3 days ago",
    status: "active",
    scopes: ["scan:write", "scan:read", "report:read"],
    createdBy: "zola@holt.africa",
    isMock: true,
  },
];

const INITIAL_ENDPOINTS = [
  {
    id: "wh_1",
    url: "https://api.roamly.app/internal/reliq/webhook",
    events: ["scan.completed", "report.generated"],
    signingSecret: "whsec_mock_3kqmn9pa7vxr",
    status: "enabled",
    createdAt: "2025-08-14",
    lastDeliveryAt: "2 min ago",
    failureCount: 0,
    isMock: true,
  },
];

const INITIAL_DELIVERIES = [
  { id: "del_1", endpointId: "wh_1", endpointUrl: "https://api.roamly.app/internal/reliq/webhook", event: "scan.completed",   status: "succeeded", responseCode: 200, timestamp: "2 min ago",   attempt: 1, durationMs: 142,  payloadId: "pay_2k8x", isMock: true },
  { id: "del_2", endpointId: "wh_1", endpointUrl: "https://api.roamly.app/internal/reliq/webhook", event: "report.generated", status: "succeeded", responseCode: 200, timestamp: "15 min ago",  attempt: 1, durationMs: 98,   payloadId: "pay_2k8r", isMock: true },
  { id: "del_3", endpointId: "wh_1", endpointUrl: "https://api.roamly.app/internal/reliq/webhook", event: "scan.completed",   status: "failed",    responseCode: 503, timestamp: "2 hours ago", attempt: 3, durationMs: 3001, payloadId: "pay_2k8w", isMock: true },
];

// ── Sub-components ────────────────────────────────────────────────────────────
const RestrictedBanner = ({ message }) => (
  <div style={{
    display: "flex", alignItems: "center", gap: 10,
    padding: "10px 16px", marginBottom: 16,
    background: "rgba(245,158,11,0.08)",
    border: "1px solid var(--amber, #f59e0b)",
    borderRadius: 8, fontSize: 13, color: "var(--amber, #f59e0b)",
  }}>
    <Icon name="alert" size={14} />
    <span>{message}</span>
  </div>
);

const MockBadge = () => (
  <span style={{
    display: "inline-flex", alignItems: "center",
    padding: "2px 7px", borderRadius: 4,
    background: "rgba(245,158,11,0.1)",
    border: "1px solid var(--amber, #f59e0b)",
    fontSize: 10.5, fontWeight: 600, color: "var(--amber, #f59e0b)",
    letterSpacing: "0.04em", textTransform: "uppercase", marginLeft: 6,
    verticalAlign: "middle",
  }}>mock</span>
);

// ── Main component ────────────────────────────────────────────────────────────
const Settings = ({ go }) => {

  // ── Tab state ──────────────────────────────────────────────────────────────
  const [tab, setTab] = React.useState(() => {
    const t = window.__reliq_pending_focus;
    if (t && t.type === "api-tab" && t.tab) {
      window.__reliq_pending_focus = null;
      return t.tab;
    }
    return "api";
  });

  // ── Access levels ──────────────────────────────────────────────────────────
  const productState        = window.reliqSubscription?.getProductState?.() || "";
  const isPastDueOrCanceled = productState === "authenticated_past_due" || productState === "authenticated_canceled";
  const canApiKeys          = window.reliqGates?.canUseApiKeys?.()      ?? false;
  const canWebhooks         = window.reliqGates?.canUseWebhooks?.()     ?? false;
  const canGithubAction     = window.reliqGates?.canUseGitHubAction?.() ?? false;

  // three access tiers: "full" | "readonly" | "blocked"
  const apiAccess     = canApiKeys      ? "full" : isPastDueOrCanceled ? "readonly" : "blocked";
  const webhookAccess = canWebhooks     ? "full" : isPastDueOrCanceled ? "readonly" : "blocked";
  const githubAccess  = canGithubAction ? "full" : isPastDueOrCanceled ? "readonly" : "blocked";

  // ── User identity ──────────────────────────────────────────────────────────
  const userEmail = React.useMemo(() => {
    try {
      const u = JSON.parse(localStorage.getItem("reliq_auth_user") || "{}");
      return u.email || "you";
    } catch (_) { return "you"; }
  }, []);

  // ── API keys state ─────────────────────────────────────────────────────────
  const [apiKeys,        setApiKeys]        = React.useState(() => loadStore(API_KEYS_STORE,   INITIAL_API_KEYS));
  const [showCreateForm, setShowCreateForm] = React.useState(false);
  const [newKeyName,     setNewKeyName]     = React.useState("");
  const [newKeyEnv,      setNewKeyEnv]      = React.useState("live");
  const [newKeyNameErr,  setNewKeyNameErr]  = React.useState(null);
  const [revealedKey,    setRevealedKey]    = React.useState(null); // { id, name, fullValue }

  // ── Webhook state ──────────────────────────────────────────────────────────
  const [endpoints,          setEndpoints]          = React.useState(() => loadStore(WEBHOOKS_STORE,   INITIAL_ENDPOINTS));
  const [deliveries,         setDeliveries]         = React.useState(() => loadStore(DELIVERIES_STORE, INITIAL_DELIVERIES));
  const [showAddEndpointForm,setShowAddEndpointForm] = React.useState(false);
  const [newEndpointUrl,     setNewEndpointUrl]     = React.useState("");
  const [newEndpointUrlErr,  setNewEndpointUrlErr]  = React.useState(null);
  const [newEndpointEvents,  setNewEndpointEvents]  = React.useState(new Set(["scan.completed"]));
  const [revealedSecret,     setRevealedSecret]     = React.useState(null); // { id, url, secret }

  // ── Persistence helpers ────────────────────────────────────────────────────
  const persistApiKeys    = (keys) => { setApiKeys(keys);    saveStore(API_KEYS_STORE,   keys); };
  const persistEndpoints  = (eps)  => { setEndpoints(eps);   saveStore(WEBHOOKS_STORE,   eps); };
  const persistDeliveries = (dels) => { setDeliveries(dels); saveStore(DELIVERIES_STORE, dels); };

  // ── URL validation ─────────────────────────────────────────────────────────
  const validateEndpointUrl = (val) => {
    if (!val || !val.trim()) return "Endpoint URL is required.";
    try {
      const u = new URL(val.trim());
      if (u.protocol !== "https:") return "Endpoint URL must use HTTPS.";
      if (!u.hostname || u.hostname === "localhost" || u.hostname === "127.0.0.1")
        return "Endpoint URL must be a public HTTPS endpoint, not localhost.";
      return null;
    } catch (_) { return "Enter a valid URL (e.g. https://example.com/webhook)."; }
  };

  // ── API key handlers ───────────────────────────────────────────────────────
  const handleCreateKey = () => {
    const nameErr = !newKeyName.trim() ? "Key name is required." : null;
    setNewKeyNameErr(nameErr);
    if (nameErr) return;
    const fullValue = generateKeyValue(newKeyEnv);
    const newKey = {
      id: `key_${apiRandHex(6)}`,
      name: newKeyName.trim(),
      prefix: `rq_${newKeyEnv}`,
      maskedValue: maskKey(fullValue),
      fullValue,
      environment: newKeyEnv,
      createdAt: new Date().toLocaleDateString("en-US", { year: "numeric", month: "2-digit", day: "2-digit" }),
      lastUsedAt: "Never",
      status: "active",
      scopes: ["scan:write", "report:read"],
      createdBy: userEmail,
      isMock: true,
    };
    const updated = [newKey, ...apiKeys];
    persistApiKeys(updated);
    setRevealedKey({ id: newKey.id, name: newKey.name, fullValue: newKey.fullValue });
    setShowCreateForm(false);
    setNewKeyName("");
    setNewKeyEnv("live");
    setNewKeyNameErr(null);
  };

  const handleDismissRevealedKey = () => {
    // Mask the fullValue in storage — it's been seen and copied
    persistApiKeys(apiKeys.map(k => k.id === revealedKey.id ? { ...k, fullValue: null } : k));
    setRevealedKey(null);
  };

  const handleCopyKey = (value, label) => {
    navigator.clipboard?.writeText(value).then(() => {
      window.reliqToast?.success(`${label} copied`);
    }).catch(() => window.reliqToast?.error("Could not copy to clipboard"));
  };

  const handleRevokeKey = (key) => {
    window.reliqConfirm?.show({
      title: "Revoke this API key?",
      message: `"${key.name}" will be permanently revoked. Any CI/CD pipelines or integrations using it will fail immediately.`,
      danger: true,
      confirmLabel: "Revoke key",
      onConfirm: () => {
        persistApiKeys(apiKeys.filter(k => k.id !== key.id));
        if (revealedKey?.id === key.id) setRevealedKey(null);
        window.reliqToast?.success(`${key.name} revoked`);
      },
    });
  };

  // ── Webhook handlers ───────────────────────────────────────────────────────
  const handleAddEndpoint = () => {
    const urlErr = validateEndpointUrl(newEndpointUrl);
    setNewEndpointUrlErr(urlErr);
    if (urlErr) return;
    if (newEndpointEvents.size === 0) {
      window.reliqToast?.error("Select at least one event to subscribe to.");
      return;
    }
    const secret = generateSecret();
    const newEp = {
      id: `wh_${apiRandHex(6)}`,
      url: newEndpointUrl.trim(),
      events: [...newEndpointEvents],
      signingSecret: secret,
      status: "enabled",
      createdAt: new Date().toLocaleDateString("en-US", { year: "numeric", month: "2-digit", day: "2-digit" }),
      lastDeliveryAt: null,
      failureCount: 0,
      isMock: true,
    };
    persistEndpoints([newEp, ...endpoints]);
    setRevealedSecret({ id: newEp.id, url: newEp.url, secret });
    setShowAddEndpointForm(false);
    setNewEndpointUrl("");
    setNewEndpointEvents(new Set(["scan.completed"]));
    setNewEndpointUrlErr(null);
  };

  const handleDismissRevealedSecret = () => {
    setRevealedSecret(null);
  };

  const handleCopySecret = (secret) => {
    navigator.clipboard?.writeText(secret).then(() => {
      window.reliqToast?.success("Signing secret copied");
    }).catch(() => window.reliqToast?.error("Could not copy to clipboard"));
  };

  const handleToggleEndpoint = (ep) => {
    const newStatus = ep.status === "enabled" ? "disabled" : "enabled";
    persistEndpoints(endpoints.map(e => e.id === ep.id ? { ...e, status: newStatus } : e));
    window.reliqToast?.success(`Endpoint ${newStatus}`);
  };

  const handleDeleteEndpoint = (ep) => {
    window.reliqConfirm?.show({
      title: "Delete this endpoint?",
      message: `"${ep.url}" will be removed. No further events will be delivered to this URL.`,
      danger: true,
      confirmLabel: "Delete endpoint",
      onConfirm: () => {
        persistEndpoints(endpoints.filter(e => e.id !== ep.id));
        persistDeliveries(deliveries.filter(d => d.endpointId !== ep.id));
        if (revealedSecret?.id === ep.id) setRevealedSecret(null);
        window.reliqToast?.success("Endpoint deleted");
      },
    });
  };

  const handleTestDelivery = (ep) => {
    const durationMs = Math.floor(Math.random() * 200) + 50;
    const delivery = {
      id: `del_${apiRandHex(6)}`,
      endpointId: ep.id,
      endpointUrl: ep.url,
      event: "scan.completed",
      status: "succeeded",
      responseCode: 200,
      timestamp: "just now",
      attempt: 1,
      durationMs,
      payloadId: `pay_${apiRandHex(4)}`,
      isMock: true,
    };
    persistDeliveries([delivery, ...deliveries]);
    persistEndpoints(endpoints.map(e => e.id === ep.id ? { ...e, lastDeliveryAt: "just now" } : e));
    window.reliqToast?.success("Test event delivered — scan.completed");
  };

  // ── GitHub tab handlers ────────────────────────────────────────────────────
  const GITHUB_YAML = `name: Reliq
on:
  push:
    branches: [main]
  pull_request:
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Reliq scan
        uses: reliq/scan@v1
        with:
          api_key: \${{ secrets.RELIQ_KEY }}
          file: ./build/app-release.aab
          target_stores: play_store,app_store
          fail_on: critical
          pr_comment: true`;

  const handleCopySnippet = () => {
    navigator.clipboard?.writeText(GITHUB_YAML).then(() => {
      window.reliqToast?.success("Workflow snippet copied");
    }).catch(() => window.reliqToast?.error("Could not copy to clipboard"));
  };

  const handleOpenMarketplace = () => {
    const url = window.RELIQ_GITHUB_MARKETPLACE_URL || "https://github.com/marketplace/actions/reliq-scan";
    window.open(url, "_blank", "noopener,noreferrer");
  };

  const handleViewSource = () => {
    const url = window.RELIQ_GITHUB_REPO_URL || "https://github.com/reliq-dev/reliq";
    window.open(url, "_blank", "noopener,noreferrer");
  };

  const handleOpenApiDocs = () => {
    try { sessionStorage.setItem("reliq_scroll_to", "docs-api-keys"); } catch (_) {}
    go("docs");
  };

  // ── Derived values ─────────────────────────────────────────────────────────
  const activeKeys = apiKeys.filter(k => k.status === "active");

  // ── Render ─────────────────────────────────────────────────────────────────
  return (
    <AuthLayout
      route="api"
      go={go}
      crumbs={["Workspace", "Developer", "API & Webhooks"]}
      maxWidth={1080}
    >
      <div className="page-head">
        <div>
          <h1 className="page-title">API & Webhooks</h1>
          <p className="page-sub">Run scans from CI, listen for completion events, ship the Reliq badge.</p>
        </div>
        <div style={{display:"flex", gap:8}}>
          <button className="btn btn-sm btn-ghost" onClick={() => go("trust-api")}>
            <Icon name="globe" size={13} /> Trust API
          </button>
          <button className="btn btn-sm" onClick={handleOpenApiDocs}>
            <Icon name="book" size={13} /> API docs <Icon name="external-link" size={11} />
          </button>
        </div>
      </div>

      <div className="tabs">
        {[
          { id: "api",      label: "API keys",     ic: "key" },
          { id: "webhooks", label: "Webhooks",      ic: "webhook" },
          { id: "github",   label: "GitHub Action", ic: "github" },
          { id: "badge",    label: "Trust badge",   ic: "shield" },
        ].map(t => (
          <div key={t.id} className={`tab ${tab === t.id ? "active" : ""}`} onClick={() => setTab(t.id)}>
            <Icon name={t.ic} size={14} />{t.label}
          </div>
        ))}
      </div>

      {/* ══ API KEYS TAB ══════════════════════════════════════════════════════ */}
      {tab === "api" && apiAccess === "blocked" && (
        <LockedTabOverlay planRequired="pro" featureName="API Keys" go={go} />
      )}

      {tab === "api" && apiAccess !== "blocked" && (
        <>
          {apiAccess === "readonly" && (
            <RestrictedBanner message="Your subscription is inactive. API keys are read-only — reactivate your plan to create or manage keys." />
          )}

          {/* ── New key reveal banner (shown once after creation) ── */}
          {revealedKey && (
            <div style={{
              padding: "14px 18px", marginBottom: 16,
              background: "rgba(16,185,129,0.07)",
              border: "1px solid var(--teal, #10b981)",
              borderRadius: 8,
            }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }}>
                <Icon name="key" size={14} style={{ color: "var(--teal)" }} />
                <span style={{ fontSize: 13, fontWeight: 600, color: "var(--teal)" }}>
                  "{revealedKey.name}" created — copy your key now
                </span>
                <MockBadge />
              </div>
              <p style={{ fontSize: 12, color: "var(--fg-2)", margin: "0 0 10px" }}>
                This is the only time your full API key will be shown. Copy it and store it somewhere safe — once dismissed, it cannot be retrieved.
              </p>
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <code style={{
                  flex: 1, padding: "8px 12px", borderRadius: 6,
                  background: "var(--bg-2)", border: "1px solid var(--line-2)",
                  fontSize: 12.5, fontFamily: "var(--font-mono)", wordBreak: "break-all",
                  color: "var(--fg-0)",
                }}>
                  {revealedKey.fullValue}
                </code>
                <button className="btn btn-sm btn-primary" onClick={() => handleCopyKey(revealedKey.fullValue, "API key")}>
                  <Icon name="copy" size={12} /> Copy
                </button>
                <button className="btn btn-sm" onClick={handleDismissRevealedKey}>Done</button>
              </div>
            </div>
          )}

          {/* ── Create key inline form ── */}
          {showCreateForm && (
            <div className="card" style={{ marginBottom: 16 }}>
              <div className="card-head">
                <div className="card-title">New API key</div>
              </div>
              <div className="card-body">
                <div className="field">
                  <label htmlFor="new-key-name">Key name</label>
                  <input
                    id="new-key-name"
                    type="text"
                    value={newKeyName}
                    onChange={e => { setNewKeyName(e.target.value); if (newKeyNameErr) setNewKeyNameErr(null); }}
                    onBlur={() => { if (!newKeyName.trim()) setNewKeyNameErr("Key name is required."); }}
                    placeholder="e.g. Production CI, Local dev"
                    aria-invalid={!!newKeyNameErr}
                    style={newKeyNameErr ? { borderColor: "var(--red)" } : undefined}
                    autoFocus
                  />
                  {newKeyNameErr && (
                    <span role="alert" style={{ display: "block", marginTop: 5, fontSize: 12, color: "var(--red)" }}>
                      <Icon name="alert" size={11} /> {newKeyNameErr}
                    </span>
                  )}
                </div>
                <div className="field">
                  <label htmlFor="new-key-env">Environment</label>
                  <select
                    id="new-key-env"
                    value={newKeyEnv}
                    onChange={e => setNewKeyEnv(e.target.value)}
                  >
                    <option value="live">Live — real scans, counts against plan</option>
                    <option value="test">Test — sandbox, no plan usage</option>
                  </select>
                </div>
                <div style={{ display: "flex", gap: 8, justifyContent: "flex-end", paddingTop: 4 }}>
                  <button
                    className="btn btn-sm"
                    onClick={() => { setShowCreateForm(false); setNewKeyName(""); setNewKeyNameErr(null); }}
                  >
                    Cancel
                  </button>
                  <button className="btn btn-sm btn-primary" onClick={handleCreateKey}>
                    <Icon name="key" size={12} /> Create key
                  </button>
                </div>
              </div>
            </div>
          )}

          {/* ── API key list ── */}
          <div className="card" style={{ marginBottom: 16 }}>
            <div className="card-head">
              <div className="card-title">API keys</div>
              <span className="card-sub">{activeKeys.length} active</span>
              {apiAccess === "full" && !showCreateForm && (
                <button
                  className="btn btn-sm btn-primary"
                  style={{ marginLeft: "auto" }}
                  onClick={() => setShowCreateForm(true)}
                >
                  <Icon name="plus" size={12} /> Create key
                </button>
              )}
            </div>

            {apiKeys.length === 0 && (
              <div style={{ padding: "36px 18px", textAlign: "center", color: "var(--fg-2)", fontSize: 13 }}>
                <Icon name="key" size={22} style={{ opacity: 0.3, display: "block", margin: "0 auto 10px" }} />
                No API keys yet. Create one to start integrating.
              </div>
            )}

            {apiKeys.map((k, i) => (
              <div
                key={k.id}
                className="apikey-row"
                style={i === 0 ? { borderTop: "1px solid var(--line-1)" } : undefined}
              >
                <div className="lbl">
                  {k.name}
                  <MockBadge />
                  <div className="sub">
                    created {k.createdAt} by {k.createdBy}
                    {" · "}
                    <span style={{ textTransform: "capitalize", color: k.environment === "live" ? "var(--teal)" : "var(--fg-2)" }}>
                      {k.environment}
                    </span>
                  </div>
                </div>
                <div className="key">
                  <Icon name="key" size={11} /> {k.maskedValue}
                  <Icon
                    name="copy"
                    size={11}
                    style={{ color: "var(--fg-2)", cursor: "pointer" }}
                    onClick={() => window.reliqToast?.info("Full key not available — keys are shown once at creation.")}
                  />
                </div>
                <div className="meta">Last used {k.lastUsedAt}</div>
                {apiAccess === "full" && (
                  <div style={{ display: "flex", gap: 6, justifyContent: "flex-end" }}>
                    <button
                      className="btn btn-sm btn-ghost"
                      title="Revoke key"
                      style={{ color: "var(--red)" }}
                      onClick={() => handleRevokeKey(k)}
                    >
                      <Icon name="trash" size={12} />
                    </button>
                  </div>
                )}
              </div>
            ))}
          </div>

          {/* ── Quick start snippet ── */}
          <div className="card">
            <div className="card-head">
              <div className="card-title">Quick start</div>
              <span className="card-sub">curl · POST /api/v1/scans</span>
            </div>
            <div className="card-body">
              <div className="code-block" style={{ marginTop: 0 }}>
                <div className="filename">terminal</div>
                <div><span className="ln">1</span><span className="kw">curl</span> -X POST <span className="str">https://api.reliq.dev/v1/scans</span> \</div>
                <div><span className="ln">2</span>  -H <span className="str">"Authorization: Bearer $RELIQ_KEY"</span> \</div>
                <div><span className="ln">3</span>  -F <span className="str">"file=@./build/app-release.aab"</span> \</div>
                <div><span className="ln">4</span>  -F <span className="str">"target_stores=play_store,app_store"</span></div>
              </div>
              <div style={{ display: "flex", gap: 12, marginTop: 16, fontSize: 12.5, color: "var(--fg-2)" }}>
                <span><Icon name="check" size={12} /> Returns scan_id immediately, poll for status</span>
                <span><Icon name="check" size={12} /> Or subscribe via webhook</span>
                <span><Icon name="check" size={12} /> Average completion 2–3 min</span>
              </div>
            </div>
          </div>

          {/* ── MCP server (agent access) ── */}
          <div className="card" style={{ marginTop: 16 }}>
            <div className="card-head">
              <div className="card-title">MCP server <span style={{fontFamily:"var(--font-mono)", fontSize:10, color:"var(--violet)", background:"var(--violet-bg)", border:"1px solid rgba(167,139,250,0.25)", borderRadius:4, padding:"1px 6px", letterSpacing:"0.06em", textTransform:"uppercase", marginLeft:6}}>Team plan</span></div>
              <span className="card-sub">Agent access · JSON-RPC</span>
            </div>
            <div className="card-body">
              <p style={{ fontSize: 12.5, color: "var(--fg-2)", marginTop: 0, lineHeight: 1.6 }}>
                Let AI agents (Claude, Cursor, Codex) call Reliq as a tool to check release &amp; agent readiness and generate reports. Authenticated with your existing API key.
              </p>

              <div style={{ display: "flex", flexWrap: "wrap", gap: 24, margin: "14px 0 6px" }}>
                <div>
                  <div style={{ fontSize: 10.5, fontFamily: "var(--font-mono)", letterSpacing: "0.12em", textTransform: "uppercase", color: "var(--fg-3)", marginBottom: 5 }}>Endpoint</div>
                  <div className="mono" style={{ fontSize: 12.5, color: "var(--fg-1)" }}>https://api.reliq.dev/v1/mcp</div>
                </div>
                <div>
                  <div style={{ fontSize: 10.5, fontFamily: "var(--font-mono)", letterSpacing: "0.12em", textTransform: "uppercase", color: "var(--fg-3)", marginBottom: 5 }}>Required scopes</div>
                  <div style={{ display: "flex", gap: 6 }}>
                    {["scans:create", "reports:read"].map(s => (
                      <span key={s} className="mono" style={{ fontSize: 11, color: "var(--fg-1)", background: "var(--bg-3)", border: "1px solid var(--line-2)", borderRadius: 4, padding: "2px 7px" }}>{s}</span>
                    ))}
                  </div>
                </div>
                <div>
                  <div style={{ fontSize: 10.5, fontFamily: "var(--font-mono)", letterSpacing: "0.12em", textTransform: "uppercase", color: "var(--fg-3)", marginBottom: 5 }}>MCP calls (30d)</div>
                  <div className="mono" style={{ fontSize: 12.5, color: "var(--fg-1)" }}>128 <MockBadge /></div>
                </div>
              </div>

              <div style={{ fontSize: 12, color: "var(--fg-2)", marginTop: 8 }}>
                Tools: <span className="mono" style={{ fontSize: 11.5 }}>reliq_check_release_readiness · reliq_check_agent_readiness · reliq_generate_report</span>
              </div>

              <div className="code-block" style={{ marginTop: 14 }}>
                <div className="filename">mcp config — Claude / Cursor</div>
                <div><span className="ln">1</span><span className="punct">{"{"}</span> <span className="str">"mcpServers"</span>: <span className="punct">{"{"}</span></div>
                <div><span className="ln">2</span>  <span className="str">"reliq"</span>: <span className="punct">{"{"}</span></div>
                <div><span className="ln">3</span>    <span className="str">"url"</span>: <span className="str">"https://api.reliq.dev/v1/mcp"</span>,</div>
                <div><span className="ln">4</span>    <span className="str">"headers"</span>: <span className="punct">{"{"}</span> <span className="str">"Authorization"</span>: <span className="str">"Bearer rq_live_…"</span> <span className="punct">{"}"}</span></div>
                <div><span className="ln">5</span>  <span className="punct">{"}"}</span> <span className="punct">{"}"}</span> <span className="punct">{"}"}</span></div>
              </div>

              <div style={{ display: "flex", alignItems: "center", gap: 14, marginTop: 14 }}>
                <button className="btn btn-sm" onClick={() => go("/docs")}>
                  <Icon name="book" size={12} /> View MCP docs
                </button>
                <span style={{ fontSize: 12, color: "var(--fg-3)" }}>
                  TEST keys (<span className="mono">rq_test_</span>) bypass plan gating for development.
                </span>
              </div>
            </div>
          </div>

          {/* ── Security note ── */}
          <div style={{
            display: "flex", alignItems: "flex-start", gap: 10,
            padding: "12px 16px", marginTop: 16,
            background: "var(--bg-2)", border: "1px solid var(--line-2)",
            borderRadius: 8, fontSize: 12.5, color: "var(--fg-2)",
          }}>
            <Icon name="lock" size={13} style={{ marginTop: 1, flexShrink: 0 }} />
            <span>
              API keys are secrets — never commit them to source control.
              Store them in environment variables or a secrets manager.
              If a key is exposed, revoke it immediately and generate a new one.
              In CI/CD, use GitHub Secrets (<code>RELIQ_KEY</code>) or your provider's equivalent.
              The backend will replace these mock values with real keys.
            </span>
          </div>
        </>
      )}

      {/* ══ WEBHOOKS TAB ══════════════════════════════════════════════════════ */}
      {tab === "webhooks" && webhookAccess === "blocked" && (
        <LockedTabOverlay planRequired="pro" featureName="Webhooks" go={go} />
      )}

      {tab === "webhooks" && webhookAccess !== "blocked" && (
        <>
          {webhookAccess === "readonly" && (
            <RestrictedBanner message="Your subscription is inactive. Webhook endpoints are read-only — reactivate your plan to manage them." />
          )}

          {/* ── Signing secret reveal banner (shown once after endpoint creation) ── */}
          {revealedSecret && (
            <div style={{
              padding: "14px 18px", marginBottom: 16,
              background: "rgba(16,185,129,0.07)",
              border: "1px solid var(--teal, #10b981)",
              borderRadius: 8,
            }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }}>
                <Icon name="lock" size={14} style={{ color: "var(--teal)" }} />
                <span style={{ fontSize: 13, fontWeight: 600, color: "var(--teal)" }}>
                  Endpoint created — save your signing secret now
                </span>
                <MockBadge />
              </div>
              <p style={{ fontSize: 12, color: "var(--fg-2)", margin: "0 0 10px" }}>
                This signing secret is shown only once. Use it to verify the <code>X-Reliq-Signature</code> header on incoming webhook payloads. If you lose it, delete the endpoint and create a new one.
              </p>
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <code style={{
                  flex: 1, padding: "8px 12px", borderRadius: 6,
                  background: "var(--bg-2)", border: "1px solid var(--line-2)",
                  fontSize: 12.5, fontFamily: "var(--font-mono)", wordBreak: "break-all",
                  color: "var(--fg-0)",
                }}>
                  {revealedSecret.secret}
                </code>
                <button className="btn btn-sm btn-primary" onClick={() => handleCopySecret(revealedSecret.secret)}>
                  <Icon name="copy" size={12} /> Copy
                </button>
                <button className="btn btn-sm" onClick={handleDismissRevealedSecret}>Done</button>
              </div>
            </div>
          )}

          {/* ── Add endpoint inline form ── */}
          {showAddEndpointForm && (
            <div className="card" style={{ marginBottom: 16 }}>
              <div className="card-head">
                <div className="card-title">New webhook endpoint</div>
              </div>
              <div className="card-body">
                <div className="field">
                  <label htmlFor="new-ep-url">Endpoint URL</label>
                  <input
                    id="new-ep-url"
                    type="url"
                    value={newEndpointUrl}
                    onChange={e => { setNewEndpointUrl(e.target.value); if (newEndpointUrlErr) setNewEndpointUrlErr(null); }}
                    onBlur={() => setNewEndpointUrlErr(validateEndpointUrl(newEndpointUrl))}
                    placeholder="https://your-server.com/webhook"
                    aria-invalid={!!newEndpointUrlErr}
                    style={newEndpointUrlErr ? { borderColor: "var(--red)" } : undefined}
                    autoFocus
                  />
                  {newEndpointUrlErr && (
                    <span role="alert" style={{ display: "block", marginTop: 5, fontSize: 12, color: "var(--red)" }}>
                      <Icon name="alert" size={11} /> {newEndpointUrlErr}
                    </span>
                  )}
                  <div className="hint">Must be a public HTTPS endpoint. A signing secret will be generated automatically.</div>
                </div>
                <div className="field">
                  <label>Events to subscribe</label>
                  <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "6px 24px", marginTop: 8 }}>
                    {WEBHOOK_EVENTS.map(ev => {
                      const checked = newEndpointEvents.has(ev.id);
                      return (
                        <label key={ev.id} style={{ display: "flex", alignItems: "center", gap: 8, cursor: "pointer", fontSize: 13 }}>
                          <input
                            type="checkbox"
                            checked={checked}
                            onChange={() => {
                              const next = new Set(newEndpointEvents);
                              if (checked) next.delete(ev.id); else next.add(ev.id);
                              setNewEndpointEvents(next);
                            }}
                            style={{ accentColor: "var(--teal)", flexShrink: 0 }}
                          />
                          <code style={{ fontSize: 11.5, color: "var(--fg-2)", flexShrink: 0 }}>{ev.id}</code>
                        </label>
                      );
                    })}
                  </div>
                </div>
                <div style={{ display: "flex", gap: 8, justifyContent: "flex-end", paddingTop: 4 }}>
                  <button
                    className="btn btn-sm"
                    onClick={() => {
                      setShowAddEndpointForm(false);
                      setNewEndpointUrl("");
                      setNewEndpointUrlErr(null);
                      setNewEndpointEvents(new Set(["scan.completed"]));
                    }}
                  >
                    Cancel
                  </button>
                  <button className="btn btn-sm btn-primary" onClick={handleAddEndpoint}>
                    <Icon name="webhook" size={12} /> Add endpoint
                  </button>
                </div>
              </div>
            </div>
          )}

          {/* ── Endpoint list ── */}
          <div className="card" style={{ marginBottom: 16 }}>
            <div className="card-head">
              <div className="card-title">Endpoints</div>
              <span className="card-sub">{endpoints.length} configured</span>
              {webhookAccess === "full" && !showAddEndpointForm && (
                <button
                  className="btn btn-sm btn-primary"
                  style={{ marginLeft: "auto" }}
                  onClick={() => setShowAddEndpointForm(true)}
                >
                  <Icon name="plus" size={12} /> Add endpoint
                </button>
              )}
            </div>

            {endpoints.length === 0 && (
              <div style={{ padding: "36px 18px", textAlign: "center", color: "var(--fg-2)", fontSize: 13 }}>
                <Icon name="webhook" size={22} style={{ opacity: 0.3, display: "block", margin: "0 auto 10px" }} />
                No endpoints yet. Add one to start receiving events.
              </div>
            )}

            {endpoints.map((ep) => (
              <div key={ep.id} style={{ borderTop: "1px solid var(--line-1)", padding: "14px 18px" }}>
                <div style={{ display: "flex", alignItems: "flex-start", gap: 12 }}>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 6, flexWrap: "wrap" }}>
                      <span style={{ fontSize: 13, fontFamily: "var(--font-mono)", fontWeight: 500, wordBreak: "break-all" }}>
                        {ep.url}
                      </span>
                      <MockBadge />
                      <span style={{
                        display: "inline-flex", padding: "2px 7px", borderRadius: 4,
                        fontSize: 10.5, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.04em",
                        background: ep.status === "enabled" ? "rgba(16,185,129,0.1)" : "var(--bg-2)",
                        color: ep.status === "enabled" ? "var(--teal)" : "var(--fg-2)",
                        border: `1px solid ${ep.status === "enabled" ? "var(--teal)" : "var(--line-2)"}`,
                      }}>
                        {ep.status}
                      </span>
                      {ep.failureCount > 0 && (
                        <span style={{
                          display: "inline-flex", padding: "2px 7px", borderRadius: 4,
                          fontSize: 10.5, fontWeight: 600,
                          background: "rgba(239,68,68,0.1)", color: "var(--red)",
                          border: "1px solid var(--red)",
                        }}>
                          {ep.failureCount} failure{ep.failureCount !== 1 ? "s" : ""}
                        </span>
                      )}
                    </div>
                    <div style={{ fontSize: 12, color: "var(--fg-2)", display: "flex", gap: 16, flexWrap: "wrap" }}>
                      <span>Events: <code style={{ fontSize: 11.5 }}>{ep.events.join(", ")}</code></span>
                      <span>Last delivery: {ep.lastDeliveryAt || "Never"}</span>
                      <span>Secret: <code style={{ fontSize: 11.5 }}>{maskSecret(ep.signingSecret)}</code></span>
                    </div>
                  </div>
                  {webhookAccess === "full" && (
                    <div style={{ display: "flex", gap: 6, flexShrink: 0, alignItems: "center" }}>
                      <button
                        className="btn btn-sm btn-ghost"
                        title="Send test event"
                        onClick={() => handleTestDelivery(ep)}
                      >
                        <Icon name="bolt" size={12} /> Test
                      </button>
                      <div
                        className={`toggle ${ep.status === "enabled" ? "on" : ""}`}
                        title={ep.status === "enabled" ? "Disable endpoint" : "Enable endpoint"}
                        onClick={() => handleToggleEndpoint(ep)}
                        style={{ cursor: "pointer" }}
                      />
                      <button
                        className="btn btn-sm btn-ghost"
                        title="Delete endpoint"
                        style={{ color: "var(--red)" }}
                        onClick={() => handleDeleteEndpoint(ep)}
                      >
                        <Icon name="trash" size={12} />
                      </button>
                    </div>
                  )}
                </div>
              </div>
            ))}
          </div>

          {/* ── Delivery history ── */}
          <div className="card">
            <div className="card-head">
              <div className="card-title">Delivery history</div>
              <span className="card-sub">{deliveries.length} total</span>
            </div>
            {deliveries.length === 0 && (
              <div style={{ padding: "36px 18px", textAlign: "center", color: "var(--fg-2)", fontSize: 13 }}>
                <Icon name="clock" size={22} style={{ opacity: 0.3, display: "block", margin: "0 auto 10px" }} />
                No deliveries yet. Deliveries appear here when events are sent.
              </div>
            )}
            {deliveries.length > 0 && (
              <div style={{ overflowX: "auto" }}>
                <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 12.5 }}>
                  <thead>
                    <tr style={{ borderBottom: "1px solid var(--line-1)" }}>
                      {["Event", "Endpoint", "Status", "Code", "Time", "Attempt", "Duration", "Payload"].map(h => (
                        <th key={h} style={{
                          padding: "8px 12px", textAlign: "left",
                          color: "var(--fg-2)", fontWeight: 500, whiteSpace: "nowrap",
                        }}>
                          {h}
                        </th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {deliveries.map(d => (
                      <tr key={d.id} style={{ borderBottom: "1px solid var(--line-1)" }}>
                        <td style={{ padding: "9px 12px" }}>
                          <code style={{ fontSize: 11.5 }}>{d.event}</code>
                        </td>
                        <td style={{
                          padding: "9px 12px", color: "var(--fg-2)",
                          maxWidth: 180, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap",
                        }}>
                          {d.endpointUrl}
                        </td>
                        <td style={{ padding: "9px 12px" }}>
                          <span style={{
                            display: "inline-flex", padding: "2px 7px", borderRadius: 4,
                            fontSize: 11, fontWeight: 600, textTransform: "uppercase",
                            background: d.status === "succeeded" ? "rgba(16,185,129,0.1)" : "rgba(239,68,68,0.1)",
                            color: d.status === "succeeded" ? "var(--teal)" : "var(--red)",
                            border: `1px solid ${d.status === "succeeded" ? "var(--teal)" : "var(--red)"}`,
                          }}>
                            {d.status}
                          </span>
                        </td>
                        <td style={{ padding: "9px 12px", color: d.responseCode >= 400 ? "var(--red)" : "var(--fg-1)" }}>
                          {d.responseCode}
                        </td>
                        <td style={{ padding: "9px 12px", color: "var(--fg-2)", whiteSpace: "nowrap" }}>
                          {d.timestamp}
                        </td>
                        <td style={{ padding: "9px 12px", color: "var(--fg-2)", textAlign: "center" }}>
                          {d.attempt}
                        </td>
                        <td style={{ padding: "9px 12px", color: "var(--fg-2)", whiteSpace: "nowrap" }}>
                          {d.durationMs}ms
                        </td>
                        <td style={{ padding: "9px 12px" }}>
                          <code style={{ fontSize: 11, color: "var(--fg-2)" }}>{d.payloadId}</code>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )}
          </div>

          {/* ── Security note ── */}
          <div style={{
            display: "flex", alignItems: "flex-start", gap: 10,
            padding: "12px 16px", marginTop: 16,
            background: "var(--bg-2)", border: "1px solid var(--line-2)",
            borderRadius: 8, fontSize: 12.5, color: "var(--fg-2)",
          }}>
            <Icon name="lock" size={13} style={{ marginTop: 1, flexShrink: 0 }} />
            <span>
              Always verify the <code>X-Reliq-Signature</code> header using your signing secret before trusting incoming payloads.
              Rotate your signing secret if it is ever exposed — delete the endpoint and create a new one.
              The backend will replace these mock values with real HMAC-signed delivery.
            </span>
          </div>
        </>
      )}

      {/* ══ GITHUB ACTION TAB ════════════════════════════════════════════════ */}
      {tab === "github" && githubAccess === "blocked" && (
        <LockedTabOverlay planRequired="pro" featureName="GitHub Action" go={go} />
      )}

      {tab === "github" && githubAccess !== "blocked" && (
        <>
          {githubAccess === "readonly" && (
            <RestrictedBanner message="Your subscription is inactive. GitHub Action setup is read-only — reactivate your plan to access CI/CD integrations." />
          )}
          <div className="card">
            <div className="card-head">
              <div className="card-title">Reliq GitHub Action</div>
              <span className="card-sub">v1 · MIT license</span>
              <button className="btn btn-sm" style={{ marginLeft: "auto" }} onClick={handleOpenMarketplace}>
                <Icon name="external-link" size={12} /> Marketplace
              </button>
            </div>
            <div className="card-body">
              <p style={{ color: "var(--fg-1)", fontSize: 13.5, margin: "0 0 18px", maxWidth: 640 }}>
                Drop Reliq into your release pipeline. Fail CI when critical issues appear. Comment scan summaries on PRs.
              </p>
              <div className="code-block" style={{ marginTop: 0 }}>
                <div className="filename">.github/workflows/reliq.yml</div>
                <div><span className="ln">1</span><span className="kw">name:</span> <span className="str">Reliq</span></div>
                <div><span className="ln">2</span><span className="kw">on:</span></div>
                <div><span className="ln">3</span>  <span className="kw">push:</span></div>
                <div><span className="ln">4</span>    <span className="at">branches:</span> <span className="str">[main]</span></div>
                <div><span className="ln">5</span>  <span className="kw">pull_request:</span></div>
                <div><span className="ln">6</span><span className="kw">jobs:</span></div>
                <div><span className="ln">7</span>  scan:</div>
                <div><span className="ln">8</span>    runs-on: ubuntu-latest</div>
                <div><span className="ln">9</span>    steps:</div>
                <div><span className="ln">10</span>      - <span className="tag">uses:</span> <span className="str">actions/checkout@v4</span></div>
                <div><span className="ln">11</span>      - <span className="tag">name:</span> Run Reliq scan</div>
                <div><span className="ln">12</span>        <span className="tag">uses:</span> <span className="str">reliq/scan@v1</span></div>
                <div><span className="ln">13</span>        <span className="tag">with:</span></div>
                <div><span className="ln">14</span>          <span className="at">api_key:</span> <span className="str">$&#123;&#123; secrets.RELIQ_KEY &#125;&#125;</span></div>
                <div><span className="ln">15</span>          <span className="at">file:</span> <span className="str">./build/app-release.aab</span></div>
                <div><span className="ln">16</span>          <span className="at">target_stores:</span> <span className="str">play_store,app_store</span></div>
                <div><span className="ln">17</span>          <span className="at">fail_on:</span> <span className="str">critical</span></div>
                <div><span className="ln">18</span>          <span className="at">pr_comment:</span> <span className="str">true</span></div>
              </div>
              <div style={{ display: "flex", gap: 8, marginTop: 16 }}>
                <button className="btn btn-primary btn-sm" onClick={handleCopySnippet}>
                  <Icon name="copy" size={12} /> Copy snippet
                </button>
                <button className="btn btn-sm" onClick={handleViewSource}>
                  <Icon name="github" size={12} /> View source
                </button>
              </div>
              {/* ── Security note ── */}
              <div style={{
                display: "flex", alignItems: "flex-start", gap: 10,
                padding: "12px 16px", marginTop: 18,
                background: "var(--bg-2)", border: "1px solid var(--line-2)",
                borderRadius: 8, fontSize: 12.5, color: "var(--fg-2)",
              }}>
                <Icon name="lock" size={13} style={{ marginTop: 1, flexShrink: 0 }} />
                <span>
                  Store your API key as a GitHub Secret named <code>RELIQ_KEY</code> — never commit it directly to your repository.
                  Go to your repo's <strong>Settings → Secrets → Actions</strong> and add <code>RELIQ_KEY</code> with your key value.
                  If you expose your key, revoke it immediately from the API Keys tab and generate a new one.
                </span>
              </div>
            </div>
          </div>
        </>
      )}

      {/* ══ BADGE TAB ════════════════════════════════════════════════════════ */}
      {tab === "badge" && (
        <div className="card">
          <div className="card-head">
            <div className="card-title">Embeddable trust badge</div>
            <span className="card-sub">$9/mo add-on · live score</span>
          </div>
          <div className="card-body">
            <p style={{ color: "var(--fg-1)", margin: "0 0 18px" }}>Show your latest Reliq score on your repo, marketing site, or app listing. Updates live.</p>
            <div style={{ display: "flex", gap: 24, alignItems: "center", padding: "24px 0" }}>
              <div style={{ display: "inline-flex", alignItems: "stretch", borderRadius: 6, overflow: "hidden", fontFamily: "var(--font-mono)", fontSize: 13 }}>
                <span style={{ background: "#1a1d23", color: "#f5f6f7", padding: "7px 12px" }}>Reliq</span>
                <span style={{ background: "var(--teal)", color: "#001a14", padding: "7px 12px", fontWeight: 700 }}>92 / 100</span>
              </div>
              <div style={{ display: "inline-flex", alignItems: "stretch", borderRadius: 6, overflow: "hidden", fontFamily: "var(--font-mono)", fontSize: 13 }}>
                <span style={{ background: "#1a1d23", color: "#f5f6f7", padding: "7px 12px" }}>Reliq</span>
                <span style={{ background: "var(--amber)", color: "#1a1206", padding: "7px 12px", fontWeight: 700 }}>78 / 100</span>
              </div>
              <div style={{ display: "inline-flex", alignItems: "stretch", borderRadius: 6, overflow: "hidden", fontFamily: "var(--font-mono)", fontSize: 13 }}>
                <span style={{ background: "#1a1d23", color: "#f5f6f7", padding: "7px 12px" }}>Reliq</span>
                <span style={{ background: "var(--red)", color: "#2a0707", padding: "7px 12px", fontWeight: 700 }}>41 / 100</span>
              </div>
            </div>
            <div className="code-block" style={{ marginTop: 8 }}>
              <div className="filename">README.md</div>
              <div><span className="ln">1</span>[![Reliq Scan](https://api.reliq.app/v1/public/reports/rep_2k8x/badge.svg)](https://reliq.dev/r/rep_2k8x)</div>
            </div>
          </div>
        </div>
      )}
    </AuthLayout>
  );
};

Object.assign(window, { Settings });
