/* Dashboard / overview */
function Dashboard({ go }) {
  const s = useStore();
  const online = s.machines.filter((m) => m.online).length;
  const offline = s.machines.length - online;
  const expiringSoon = s.machines.filter((m) => expiryInfo(m.expiry).soon).length;
  const exitNodes = s.machines.filter((m) => s.isExitNode(m) && s.exitApproved(m)).length;
  let pendingRoutes = 0, advertised = 0;
  s.machines.forEach((m) => s.subnetPrefixes(m).forEach((c) => { advertised++; if (!m.approvedRoutes.includes(c)) pendingRoutes++; }));
  const pendingReg = s.pending.length;

  const spark1 = [8, 9, 9, 11, 10, 12, 13, 12, 14, 13, 15, 16];
  const spark2 = [40, 42, 41, 45, 48, 47, 52, 55, 53, 58, 60, 62];

  return (
    <div className="page fade-up">
      <div className="section-head">
        <div>
          <h2 style={{ fontSize: 19 }}>Overview</h2>
          <div className="sub">Real-time state of <b className="mono">{s.serverInfo.url.replace("https://", "")}</b></div>
        </div>
        <div className="spacer" />
        <RefreshBtn />
        <span className="badge online"><span className="dot" />Control plane healthy</span>
      </div>

      {/* stats */}
      <div className="stat-grid" style={{ marginBottom: 14 }}>
        <div className="stat">
          <div className="label"><Ic name="machines" size={15} />Machines online</div>
          <div className="value">{online}<span className="unit">/ {s.machines.length}</span></div>
          <Sparkline data={spark1} />
          <div className="delta up"><Ic name="arrowUp" size={13} /><b>+3</b> this week</div>
        </div>
        <div className="stat">
          <div className="label"><Ic name="users" size={15} />Users</div>
          <div className="value">{s.users.length}</div>
          <div className="delta"><span style={{ color: "var(--text-faint)" }}>{s.users.filter(u=>u.provider==="oidc").length} via OIDC</span></div>
        </div>
        <div className="stat">
          <div className="label"><Ic name="routes" size={15} />Exit nodes</div>
          <div className="value">{exitNodes}</div>
          <div className="delta"><span style={{ color: "var(--text-faint)" }}>{advertised} subnet routes</span></div>
        </div>
        <div className="stat">
          <div className="label"><Ic name="activity" size={15} />Traffic (24h)</div>
          <div className="value">62<span className="unit">GB</span></div>
          <Sparkline data={spark2} color="var(--online)" />
          <div className="delta up"><Ic name="arrowUp" size={13} /><b>+18%</b> vs yesterday</div>
        </div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1.6fr 1fr", gap: 14, alignItems: "start" }} className="dash-cols">
        {/* left: attention + machines preview */}
        <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          {(expiringSoon > 0 || pendingRoutes > 0 || offline > 0 || pendingReg > 0) && (
            <div className="card card-pad" style={{ display: "flex", flexDirection: "column", gap: 11 }}>
              <div className="section-head" style={{ margin: 0 }}>
                <h2>Needs attention</h2><div className="spacer" />
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                {pendingReg > 0 && (
                  <AttnRow icon="clock" cls="accent" title={`${pendingReg} node${pendingReg>1?"s":""} awaiting registration approval`}
                    desc="Devices logged in via OIDC and need an admin to admit them." action="Approve" onAction={() => go("machines")} />
                )}
                {expiringSoon > 0 && (
                  <AttnRow icon="clock" cls="warn" title={`${expiringSoon} machine key${expiringSoon>1?"s":""} expiring soon`}
                    desc="Re-authenticate or disable expiry before they drop off the tailnet." action="Review" onAction={() => go("machines")} />
                )}
                {pendingRoutes > 0 && (
                  <AttnRow icon="routes" cls="info" title={`${pendingRoutes} subnet route${pendingRoutes>1?"s":""} awaiting approval`}
                    desc="Advertised by a node but not in its approved set." action="Approve" onAction={() => go("routes")} />
                )}
                {offline > 0 && (
                  <AttnRow icon="power" cls="" title={`${offline} machine${offline>1?"s":""} offline`}
                    desc="Last seen more than an hour ago." action="View" onAction={() => go("machines")} />
                )}
              </div>
            </div>
          )}

          <div className="card">
            <div className="tbl-toolbar">
              <b style={{ fontSize: 13.5 }}>Recently active</b>
              <div style={{ flex: 1 }} />
              <button className="btn sm ghost" onClick={() => go("machines")}>All machines <Ic name="chevRight" size={14} /></button>
            </div>
            <div className="tbl-scroll">
              <table className="tbl">
                <tbody>
                  {s.machines.slice().sort((a, b) => b.lastSeen - a.lastSeen).slice(0, 6).map((m) => {
                    const u = s.userById(m.user);
                    return (
                      <tr key={m.id} onClick={() => go("machines")}>
                        <td style={{ width: 30 }}><span className={"dot-status " + (m.online ? "online" : "offline")} /></td>
                        <td>
                          <div className="cell-main"><Ic name={osIcon(m.kind, m.os)} size={16} style={{ color: "var(--text-dim)" }} />{m.name}</div>
                        </td>
                        <td className="hide-sm"><span className="ip">{m.ip4}</span></td>
                        <td className="hide-sm">{u && <span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}><Avatar user={u} size={20} /><span style={{ fontSize: 12.5, color: "var(--text-dim)" }}>{u.name}</span></span>}</td>
                        <td style={{ textAlign: "right", color: "var(--text-faint)", fontSize: 12 }}>{m.online ? "Connected" : relTime(m.lastSeen)}</td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </div>
        </div>

        {/* right: activity feed + server info */}
        <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          <div className="card card-pad">
            <div className="section-head" style={{ margin: "0 0 12px" }}><h2>Activity</h2></div>
            <div style={{ display: "flex", flexDirection: "column", gap: 0 }}>
              {s.activity.map((a, i) => {
                const u = s.userById(a.user);
                return (
                  <div key={a.id} style={{ display: "flex", gap: 11, paddingBottom: i === s.activity.length - 1 ? 0 : 14, position: "relative" }}>
                    <div style={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
                      <span style={{ width: 26, height: 26, borderRadius: 99, background: "var(--surface-2)", display: "grid", placeItems: "center", color: actColor(a.kind), flexShrink: 0 }}>
                        <Ic name={actIcon(a.kind)} size={14} />
                      </span>
                      {i < s.activity.length - 1 && <span style={{ width: 1.5, flex: 1, background: "var(--border)", marginTop: 4 }} />}
                    </div>
                    <div style={{ minWidth: 0, paddingBottom: 2 }}>
                      <div style={{ fontSize: 13, lineHeight: 1.4 }}>{a.text}</div>
                      <div style={{ fontSize: 11.5, color: "var(--text-faint)" }}>{u ? u.name + " · " : ""}{relTime(a.t)}</div>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>

          <div className="card card-pad">
            <div className="section-head" style={{ margin: "0 0 12px" }}><h2>Server</h2></div>
            <div style={{ display: "flex", flexDirection: "column", gap: 10, fontSize: 13 }}>
              <InfoRow label="Version"><span className="badge accent">{s.serverInfo.version}</span></InfoRow>
              <InfoRow label="Uptime"><span className="mono">{s.serverInfo.uptime != null ? dur(s.serverInfo.uptime) : "—"}</span></InfoRow>
              <InfoRow label="IPv4 prefix">{s.serverInfo.ipv4 ? <span className="ip">{s.serverInfo.ipv4}</span> : <span style={{ color: "var(--text-faint)", fontSize: 12 }}>not exposed by API</span>}</InfoRow>
              <InfoRow label="IPv6 prefix">{s.serverInfo.ipv6 ? <span className="ip">{s.serverInfo.ipv6}</span> : <span style={{ color: "var(--text-faint)", fontSize: 12 }}>not exposed by API</span>}</InfoRow>
              <InfoRow label="DNS"><span className="badge online"><span className="dot" />MagicDNS on</span></InfoRow>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function AttnRow({ icon, cls, title, desc, action, onAction }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 12, padding: "11px 12px", background: "var(--surface-2)", borderRadius: 9, border: "1px solid var(--border)" }}>
      <span className={"badge " + cls} style={{ width: 30, height: 30, borderRadius: 8, padding: 0, justifyContent: "center" }}><Ic name={icon} size={16} /></span>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 13, fontWeight: 550 }}>{title}</div>
        <div style={{ fontSize: 12, color: "var(--text-dim)" }}>{desc}</div>
      </div>
      <button className="btn sm" onClick={onAction}>{action}</button>
    </div>
  );
}
function InfoRow({ label, children }) {
  return (
    <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
      <span style={{ color: "var(--text-dim)" }}>{label}</span>
      {children}
    </div>
  );
}
function actIcon(k) { return ({ join: "plus", route: "routes", expire: "clock", acl: "acl", key: "key", offline: "power" })[k] || "info"; }
function actColor(k) { return ({ join: "var(--online)", route: "var(--accent)", expire: "var(--warn)", acl: "var(--info)", key: "var(--accent)", offline: "var(--text-faint)" })[k] || "var(--text-dim)"; }

window.Dashboard = Dashboard;
window.InfoRow = InfoRow;
