
const HW_ITEMS = [
  {
    id: "car-rpi",
    label: "Car Raspberry Pi 4/5",
    category: "COMPUTE",
    color: "#a855f7",
    specs: [
      ["Role", "UTS car mode — CAN reader & UDP sender"],
      ["OS", "Ubuntu + SocketCAN"],
      ["CAN interface", "can0 via MCP2517FD HAT"],
      ["Transport", "UDP :5005 batched, TCP :5006 recovery"],
      ["Container", "Docker Compose"],
    ],
    desc: "Auto-detects its role at boot by probing for can0. Batches 20 CAN messages per 50 ms burst and ships them wirelessly. A 60-second ring buffer enables retransmission of any dropped packets.",
    icon: (
      <svg viewBox="0 0 48 48" width="42" height="42" fill="none" stroke="currentColor" strokeWidth="1.5">
        <rect x="6" y="10" width="36" height="28" rx="3" />
        <rect x="11" y="15" width="10" height="8" rx="1" opacity="0.5" />
        <rect x="27" y="15" width="10" height="8" rx="1" opacity="0.5" />
        <line x1="14" y1="30" x2="34" y2="30" opacity="0.4" />
        <line x1="14" y1="34" x2="28" y2="34" opacity="0.4" />
        <circle cx="38" cy="34" r="2" fill="currentColor" opacity="0.6" />
      </svg>
    ),
  },
  {
    id: "can-hat",
    label: "MCP2517FD CAN HAT",
    category: "INTERFACE",
    color: "#D6AB39",
    specs: [
      ["Controller", "MCP2517FD (CAN FD)"],
      ["Crystal", "20 MHz S73305"],
      ["Transceiver", "MCP2562FDT-HSN"],
      ["Bus", "SPI to RPi GPIO"],
      ["Bitrate", "500 kbps (standard CAN)"],
    ],
    desc: "SPI-connected CAN FD controller that bridges the vehicle's CAN bus to the Raspberry Pi. The interrupt GPIO (25) is configurable for different HAT wiring configurations.",
    icon: (
      <svg viewBox="0 0 48 48" width="42" height="42" fill="none" stroke="currentColor" strokeWidth="1.5">
        <rect x="4" y="14" width="40" height="20" rx="3" />
        <rect x="8" y="18" width="8" height="12" rx="1" opacity="0.5" />
        <rect x="20" y="18" width="8" height="12" rx="1" opacity="0.5" />
        <rect x="32" y="18" width="8" height="12" rx="1" opacity="0.5" />
        <line x1="4" y1="38" x2="4" y2="42" strokeWidth="1" opacity="0.4" />
        <line x1="10" y1="38" x2="10" y2="42" strokeWidth="1" opacity="0.4" />
        <line x1="16" y1="38" x2="16" y2="42" strokeWidth="1" opacity="0.4" />
        <line x1="22" y1="38" x2="22" y2="42" strokeWidth="1" opacity="0.4" />
        <line x1="28" y1="38" x2="28" y2="42" strokeWidth="1" opacity="0.4" />
        <line x1="34" y1="38" x2="34" y2="42" strokeWidth="1" opacity="0.4" />
        <line x1="40" y1="38" x2="40" y2="42" strokeWidth="1" opacity="0.4" />
      </svg>
    ),
  },
  {
    id: "radio",
    label: "Ubiquiti 5 GHz Link",
    category: "RF LINK",
    color: "#22d3ee",
    specs: [
      ["Frequency", "5 GHz"],
      ["CAN telemetry", ":5005 UDP + :5006 TCP recovery"],
      ["Video", "RTSP :8554 → WebRTC WHEP :8889"],
      ["Audio", "Audio streaming over link"],
      ["Range", "Competition track coverage"],
    ],
    desc: "Point-to-point 5 GHz link carrying CAN telemetry, live H.264 video, and audio over a single radio link. UDP for low-latency streaming, TCP ring buffer for gap recovery — near-zero data loss even under intermittent RF conditions.",
    icon: (
      <svg viewBox="0 0 48 48" width="42" height="42" fill="none" stroke="currentColor" strokeWidth="1.5">
        <path d="M24 32 L24 42" />
        <path d="M16 44 L32 44" />
        <path d="M12 28 Q24 14 36 28" opacity="0.8" />
        <path d="M6 22 Q24 4 42 22" opacity="0.4" />
        <circle cx="24" cy="33" r="2.5" fill="currentColor" opacity="0.8" />
      </svg>
    ),
  },
  {
    id: "base-rpi",
    label: "Base Station RPi",
    category: "COMPUTE",
    color: "#a855f7",
    specs: [
      ["Role", "UTS base mode — receiver & publisher"],
      ["Services", "Redis, WebSocket bridge, status server"],
      ["DB write", "TimescaleDB (direct over LAN/VPN)"],
      ["Status page", ":8080 HTTP"],
      ["WS feed", ":9080 WebSocket → PECAN"],
    ],
    desc: "Runs on a MacBook or RPi at pitside. No CAN hardware needed — role is auto-detected. Receives UDP from the car, publishes to Redis, bridges to WebSocket for PECAN, and simultaneously writes to the server TimescaleDB.",
    icon: (
      <svg viewBox="0 0 48 48" width="42" height="42" fill="none" stroke="currentColor" strokeWidth="1.5">
        <rect x="4" y="10" width="40" height="26" rx="3" />
        <line x1="4" y1="36" x2="44" y2="36" opacity="0.4" />
        <rect x="14" y="38" width="20" height="4" rx="2" />
        <rect x="10" y="16" width="12" height="8" rx="1" opacity="0.4" />
        <circle cx="32" cy="20" r="5" opacity="0.4" />
        <line x1="28" y1="28" x2="36" y2="28" opacity="0.3" />
      </svg>
    ),
  },
];

function HardwareCard({ item }) {
  const [open, setOpen] = React.useState(false);
  return (
    <div
      onClick={() => setOpen(!open)}
      style={{
        background: open
          ? `linear-gradient(135deg, ${item.color}15 0%, rgba(32,32,47,0.9) 100%)`
          : "rgba(32,32,47,0.7)",
        border: `1px solid ${open ? item.color + "60" : item.color + "25"}`,
        borderRadius: 16, padding: "28px 28px 24px",
        cursor: "pointer", transition: "all 0.25s",
        boxShadow: open ? `0 0 32px ${item.color}20` : "none",
      }}
      onMouseEnter={e => { if (!open) e.currentTarget.style.borderColor = item.color + "50"; }}
      onMouseLeave={e => { if (!open) e.currentTarget.style.borderColor = item.color + "25"; }}
    >
      <div style={{ display: "flex", alignItems: "flex-start", gap: 16, marginBottom: 16 }}>
        <div style={{ color: item.color, flexShrink: 0 }}>{item.icon}</div>
        <div style={{ flex: 1 }}>
          <div style={{ fontFamily: "'Space Mono', monospace", fontSize: 9, color: item.color, letterSpacing: 3, textTransform: "uppercase", marginBottom: 6, opacity: 0.8 }}>{item.category}</div>
          <h3 style={{ fontFamily: "'Orbitron', sans-serif", fontWeight: 700, fontSize: 15, color: "#fff", marginBottom: 8, lineHeight: 1.2 }}>{item.label}</h3>
          <p style={{ fontSize: 13, color: "rgba(255,255,255,0.55)", lineHeight: 1.6 }}>{item.desc}</p>
        </div>
        <div style={{ color: item.color, fontSize: 18, flexShrink: 0, marginTop: 8, transition: "transform 0.2s", transform: open ? "rotate(90deg)" : "none" }}>›</div>
      </div>

      {open && (
        <div style={{ borderTop: `1px solid ${item.color}20`, paddingTop: 16, marginTop: 4 }}>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px 20px" }}>
            {item.specs.map(([k, v], i) => (
              <div key={i} style={{ display: "flex", gap: 8, alignItems: "flex-start" }}>
                <span style={{ fontFamily: "'Space Mono', monospace", fontSize: 10, color: item.color, opacity: 0.7, flexShrink: 0, marginTop: 1 }}>{k}:</span>
                <span style={{ fontFamily: "'Space Mono', monospace", fontSize: 10, color: "rgba(255,255,255,0.65)", lineHeight: 1.4 }}>{v}</span>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

function Hardware() {
  return (
    <section id="hardware" style={{ padding: "100px 2rem" }}>
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>
        <SectionHeader
          tag="03 / Hardware"
          title="Hardware Stack"
          subtitle="Every component is sourced, configured, and integrated by the WFR team. Click any card to see specs."
        />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(340px, 1fr))", gap: 20, marginTop: 48 }}>
          {HW_ITEMS.map(item => <HardwareCard key={item.id} item={item} />)}
        </div>

        {/* Software stack footnote */}
        <div style={{
          marginTop: 32, padding: "20px 28px",
          background: "rgba(168,85,247,0.06)", border: "1px solid rgba(168,85,247,0.15)", borderRadius: 12,
          display: "flex", gap: 24, flexWrap: "wrap", alignItems: "center",
        }}>
          <span style={{ fontFamily: "'Space Mono', monospace", fontSize: 10, color: "rgba(168,85,247,0.7)", letterSpacing: 2, textTransform: "uppercase", flexShrink: 0 }}>Software on RPi:</span>
          {["Ubuntu (arm64)", "SocketCAN + can-utils", "Python 3.11+", "Redis", "Docker Compose", "asyncio + WebSockets"].map(s => (
            <span key={s} style={{
              fontFamily: "'Space Mono', monospace", fontSize: 11, color: "rgba(255,255,255,0.55)",
              background: "rgba(255,255,255,0.05)", border: "1px solid rgba(255,255,255,0.1)", borderRadius: 6, padding: "4px 10px",
            }}>{s}</span>
          ))}
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { Hardware });
