// Dashboard — machines overview + session table

function Dashboard({ theme, machines, sessions, onOpenSession, onAddMachine, onDeleteMachine }) {
  const t = theme;
  const store = useStore();
  const [showAddMachine, setShowAddMachine] = React.useState(false);
  const [showConnect, setShowConnect] = React.useState(null);
  const [latestVersion, setLatestVersion] = React.useState(null);

  React.useEffect(() => {
    fetch('/cli/agent-connector.js', { method: 'HEAD' }).catch(() => {});
    fetch('/cli/agent-connector.js').then(r => r.text()).then(txt => {
      const m = txt.match(/CONNECTOR_VERSION\s*=\s*'([^']+)'/);
      if (m) setLatestVersion(m[1]);
    }).catch(() => {});
  }, []);

  const totals = {
    machines: machines.length,
    online: machines.filter(m => m.status === "online").length,
    running: sessions.filter(s => s.status === "running").length,
    waiting: sessions.filter(s => s.status === "waiting").length,
  };

  return (
    <main style={{ flex: 1, background: t.chatBg, color: t.fg, fontFamily: t.fontSans, overflowY: "auto", minWidth: 0 }}>
      {/* Header */}
      <div style={{ padding: "24px 32px", borderBottom: `1px solid ${t.line}`, background: t.bg2 }}>
        <div style={{ fontFamily: t.fontDisplay, fontWeight: t.weightHeading, fontSize: 22, letterSpacing: -0.2, lineHeight: 1, marginBottom: 6 }}>Overview</div>
        <div style={{ fontSize: 12, color: t.fg2, fontFamily: t.fontMono }}>
          {totals.machines} machines - {totals.online} online - {totals.running} running - {totals.waiting} waiting
        </div>
      </div>

      {/* Stats strip */}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 1, background: t.line, borderBottom: `1px solid ${t.line}` }}>
        <StatBlock theme={t} label="ACTIVE AGENTS" value={totals.running} sub={`${totals.waiting} waiting`} accent />
        <StatBlock theme={t} label="MACHINES ONLINE" value={`${totals.online}/${totals.machines}`} sub="relay connected" />
        <StatBlock theme={t} label="SESSIONS" value={sessions.length} sub={`${sessions.filter(s => s.status === 'idle').length} idle`} />
      </div>

      {/* Machines */}
      <div style={{ padding: "24px 32px 20px" }}>
        <div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", marginBottom: 12 }}>
          <h3 style={{ margin: 0, fontFamily: t.fontDisplay, fontWeight: t.weightHeading, fontSize: 14 }}>Machines</h3>
          <button onClick={() => setShowAddMachine(true)} style={{
            padding: "5px 12px", background: t.accent, color: t.bg, border: "none",
            borderRadius: t.radius, cursor: "pointer", fontSize: 12, fontFamily: t.fontSans, fontWeight: 600,
          }}>+ Add machine</button>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(300px, 1fr))", gap: 12 }}>
          {machines.map(m => (
            <MachineCard key={m.id} m={m} sessions={sessions.filter(s => s.machine_id === m.id)} theme={t}
              onOpenSession={onOpenSession} onConnect={() => setShowConnect(m)} onDelete={() => onDeleteMachine(m.id)}
              onUpdate={store.updateMachine} latestVersion={latestVersion} />
          ))}
          {machines.length === 0 && (
            <div style={{ padding: 20, color: t.fg3, fontSize: 13, fontStyle: "italic" }}>No machines yet. Add one to get started.</div>
          )}
        </div>
      </div>

      {/* Sessions table */}
      <div style={{ padding: "8px 32px 40px" }}>
        <h3 style={{ margin: "0 0 12px", fontFamily: t.fontDisplay, fontWeight: t.weightHeading, fontSize: 14 }}>Sessions</h3>
        <div style={{ border: `1px solid ${t.line}`, borderRadius: t.radius, overflow: "hidden", background: t.panel }}>
          <div style={{
            display: "grid", gridTemplateColumns: "24px 1.5fr 1fr 90px 100px",
            gap: 12, padding: "10px 16px", fontSize: 10, fontFamily: t.fontMono,
            letterSpacing: 0.8, textTransform: "uppercase", color: t.fg3,
            borderBottom: `1px solid ${t.line}`, background: t.panel2,
          }}>
            <span /><span>Session</span><span>Machine</span><span>Status</span><span style={{ textAlign: "right" }}>Updated</span>
          </div>
          {sessions.length === 0 && (
            <div style={{ padding: "16px", color: t.fg3, fontSize: 12, textAlign: "center" }}>No sessions yet</div>
          )}
          {sessions.map(s => {
            const m = machines.find(x => x.id === s.machine_id);
            return (
              <button key={s.id} onClick={() => onOpenSession(s.id)} style={{
                display: "grid", gridTemplateColumns: "24px 1.5fr 1fr 90px 100px",
                gap: 12, padding: "12px 16px", fontSize: 12.5, fontFamily: t.fontSans,
                color: t.fg, background: "transparent", border: "none",
                borderTop: `1px solid ${t.line}`, cursor: "pointer",
                width: "100%", textAlign: "left", alignItems: "center",
              }}
              onMouseEnter={e => e.currentTarget.style.background = t.panel2}
              onMouseLeave={e => e.currentTarget.style.background = "transparent"}>
                <StatusDot status={s.status} theme={t} size={7} />
                <span style={{ fontWeight: 500 }}>{s.name || s.agent_type || "Session"}</span>
                <span style={{ color: t.fg2, fontFamily: t.fontMono, fontSize: 11 }}>{m?.name || "?"}</span>
                <span style={{
                  fontFamily: t.fontMono, fontSize: 10, textTransform: "uppercase", letterSpacing: 0.8,
                  color: s.status === "running" ? t.accent : s.status === "waiting" ? t.warn : t.fg3,
                }}>{s.status}</span>
                <span style={{ fontFamily: t.fontMono, fontSize: 10.5, color: t.fg3, textAlign: "right" }}>{timeAgo(s.updated_at)}</span>
              </button>
            );
          })}
        </div>
      </div>

      {showAddMachine && <AddMachineModal theme={t} onClose={() => setShowAddMachine(false)} onAdd={onAddMachine} />}
      {showConnect && <ConnectModal theme={t} machine={showConnect} onClose={() => setShowConnect(null)} />}
    </main>
  );
}

function StatBlock({ theme, label, value, sub, accent, warn }) {
  const t = theme;
  return (
    <div style={{ padding: "16px 20px", background: t.bg2 }}>
      <div style={{ fontSize: 10, fontFamily: t.fontMono, letterSpacing: 1, color: t.fg3, marginBottom: 8 }}>{label}</div>
      <div style={{
        fontFamily: t.fontDisplay, fontSize: 28, fontWeight: t.weightHeading, lineHeight: 1,
        color: warn ? t.warn : accent ? t.accent : t.fg, marginBottom: 4,
      }}>{value}</div>
      <div style={{ fontSize: 11, color: t.fg2, fontFamily: t.fontMono }}>{sub}</div>
    </div>
  );
}

function MachineCard({ m, sessions, theme, onOpenSession, onConnect, onDelete, onUpdate, latestVersion }) {
  const t = theme;
  const running = sessions.filter(s => s.status === "running").length;
  const [updating, setUpdating] = React.useState(false);
  const needsUpdate = m.status === "online" && m.connector_version && latestVersion && m.connector_version !== latestVersion;
  const handleUpdate = async () => { setUpdating(true); try { await onUpdate(m.id); } finally { setTimeout(() => setUpdating(false), 5000); } };
  return (
    <div style={{ background: t.panel, border: `1px solid ${t.line}`, borderRadius: t.radius, padding: 16, display: "flex", flexDirection: "column", gap: 12 }}>
      <div style={{ display: "flex", alignItems: "flex-start", gap: 10 }}>
        <div style={{
          width: 32, height: 32, borderRadius: t.radius, background: t.panel2, border: `1px solid ${t.line2}`,
          display: "flex", alignItems: "center", justifyContent: "center",
          fontFamily: t.fontMono, fontSize: 11, color: t.fg2, fontWeight: 600, flexShrink: 0,
        }}>{m.name.split(" ").map(w => w[0]).join("").slice(0, 2)}</div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13.5, fontWeight: 600, color: t.fg }}>{m.name}</div>
          <div style={{ fontSize: 10.5, fontFamily: t.fontMono, color: t.fg3, marginTop: 1, display: "flex", alignItems: "center", gap: 6 }}>
            {m.connector_version || "no connector"}
            {needsUpdate && <button onClick={handleUpdate} disabled={updating} style={{
              padding: "1px 8px", background: t.warn, color: t.bg, border: "none",
              borderRadius: 999, cursor: "pointer", fontSize: 10, fontFamily: t.fontMono, fontWeight: 600,
            }}>{updating ? "Updating..." : "Update"}</button>}
          </div>
        </div>
        <div style={{ fontSize: 10, fontFamily: t.fontMono, display: "flex", alignItems: "center", gap: 5, color: m.status === "online" ? t.accent : t.fg3, textTransform: "uppercase", letterSpacing: 0.6 }}>
          <StatusDot status={m.status} theme={t} /> {m.status}
        </div>
      </div>
      <div style={{ borderTop: `1px solid ${t.line}`, paddingTop: 10, display: "flex", flexDirection: "column", gap: 4 }}>
        <div style={{ display: "flex", justifyContent: "space-between", fontSize: 10, fontFamily: t.fontMono, color: t.fg3, letterSpacing: 0.6, textTransform: "uppercase", marginBottom: 2 }}>
          <span>{sessions.length} session{sessions.length !== 1 ? "s" : ""}</span>
          <span>{running} running</span>
        </div>
        {sessions.slice(0, 3).map(s => (
          <button key={s.id} onClick={() => onOpenSession(s.id)} style={{
            display: "flex", alignItems: "center", gap: 8, padding: "4px 6px",
            background: "transparent", border: "none", borderRadius: t.radius / 2 + 2,
            cursor: "pointer", fontFamily: t.fontSans, color: t.fg2, textAlign: "left", fontSize: 11.5,
          }}
          onMouseEnter={e => e.currentTarget.style.background = t.panel2}
          onMouseLeave={e => e.currentTarget.style.background = "transparent"}>
            <StatusDot status={s.status} theme={t} />
            <span style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", color: t.fg }}>{s.name || s.agent_type}</span>
            <span style={{ fontFamily: t.fontMono, fontSize: 10, color: t.fg3 }}>{timeAgo(s.updated_at)}</span>
          </button>
        ))}
      </div>
      <div style={{ display: "flex", gap: 6 }}>
        <button onClick={onConnect} style={{ flex: 1, padding: "6px", background: "transparent", border: `1px solid ${t.line2}`, borderRadius: t.radius, color: t.fg2, fontSize: 11, fontFamily: t.fontMono, cursor: "pointer" }}>Connect info</button>
        <button onClick={onDelete} style={{ padding: "6px 10px", background: "transparent", border: `1px solid ${t.err}33`, borderRadius: t.radius, color: t.err, fontSize: 11, fontFamily: t.fontMono, cursor: "pointer" }}>Remove</button>
      </div>
    </div>
  );
}

function AddMachineModal({ theme, onClose, onAdd }) {
  const t = theme;
  const [name, setName] = React.useState("");
  const handleAdd = async () => {
    if (!name.trim()) return;
    await onAdd(name.trim());
    onClose();
  };
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,0.5)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 200 }}>
      <div onClick={e => e.stopPropagation()} style={{ width: 400, background: t.panel, border: `1px solid ${t.line2}`, borderRadius: t.radius + 4, padding: 24, fontFamily: t.fontSans, color: t.fg, animation: "ac-fade 0.2s" }}>
        <div style={{ fontFamily: t.fontDisplay, fontWeight: t.weightHeading, fontSize: 18, marginBottom: 16 }}>Add machine</div>
        <input value={name} onChange={e => setName(e.target.value)} placeholder="Machine name"
          onKeyDown={e => e.key === "Enter" && handleAdd()}
          style={{ width: "100%", padding: "9px 12px", background: t.panel2, border: `1px solid ${t.line2}`, borderRadius: t.radius, color: t.fg, fontFamily: t.fontSans, fontSize: 13, outline: "none", boxSizing: "border-box", marginBottom: 16 }} />
        <div style={{ display: "flex", gap: 8, justifyContent: "flex-end" }}>
          <button onClick={onClose} style={{ padding: "8px 16px", background: "transparent", border: `1px solid ${t.line2}`, borderRadius: t.radius, color: t.fg2, cursor: "pointer", fontSize: 13 }}>Cancel</button>
          <button onClick={handleAdd} style={{ padding: "8px 16px", background: t.accent, color: t.bg, border: "none", borderRadius: t.radius, cursor: "pointer", fontSize: 13, fontWeight: 600 }}>Add</button>
        </div>
      </div>
    </div>
  );
}

function ConnectModal({ theme, machine, onClose }) {
  const t = theme;
  const [copied, setCopied] = React.useState(false);
  const relayUrl = window.location.origin;
  const cmd = `curl -O ${relayUrl}/cli/agent-connector.js && node agent-connector.js --relay ${relayUrl} --token ${machine.connect_token || '<TOKEN>'}`;
  const installCmd = `node agent-connector.js --install --relay ${relayUrl} --token ${machine.connect_token || '<TOKEN>'}`;
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,0.5)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 200 }}>
      <div onClick={e => e.stopPropagation()} style={{ width: 560, maxWidth: "90vw", background: t.panel, border: `1px solid ${t.line2}`, borderRadius: t.radius + 4, padding: 24, fontFamily: t.fontSans, color: t.fg, animation: "ac-fade 0.2s" }}>
        <div style={{ fontFamily: t.fontDisplay, fontWeight: t.weightHeading, fontSize: 18, marginBottom: 8 }}>Connect {machine.name}</div>
        <div style={{ fontSize: 12, color: t.fg2, marginBottom: 16 }}>Run this on the machine to connect the agent:</div>
        <div style={{ padding: 12, background: t.panel2, border: `1px solid ${t.line}`, borderRadius: t.radius, fontFamily: t.fontMono, fontSize: 11, color: t.accent, wordBreak: "break-all", lineHeight: 1.5, marginBottom: 8 }}>{cmd}</div>
        <div style={{ fontSize: 11, color: t.fg3, marginBottom: 12 }}>To install as a service (persists after reboot):</div>
        <div style={{ padding: 12, background: t.panel2, border: `1px solid ${t.line}`, borderRadius: t.radius, fontFamily: t.fontMono, fontSize: 11, color: t.fg2, wordBreak: "break-all", lineHeight: 1.5, marginBottom: 16 }}>{installCmd}</div>
        <div style={{ display: "flex", gap: 8, justifyContent: "flex-end" }}>
          <button onClick={() => { navigator.clipboard?.writeText(cmd); setCopied(true); setTimeout(() => setCopied(false), 1500); }}
            style={{ padding: "8px 16px", background: copied ? t.accent : "transparent", border: `1px solid ${copied ? t.accent : t.line2}`, borderRadius: t.radius, color: copied ? t.bg : t.fg2, cursor: "pointer", fontSize: 13 }}>
            {copied ? "Copied!" : "Copy command"}
          </button>
          <button onClick={onClose} style={{ padding: "8px 16px", background: t.accent, color: t.bg, border: "none", borderRadius: t.radius, cursor: "pointer", fontSize: 13, fontWeight: 600 }}>Done</button>
        </div>
      </div>
    </div>
  );
}

window.Dashboard = Dashboard;
