/* Keys: Pre-auth keys + API keys (tabbed) */
function Keys() {
  const [tab, setTab] = useState("preauth");
  return (
    <div className="page fade-up">
      <div className="section-head">
        <div>
          <h2 style={{ fontSize: 19 }}>Keys</h2>
          <div className="sub">Pre-auth keys register devices · API keys authenticate the control API</div>
        </div>
        <div className="spacer" />
        <RefreshBtn />
        <div className="seg">
          <button className={tab === "preauth" ? "on" : ""} onClick={() => setTab("preauth")}>Pre-auth</button>
          <button className={tab === "api" ? "on" : ""} onClick={() => setTab("api")}>API keys</button>
        </div>
      </div>
      {tab === "preauth" ? <PreauthKeys /> : <ApiKeys />}
    </div>
  );
}

function keyStatus(k) {
  if (k.expiration < Date.now()) return { label: "Expired", cls: "danger" };
  if (!k.reusable && k.used) return { label: "Used", cls: "" };
  const exp = expiryInfo(k.expiration);
  return { label: exp.soon ? exp.label : "Active", cls: exp.soon ? exp.cls : "online" };
}

function PreauthKeys() {
  const s = useStore();
  const toast = useToast();
  const [modal, setModal] = useState(null);
  const [created, setCreated] = useState(null);
  const [confirmDel, setConfirmDel] = useState(null);
  // create form state — real defaults: single-use, short-lived
  const [user, setUser] = useState(s.users[0] && s.users[0].id);
  const [reusable, setReusable] = useState(false);
  const [ephemeral, setEphemeral] = useState(false);
  const [ttl, setTtl] = useState(1);
  const [tags, setTags] = useState([]);

  const submit = () => {
    const expiration = Date.now() + ttl * 86400000;
    const key = HS.act.createPreauth({ user, reusable, ephemeral, aclTags: tags, expiration });
    setCreated(key);
    toast.push({ kind: "success", title: "Pre-auth key created", msg: reusable ? "Reusable key" : "Single-use key" });
  };

  return (
    <>
      <div style={{ display: "flex", justifyContent: "flex-end", marginBottom: 14 }}>
        <button className="btn primary" onClick={() => { setCreated(null); setTags([]); setReusable(false); setEphemeral(false); setTtl(1); setModal("create"); }}><Ic name="plus" size={15} />Generate key</button>
      </div>
      <div className="tbl-wrap">
        <div className="tbl-scroll">
          <table className="tbl">
            <thead>
              <tr><th>Key</th><th>User</th><th>Properties</th><th>Used</th><th>Status</th><th></th></tr>
            </thead>
            <tbody>
              {s.preauthKeys.map((k) => {
                const u = s.userById(k.user);
                const st = keyStatus(k);
                const expired = k.expiration < Date.now();
                return (
                  <tr key={k.id} style={{ cursor: "default", opacity: expired ? 0.55 : 1 }}>
                    <td>
                      <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                        <Ic name="key" size={15} style={{ color: "var(--text-dim)" }} />
                        <span className="mono" style={{ fontSize: 12.5 }}>{k.key.slice(0, 8)}<span style={{ color: "var(--text-faint)" }}>…{k.key.slice(-4)}</span></span>
                        <CopyBtn text={k.key} label="Key copied" />
                      </div>
                    </td>
                    <td>{u && <span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}><Avatar user={u} size={20} />{u.name}</span>}</td>
                    <td>
                      <div style={{ display: "flex", gap: 5, flexWrap: "wrap" }}>
                        <span className={"badge " + (k.reusable ? "accent" : "")}>{k.reusable ? "reusable" : "single-use"}</span>
                        {k.ephemeral && <span className="badge info">ephemeral</span>}
                        {k.aclTags?.map((t) => <span key={t} className="tag">{t}</span>)}
                      </div>
                    </td>
                    <td>{k.used ? <span className="badge"><span className="dot" style={{ background: "var(--text-faint)" }} />used</span> : <span className="badge" style={{ color: "var(--text-faint)" }}>unused</span>}</td>
                    <td><span className={"badge " + st.cls}>{st.label}</span></td>
                    <td>
                      <div className="row-actions">
                        {!expired && <button className="btn sm" onClick={() => { HS.act.expirePreauth(k.id); toast.push({ kind: "success", title: "Key expired" }); }} title="POST /preauthkey/expire">Expire</button>}
                        <button className="btn icon sm ghost" onClick={() => setConfirmDel(k)} title="DELETE /preauthkey"><Ic name="trash" size={15} /></button>
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>

      <div style={{ marginTop: 12, fontSize: 12, color: "var(--text-faint)", display: "flex", gap: 7, alignItems: "center" }}>
        <Ic name="info" size={14} /> <span><b>Expire</b> invalidates the key but keeps the record; <b>Delete</b> removes it entirely. Headscale exposes a <span className="code-inline">used</span> boolean, not a usage count.</span>
      </div>

      {confirmDel && (
        <ConfirmModal danger title="Delete pre-auth key?" subtitle="DELETE /api/v1/preauthkey" confirmLabel="Delete key"
          body={<div style={{ fontSize: 13.5, color: "var(--text-dim)" }}>Permanently removes key <span className="code-inline">{confirmDel.key.slice(0, 8)}…</span>. Devices already registered with it stay connected.</div>}
          onConfirm={() => { HS.act.deletePreauth(confirmDel.id); toast.push({ kind: "success", title: "Key deleted" }); }}
          onClose={() => setConfirmDel(null)} />
      )}

      {modal === "create" && (
        <Modal title="Generate pre-auth key" subtitle="Register devices without interactive login" icon="key" size="lg" onClose={() => setModal(null)}
          footer={created ? <><div className="spacer" /><button className="btn primary" onClick={() => setModal(null)}>Done</button></>
            : <><div className="spacer" /><button className="btn" onClick={() => setModal(null)}>Cancel</button><button className="btn primary" onClick={submit}>Generate key</button></>}>
          {created ? (
            <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
              <div className="badge online" style={{ alignSelf: "flex-start" }}><span className="dot" />Key generated — copy it now</div>
              <CmdBlock text={created} />
              <span className="hint">This is the only time the full key is shown. Use it with <span className="code-inline">tailscale up --authkey {created.slice(0,8)}…</span></span>
            </div>
          ) : (
            <>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
                <div className="field">
                  <label>User <span style={{ color: "var(--text-faint)", fontWeight: 400 }}>(by id)</span></label>
                  <Menu align="left" trigger={<button className="btn" style={{ justifyContent: "flex-start", width: "100%" }}>{s.userById(user) ? <><Avatar user={s.userById(user)} size={20} />{s.userById(user).name}</> : <span style={{ color: "var(--text-faint)" }}>no users</span>}<div style={{ flex: 1 }} /><Ic name="chevDown" size={14} /></button>}>
                    {s.users.map((u) => <MenuItem key={u.id} onClick={() => setUser(u.id)}>{u.name}</MenuItem>)}
                  </Menu>
                </div>
                <div className="field">
                  <label>Expiration</label>
                  <Menu align="left" trigger={<button className="btn" style={{ justifyContent: "flex-start", width: "100%" }}>{ttl === 1 ? "1 day" : ttl + " days"}<div style={{ flex: 1 }} /><Ic name="chevDown" size={14} /></button>}>
                    {[1, 7, 30, 90, 180].map((d) => <MenuItem key={d} onClick={() => setTtl(d)}>{d === 1 ? "1 day" : d + " days"}</MenuItem>)}
                  </Menu>
                </div>
              </div>
              <ToggleRow label="Reusable" desc="Allow the key to register multiple devices (default: single-use)" on={reusable} set={setReusable} />
              <ToggleRow label="Ephemeral" desc="Devices auto-remove when they go offline (CI, containers)" on={ephemeral} set={setEphemeral} />
              <div className="field">
                <label>Auto-apply ACL tags</label>
                <div style={{ display: "flex", gap: 5, flexWrap: "wrap" }}>
                  {s.tagOwners.map((t) => (
                    <span key={t} className={"tag" + (tags.includes(t) ? "" : " muted")} style={{ cursor: "pointer" }}
                      onClick={() => setTags(tags.includes(t) ? tags.filter((x) => x !== t) : [...tags, t])}>{tags.includes(t) ? "✓ " : ""}{t}</span>
                  ))}
                </div>
                <span className="hint">Nodes registered with this key get these tags (and become tag-owned).</span>
              </div>
            </>
          )}
        </Modal>
      )}
    </>
  );
}

function ApiKeys() {
  const s = useStore();
  const toast = useToast();
  const [modal, setModal] = useState(null);
  const [created, setCreated] = useState(null);
  const [confirmDel, setConfirmDel] = useState(null);
  const [ttl, setTtl] = useState(90);

  return (
    <>
      <div style={{ display: "flex", justifyContent: "flex-end", marginBottom: 14 }}>
        <button className="btn primary" onClick={() => { setTtl(90); setCreated(null); setModal("create"); }}><Ic name="plus" size={15} />Create API key</button>
      </div>
      <div className="tbl-wrap">
        <div className="tbl-scroll">
          <table className="tbl">
            <thead><tr><th>Prefix</th><th>Access</th><th>Last seen</th><th>Created</th><th>Status</th><th></th></tr></thead>
            <tbody>
              {s.apiKeys.map((k) => {
                const st = keyStatus({ ...k, reusable: true });
                const expired = k.expiration < Date.now();
                return (
                  <tr key={k.id} style={{ cursor: "default", opacity: expired ? 0.55 : 1 }}>
                    <td><div style={{ display: "flex", alignItems: "center", gap: 8 }}><Ic name="apikey" size={15} style={{ color: "var(--text-dim)" }} /><span className="mono" style={{ fontSize: 12.5 }}>{k.prefix}</span></div></td>
                    <td><span className="badge warn" title="Headscale API keys are all-or-nothing">full admin</span></td>
                    <td style={{ color: "var(--text-dim)", fontSize: 12.5 }}>{k.lastSeen ? relTime(k.lastSeen) : "never"}</td>
                    <td style={{ color: "var(--text-faint)", fontSize: 12.5 }}>{absDate(k.createdAt)}</td>
                    <td><span className={"badge " + st.cls}>{st.label}</span></td>
                    <td><div className="row-actions">
                      {!expired && <button className="btn sm" onClick={() => { HS.act.expireApiKey(k.id); toast.push({ kind: "success", title: "API key expired" }); }} title="POST /apikey/expire">Expire</button>}
                      <button className="btn icon sm ghost" onClick={() => setConfirmDel(k)} title="DELETE /apikey/{prefix}"><Ic name="trash" size={15} /></button>
                    </div></td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>

      <div style={{ marginTop: 12, fontSize: 12, color: "var(--text-faint)", display: "flex", gap: 7, alignItems: "center" }}>
        <Ic name="info" size={14} /> <span>Keys are identified by prefix only — Headscale stores no name/note. Every key grants <b>full</b> API access (no scopes).</span>
      </div>

      {confirmDel && (
        <ConfirmModal danger title="Delete API key?" subtitle={"DELETE /api/v1/apikey/" + confirmDel.prefix} confirmLabel="Delete key"
          body={<div style={{ fontSize: 13.5, color: "var(--text-dim)" }}>Any integration using <span className="code-inline">{confirmDel.prefix}.…</span> will immediately lose API access.</div>}
          onConfirm={() => { HS.act.deleteApiKey(confirmDel.id); toast.push({ kind: "success", title: "API key deleted" }); }}
          onClose={() => setConfirmDel(null)} />
      )}

      {modal === "create" && (
        <Modal title="Create API key" subtitle="Authenticate the Headscale gRPC/HTTP API" icon="apikey" onClose={() => setModal(null)}
          footer={created ? <><div className="spacer" /><button className="btn primary" onClick={() => setModal(null)}>Done</button></>
            : <><div className="spacer" /><button className="btn" onClick={() => setModal(null)}>Cancel</button>
              <button className="btn primary" onClick={() => { const full = HS.act.createApiKey(ttl); setCreated(full); toast.push({ kind: "success", title: "API key created" }); }}>Create key</button></>}>
          {created ? (
            <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
              <div className="badge online" style={{ alignSelf: "flex-start" }}><span className="dot" />Copy now — shown once</div>
              <CmdBlock text={created} />
              <span className="hint">Pass via <span className="code-inline">Authorization: Bearer {created.slice(0,12)}…</span></span>
            </div>
          ) : (
            <>
              <div style={{ display: "flex", gap: 9, padding: "11px 13px", background: "var(--warn-soft)", color: "var(--warn)", borderRadius: 8, fontSize: 12.5, lineHeight: 1.5 }}>
                <Ic name="shield" size={16} style={{ flexShrink: 0, marginTop: 1 }} />
                <div>API keys grant <b>full administrative access</b> — there are no per-resource scopes. Treat the secret like a root password.</div>
              </div>
              <div className="field"><label>Expiration</label>
                <Menu align="left" trigger={<button className="btn" style={{ justifyContent: "flex-start", width: 200 }}>{ttl} days<div style={{ flex: 1 }} /><Ic name="chevDown" size={14} /></button>}>
                  {[30, 90, 180, 365].map((d) => <MenuItem key={d} onClick={() => setTtl(d)}>{d} days</MenuItem>)}
                </Menu>
                <span className="hint">The only field Headscale stores besides the generated prefix.</span>
              </div>
            </>
          )}
        </Modal>
      )}
    </>
  );
}

function ToggleRow({ label, desc, on, set }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 12, padding: "10px 12px", background: "var(--surface-2)", borderRadius: 9, border: "1px solid var(--border)" }}>
      <div style={{ flex: 1 }}>
        <div style={{ fontSize: 13, fontWeight: 550 }}>{label}</div>
        <div style={{ fontSize: 12, color: "var(--text-dim)" }}>{desc}</div>
      </div>
      <span className={"toggle" + (on ? " on" : "")} onClick={() => set(!on)} />
    </div>
  );
}

Object.assign(window, { Keys, ToggleRow });
