
const SERVER_SERVICES = [
  {
    color: "#22d3ee",
    name: "TimescaleDB",
    port: ":5432",
    tag: "TIME-SERIES DB",
    body: "PostgreSQL extension with hypertable partitioning for time-series CAN data. Receives direct writes from the base station UTS and batch uploads from the Flight Recorder via the data-downloader API.",
  },
  {
    color: "#f97316",
    name: "Grafana",
    port: ":8087",
    tag: "ANALYTICS",
    body: "Pre-built dashboards for lap-by-lap analysis, battery degradation, and drivetrain health. A Cloudflare Workers proxy exposes dashboards publicly without opening internal ports.",
  },
  {
    color: "#a855f7",
    name: "Data Downloader",
    port: "FastAPI",
    tag: "API",
    body: "FastAPI service accepting batch CAN frame uploads (POST /api/can-frames/batch) from the Flight Recorder. Decodes frames, inserts into TimescaleDB, and serves query endpoints for filtered data export.",
  },
  {
    color: "#D6AB39",
    name: "File Uploader",
    port: "Web UI",
    tag: "UTILITY",
    body: "Web interface for CSV-format CAN log uploads. Enables post-session data ingestion from bench recordings or exported PECAN sessions.",
  },
  {
    color: "#ef4444",
    name: "Health Monitor",
    port: "Docker",
    tag: "OPS",
    body: "Watches all Docker container health states and alerts on failures. Keeps the server stack self-healing during multi-day competition sessions.",
  },
  {
    color: "#a855f7",
    name: "Slackbot",
    port: "Slack API",
    tag: "NOTIFICATIONS",
    body: "Pushes telemetry alerts and system health events to the team Slack. Notifies engineers of connection drops, data anomalies, or upload completions.",
  },
];

function ServerStack() {
  return (
    <section id="server" style={{ padding: "100px 2rem", background: "rgba(0,0,0,0.2)" }}>
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>
        <SectionHeader
          tag="10 / Server Stack"
          title="Server Stack"
          subtitle="A VPS-hosted Docker Compose stack providing long-term storage, historical analysis, and team alerting."
        />

        {/* Architecture summary */}
        <div style={{
          marginTop: 40, padding: "24px 28px",
          background: "rgba(34,211,238,0.05)", border: "1px solid rgba(34,211,238,0.2)",
          borderRadius: 14, display: "flex", gap: 20, flexWrap: "wrap", alignItems: "center",
        }}>
          <div style={{ fontFamily: "'Space Mono', monospace", fontSize: 10, color: "rgba(34,211,238,0.7)", letterSpacing: 2, textTransform: "uppercase", flexShrink: 0 }}>Deploy:</div>
          {["Docker Compose", "VPS (Linux)", "Nginx reverse proxy", "HTTPS / TLS", "Cloudflare Workers (Grafana proxy)"].map(s => (
            <span key={s} style={{
              fontFamily: "'Space Mono', monospace", fontSize: 11, color: "rgba(255,255,255,0.6)",
              background: "rgba(255,255,255,0.05)", border: "1px solid rgba(255,255,255,0.1)",
              borderRadius: 6, padding: "4px 10px",
            }}>{s}</span>
          ))}
        </div>

        {/* Service grid */}
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))", gap: 18, marginTop: 32 }}>
          {SERVER_SERVICES.map(s => (
            <div key={s.name} style={{
              background: "rgba(32,32,47,0.6)", border: `1px solid ${s.color}20`,
              borderRadius: 14, padding: "22px 22px 18px",
              transition: "all 0.2s",
            }}
              onMouseEnter={e => { e.currentTarget.style.background = `linear-gradient(135deg, ${s.color}10, rgba(32,32,47,0.8))`; e.currentTarget.style.borderColor = s.color + "40"; }}
              onMouseLeave={e => { e.currentTarget.style.background = "rgba(32,32,47,0.6)"; e.currentTarget.style.borderColor = s.color + "20"; }}
            >
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 10 }}>
                <div>
                  <div style={{ fontFamily: "'Orbitron', sans-serif", fontWeight: 700, fontSize: 15, color: "#fff", marginBottom: 3 }}>{s.name}</div>
                  <div style={{ fontFamily: "'Space Mono', monospace", fontSize: 10, color: s.color, opacity: 0.8 }}>{s.port}</div>
                </div>
                <span style={{
                  fontFamily: "'Space Mono', monospace", fontSize: 8, color: s.color,
                  background: s.color + "15", border: `1px solid ${s.color}30`,
                  borderRadius: 4, padding: "3px 7px", letterSpacing: 1.5, textTransform: "uppercase", flexShrink: 0,
                }}>{s.tag}</span>
              </div>
              <p style={{ fontSize: 13, color: "rgba(255,255,255,0.55)", lineHeight: 1.65 }}>{s.body}</p>
            </div>
          ))}
        </div>

        {/* Grafana screenshots */}
        <div style={{ marginTop: 48 }}>
          <div style={{ fontFamily: "'Space Mono', monospace", fontSize: 9, color: "rgba(255,255,255,0.4)", letterSpacing: 2, textTransform: "uppercase", marginBottom: 16 }}>Live Dashboards — WFR26 Data</div>
          <div style={{ display: "grid", gridTemplateColumns: "3fr 2fr", gap: 16, alignItems: "start" }}>
            <div>
              <img src="assets/Grafana1.png" alt="Grafana thermistor and inverter dashboard"
                style={{ width: "100%", borderRadius: 10, border: "1px solid rgba(255,255,255,0.08)", boxShadow: "0 8px 32px rgba(0,0,0,0.5)", display: "block" }} />
              <div style={{ fontFamily: "'Space Mono', monospace", fontSize: 10, color: "rgba(255,255,255,0.35)", marginTop: 8 }}>Thermistor data (Module 4) + Cooling / Inverter inputs</div>
            </div>
            <div>
              <img src="assets/Grafana2.png" alt="Grafana battery cell voltage and VCU state"
                style={{ width: "100%", borderRadius: 10, border: "1px solid rgba(255,255,255,0.08)", boxShadow: "0 8px 32px rgba(0,0,0,0.5)", display: "block" }} />
              <div style={{ fontFamily: "'Space Mono', monospace", fontSize: 10, color: "rgba(255,255,255,0.35)", marginTop: 8 }}>Module voltage + Battery thermistor heatmap + VCU state</div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { ServerStack });
