import { useEffect, useMemo, useRef, useState } from "react";
import Globe from "react-globe.gl";
import { motion, AnimatePresence } from "framer-motion";
import {
  Activity,
  CheckCircle2,
  Circle,
  Factory,
  Gauge,
  Package,
  RefreshCcw,
  Sun,
  Truck,
  Wrench,
  Zap,
} from "lucide-react";

const TASKS = ["easy", "medium", "hard"];
const STEP_INTERVAL_MS = 2200;
const explicitApiBase = import.meta.env.VITE_API_BASE?.replace(/\/$/, "");
const isLocalPreview =
  typeof window !== "undefined" &&
  ["localhost", "127.0.0.1"].includes(window.location.hostname) &&
  window.location.port === "4173";
const API_BASE = explicitApiBase || (isLocalPreview ? "http://127.0.0.1:8000" : "");

const EARTH_TEXTURE = "https://unpkg.com/three-globe/example/img/earth-blue-marble.jpg";
const EARTH_BUMP    = "https://unpkg.com/three-globe/example/img/earth-topology.png";
const STARFIELD     = "https://unpkg.com/three-globe/example/img/night-sky.png";

function apiUrl(path) {
  return `${API_BASE}${path}`;
}

// ─── data hook ───────────────────────────────────────────────────────────────
function useDemoData() {
  const [snapshot, setSnapshot] = useState(null);
  const [loading, setLoading]   = useState(true);
  const [playing, setPlaying]   = useState(true);
  const [taskName, setTaskName] = useState("medium");
  const [error, setError]       = useState("");
  const steppingRef = useRef(false);

  async function loadSnapshot() {
    try {
      const res = await fetch(apiUrl("/api/ui/demo"));
      if (!res.ok) throw new Error(`Snapshot ${res.status}`);
      const data = await res.json();
      setSnapshot(data);
      setTaskName(data.task_name ?? "medium");
      setError("");
    } catch (err) {
      setError(err instanceof Error ? err.message : "Unable to load snapshot");
    } finally {
      setLoading(false);
    }
  }

  async function resetDemo(nextTask) {
    setLoading(true);
    try {
      const res = await fetch(
        apiUrl(`/api/ui/demo/reset?task_name=${encodeURIComponent(nextTask)}`),
        { method: "POST" }
      );
      if (!res.ok) throw new Error(`Reset ${res.status}`);
      const data = await res.json();
      setSnapshot(data);
      setTaskName(data.task_name ?? nextTask);
      setPlaying(true);
      setError("");
    } catch (err) {
      setError(err instanceof Error ? err.message : "Unable to reset");
    } finally {
      setLoading(false);
    }
  }

  async function stepDemo() {
    if (steppingRef.current || loading) return;
    if (snapshot?.done || (snapshot?.step_count ?? 0) >= (snapshot?.max_steps ?? Infinity)) {
      setPlaying(false);
      return;
    }
    steppingRef.current = true;
    try {
      const res = await fetch(apiUrl("/api/ui/demo/step"), { method: "POST" });
      if (!res.ok) throw new Error(`Step ${res.status}`);
      const data = await res.json();
      setSnapshot(data);
      if (data.done || (data.step_count ?? 0) >= (data.max_steps ?? Infinity))
        setPlaying(false);
      setError("");
    } catch (err) {
      setPlaying(false);
      setError(err instanceof Error ? err.message : "Unable to step");
    } finally {
      steppingRef.current = false;
    }
  }

  useEffect(() => { loadSnapshot(); }, []);

  useEffect(() => {
    if (!playing || loading || snapshot?.done ||
        (snapshot?.step_count ?? 0) >= (snapshot?.max_steps ?? Infinity)) return;
    const timer = window.setInterval(stepDemo, STEP_INTERVAL_MS);
    return () => window.clearInterval(timer);
  }, [playing, loading, snapshot]);

  return { snapshot, loading, playing, taskName, error, setPlaying, resetDemo, stepDemo };
}

// ─── colour helpers ──────────────────────────────────────────────────────────
function platformColor(action) {
  switch (action) {
    case "produce":  return "#ffb86b";
    case "assemble": return "#9caaff";
    case "deliver":  return "#7cf7c9";
    case "recharge": return "#59b8ff";
    default:         return "#95a2bb";
  }
}
function energyColor(v) {
  if (v < 20) return "#ff7171";
  if (v < 40) return "#ffb86b";
  return "#7cf7c9";
}

// ─── reward sparkline ────────────────────────────────────────────────────────
function RewardSparkline({ history }) {
  if (!history || history.length < 2) return null;
  const W = 160, H = 36;
  const min   = Math.min(...history);
  const max   = Math.max(...history);
  const range = max - min || 1;
  const pts   = history.map((v, i) => {
    const x = (i / (history.length - 1)) * W;
    const y = H - ((v - min) / range) * (H - 4) - 2;
    return `${x.toFixed(1)},${y.toFixed(1)}`;
  }).join(" ");
  const zeroY = H - ((0 - min) / range) * (H - 4) - 2;
  return (
    <svg width={W} height={H} className="sparkline">
      <line x1="0" y1={zeroY.toFixed(1)} x2={W} y2={zeroY.toFixed(1)} className="spark-zero" />
      <polyline points={pts} className="spark-line" />
      <circle cx={W} cy={H - ((history[history.length - 1] - min) / range) * (H - 4) - 2}
        r="2.5" className="spark-dot" />
    </svg>
  );
}

// ─── Globe view ───────────────────────────────────────────────────────────────
function GlobeView({ snapshot, globeSize }) {
  const globeRef     = useRef(null);
  const pathStoreRef = useRef([]);
  const snapAnimRef  = useRef(null);
  const [pathData, setPathData] = useState([]);

  // Lock camera controls + snap back to equator after user interaction
  useEffect(() => {
    if (!globeRef.current) return;
    const controls = globeRef.current.controls();
    controls.autoRotate      = true;
    controls.autoRotateSpeed = 0.6;
    controls.enablePan       = false;
    controls.enableZoom      = false;
    controls.minDistance     = 210;
    controls.maxDistance     = 310;
    controls.minPolarAngle   = Math.PI * 0.25;
    controls.maxPolarAngle   = Math.PI * 0.75;

    const snapToEquator = () => {
      if (snapAnimRef.current) cancelAnimationFrame(snapAnimRef.current);
      const camera = globeRef.current.camera();

      const tick = () => {
        const tx = controls.target.x, ty = controls.target.y, tz = controls.target.z;
        const dx = camera.position.x - tx;
        const dy = camera.position.y - ty;
        const dz = camera.position.z - tz;
        const r   = Math.sqrt(dx * dx + dy * dy + dz * dz);
        const phi = Math.atan2(Math.sqrt(dx * dx + dz * dz), dy); // current polar angle
        const diff = Math.PI / 2 - phi;                            // distance from equator

        if (Math.abs(diff) < 0.002) { controls.update(); return; }

        const newPhi   = phi + diff * 0.08;          // ease toward equator
        const theta    = Math.atan2(dz, dx);
        const sinPhi   = Math.sin(newPhi);
        const cosPhi   = Math.cos(newPhi);
        camera.position.set(
          tx + r * sinPhi * Math.cos(theta),
          ty + r * cosPhi,
          tz + r * sinPhi * Math.sin(theta),
        );
        controls.update();
        snapAnimRef.current = requestAnimationFrame(tick);
      };

      snapAnimRef.current = requestAnimationFrame(tick);
    };

    // Cancel snap if user grabs the globe again
    const cancelSnap = () => {
      if (snapAnimRef.current) cancelAnimationFrame(snapAnimRef.current);
    };

    controls.addEventListener('end',   snapToEquator);
    controls.addEventListener('start', cancelSnap);
    return () => {
      controls.removeEventListener('end',   snapToEquator);
      controls.removeEventListener('start', cancelSnap);
      if (snapAnimRef.current) cancelAnimationFrame(snapAnimRef.current);
    };
  }, []);

  // Build/update path data from snapshot
  useEffect(() => {
    const platforms = snapshot?.platforms ?? [];
    const stepCount = snapshot?.step_count ?? 0;

    if (!platforms.length) { pathStoreRef.current = []; setPathData([]); return; }

    if (stepCount === 0) {
      // Fresh reset — build all paths from scratch
      const next = [];
      for (const p of platforms) {
        const alt   = 0.11 + Math.min(p.altitude_km / 8000, 0.1);
        const color = platformColor(p.last_action);

        // Full orbit ring
        const orbitPts = (p.route ?? []).map(n => ({ lat: n.latitude, lng: n.longitude, alt }));
        if (orbitPts.length > 1)
          next.push({ id: `orbit-${p.id}`, color, points: orbitPts });

        // Moving trail
        next.push({ id: `trail-${p.id}`, color,
          points: [{ lat: p.latitude, lng: p.longitude, alt }] });

        // Collapsed delivery arc (pre-create so it never pops in)
        next.push({ id: `deliver-${p.id}`, color: "#7cf7c9",
          points: [{ lat: p.latitude, lng: p.longitude, alt },
                   { lat: p.latitude, lng: p.longitude, alt: 0.01 }],
          active: false });
      }
      pathStoreRef.current = next;
    } else {
      const pathMap = new Map(pathStoreRef.current.map(p => [p.id, p]));

      for (const p of platforms) {
        const alt   = 0.11 + Math.min(p.altitude_km / 8000, 0.1);
        const color = platformColor(p.last_action);
        const pt    = { lat: p.latitude, lng: p.longitude, alt };

        // Update orbit ring colour
        const orbit = pathMap.get(`orbit-${p.id}`);
        if (orbit) orbit.color = color;

        // Extend trail
        const trail = pathMap.get(`trail-${p.id}`);
        if (trail) {
          trail.color = color;
          const last  = trail.points[trail.points.length - 1];
          const moved = !last ||
            Math.abs(last.lat - pt.lat) > 0.0001 ||
            Math.abs(last.lng - pt.lng) > 0.0001;
          if (moved) {
            trail.points.push(pt);
            if (trail.points.length > 120) trail.points.shift();
          }
        }

        // Delivery arc — show when action is "deliver"
        const arc = pathMap.get(`deliver-${p.id}`);
        if (arc) {
          if (p.last_action === "deliver") {
            // Point to a notional ground station below
            arc.points = [{ lat: p.latitude, lng: p.longitude, alt },
                          { lat: 0, lng: p.longitude, alt: 0.01 }];
            arc.color  = "#7cf7c9";
            arc.active = true;
          } else if (arc.active) {
            const start = arc.points[0] ?? pt;
            arc.points  = [start, { ...start, alt: start.alt - 0.001 }];
            arc.active  = false;
          }
        }
      }

      pathStoreRef.current = [...pathMap.values()];
    }

    setPathData([...pathStoreRef.current]);
  }, [snapshot]);

  // HTML marker nodes for platforms
  const markerNodes = useMemo(() => {
    return (snapshot?.platforms ?? []).map(p => ({
      ...p,
      lat:      p.latitude,
      lng:      p.longitude,
      altitude: 0.1 + Math.min(p.altitude_km / 8000, 0.1),
      color:    platformColor(p.last_action),
      size:     0.44,
    }));
  }, [snapshot]);

  return (
    <div className="globe-shell">
      <div className="globe-backdrop" />
      <div className="globe-frame">
        <Globe
          ref={globeRef}
          width={globeSize}
          height={globeSize}
          backgroundColor="rgba(4,11,20,0)"
          backgroundImageUrl={STARFIELD}
          globeImageUrl={EARTH_TEXTURE}
          bumpImageUrl={EARTH_BUMP}
          showAtmosphere
          atmosphereColor="#7ec8ff"
          atmosphereAltitude={0.18}
          animateIn={false}
          waitForGlobeReady={false}
          pathsData={pathData}
          pathPoints="points"
          pathPointLat="lat"
          pathPointLng="lng"
          pathPointAlt="alt"
          pathColor="color"
          pathTransitionDuration={STEP_INTERVAL_MS * 0.8}
          pathStroke={path => {
            const id = String(path.id);
            if (id.startsWith("orbit-"))   return 0.6;
            if (id.startsWith("trail-"))   return 1.5;
            return 1.2;
          }}
          pathDashLength={path => {
            const id = String(path.id);
            return (id.startsWith("orbit-") || id.startsWith("trail-")) ? 0 : 0.05;
          }}
          pathDashGap={path => {
            const id = String(path.id);
            return (id.startsWith("orbit-") || id.startsWith("trail-")) ? 0 : 0.1;
          }}
          pathDashAnimateTime={path => {
            const id = String(path.id);
            return (id.startsWith("deliver-") && path.active) ? 1600 : 0;
          }}
          htmlElementsData={markerNodes}
          htmlLat="lat"
          htmlLng="lng"
          htmlAltitude="altitude"
          htmlElement={p => {
            const el = document.createElement("div");
            el.className = "globe-marker platform";
            el.style.setProperty("--marker-color", p.color);
            el.style.setProperty("--marker-size", `${p.size}rem`);
            el.innerHTML = `
              <span></span>
              <div class="marker-tip">
                <div class="tip-title">Platform ${p.id}</div>
                <div class="tip-row"><span>Action</span>
                  <strong class="tip-action ${p.last_action ?? 'idle'}">${p.last_action ?? "idle"}</strong></div>
                <div class="tip-row"><span>Energy</span><strong>${p.energy?.toFixed(0) ?? "?"}%</strong></div>
                <div class="tip-row"><span>Materials</span><strong>${p.material_stock?.toFixed(0) ?? "?"}</strong></div>
                <div class="tip-row"><span>Components</span><strong>${p.component_stock?.toFixed(0) ?? "?"}</strong></div>
                <div class="tip-row"><span>Products</span><strong>${p.product_stock ?? 0}</strong></div>
                <div class="tip-row"><span>Alt</span><strong>${p.altitude_km?.toFixed(0) ?? "?"}km</strong></div>
              </div>`;
            return el;
          }}
        />
      </div>

      <div className="globe-overlay">
        <div>
          <p className="eyebrow">Orbital Manufacturing Console</p>
          <h1>Live platform tracking</h1>
        </div>
        <div className="overlay-metrics">
          <div>
            <span>Platforms</span>
            <strong>{snapshot?.platforms?.length ?? 0}</strong>
          </div>
          <div>
            <span>Delivering</span>
            <strong>
              {snapshot?.platforms?.filter(p => p.last_action === "deliver").length ?? 0}
            </strong>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── agent stats ─────────────────────────────────────────────────────────────
function AgentStats({ snapshot }) {
  const metrics    = snapshot?.metrics ?? {};
  const history    = snapshot?.reward_history ?? [];
  const score      = snapshot?.mission_score ?? 0;
  const step       = snapshot?.step_count ?? 0;
  const maxStep    = snapshot?.max_steps ?? 1;
  const pct        = Math.min(100, Math.round((step / maxStep) * 100));
  const lastReward = history.length ? history[history.length - 1] : 0;
  const avgReward  = history.length
    ? (history.reduce((a, b) => a + b, 0) / history.length).toFixed(2)
    : "0.00";
  const posSteps   = history.filter(r => r > 0).length;
  const efficiency = history.length ? Math.round((posSteps / history.length) * 100) : 0;

  return (
    <div className="card agent-card">
      <div className="card-head">
        <div><p className="eyebrow">RL Agent</p><h3>Performance</h3></div>
        <Gauge size={15} className="icon-muted" />
      </div>

      <div className="score-row">
        <div className="score-arc">
          <svg viewBox="0 0 60 38" width="90" height="56">
            <path d="M 5 35 A 25 25 0 0 1 55 35" fill="none"
              stroke="rgba(100,140,200,0.15)" strokeWidth="5" strokeLinecap="round" />
            <path d="M 5 35 A 25 25 0 0 1 55 35" fill="none"
              stroke={score > 0.7 ? "#7cf7c9" : score > 0.4 ? "#ffb86b" : "#ff8f8f"}
              strokeWidth="5" strokeLinecap="round"
              strokeDasharray={`${score * 78.5} 78.5`} />
            <text x="30" y="34" textAnchor="middle" fill="#e8f4ff" fontSize="10" fontWeight="700">
              {Math.round(score * 100)}%
            </text>
          </svg>
          <span className="score-label">Mission Score</span>
        </div>
        <div className="agent-kpis">
          <div className="kpi">
            <span>Avg reward/step</span>
            <strong className={Number(avgReward) >= 0 ? "pos" : "neg"}>
              {Number(avgReward) >= 0 ? "+" : ""}{avgReward}
            </strong>
          </div>
          <div className="kpi"><span>Positive steps</span><strong>{efficiency}%</strong></div>
          <div className="kpi">
            <span>Last step</span>
            <strong className={lastReward >= 0 ? "pos" : "neg"}>
              {lastReward >= 0 ? "+" : ""}{lastReward.toFixed(2)}
            </strong>
          </div>
        </div>
      </div>

      <div className="spark-wrap">
        <span className="spark-label">Step rewards</span>
        <RewardSparkline history={history} />
      </div>

      <div className="ep-progress">
        <div className="ep-head">
          <span>Episode {step}/{maxStep}</span>
          <span>{pct}% complete</span>
        </div>
        <div className="ep-bar"><div className="ep-fill" style={{ width: `${pct}%` }} /></div>
      </div>

      <div className="agent-pills">
        <span className="ap">Produced: {metrics.production_runs ?? 0}</span>
        <span className="ap">Assembled: {metrics.assemblies_completed ?? 0}</span>
        <span className="ap">Delivered: {metrics.deliveries_completed ?? 0}</span>
        <span className="ap">On-time: {metrics.on_time_deliveries ?? 0}</span>
        <span className="ap warn">Invalid: {metrics.invalid_actions ?? 0}</span>
      </div>
    </div>
  );
}

// ─── platform fleet ──────────────────────────────────────────────────────────
function PlatformFleet({ snapshot }) {
  const platforms = snapshot?.platforms ?? [];
  return (
    <div className="card fleet-card">
      <div className="card-head">
        <div><p className="eyebrow">Fleet</p><h3>Platforms</h3></div>
        <Factory size={15} className="icon-muted" />
      </div>
      <div className="sat-list">
        <AnimatePresence>
          {platforms.map(p => (
            <motion.div key={p.id} className="sat-row" layout>
              <div className="sat-head">
                <span className="sat-name">Platform {p.id}</span>
                <span className={`act-badge ${p.last_action ?? "idle"}`}>
                  {p.last_action ?? "idle"}
                </span>
              </div>
              <div className="bar-row">
                <Zap size={10} className="bar-icon" />
                <div className="bar-track">
                  <div className="bar-fill battery"
                    style={{ width: `${p.energy}%`, "--bar-color": energyColor(p.energy) }} />
                </div>
                <span className="bar-val">{p.energy.toFixed(0)}%</span>
              </div>
              <div className="bar-row">
                <Wrench size={10} className="bar-icon" />
                <div className="bar-track">
                  <div className="bar-fill mat" style={{ width: `${p.material_stock}%` }} />
                </div>
                <span className="bar-val">{p.material_stock.toFixed(0)}</span>
              </div>
              <div className="bar-row">
                <Activity size={10} className="bar-icon" />
                <div className="bar-track">
                  <div className="bar-fill comp" style={{ width: `${p.component_stock}%` }} />
                </div>
                <span className="bar-val">{p.component_stock.toFixed(0)}</span>
              </div>
              <div className="bar-row">
                <Package size={10} className="bar-icon" />
                <div className="bar-track">
                  <div className="bar-fill prod"
                    style={{ width: `${(p.product_stock / 10) * 100}%` }} />
                </div>
                <span className="bar-val">{p.product_stock}</span>
              </div>
            </motion.div>
          ))}
        </AnimatePresence>
      </div>
    </div>
  );
}

// ─── delivery orders ─────────────────────────────────────────────────────────
function DeliveryOrders({ snapshot }) {
  const windows = snapshot?.delivery_windows ?? [];
  const orders  = snapshot?.pending_orders ?? [];
  const step    = snapshot?.step_count ?? 0;

  return (
    <div className="card mission-card">
      <div className="card-head">
        <div><p className="eyebrow">Logistics</p><h3>Delivery Orders</h3></div>
        <Truck size={16} className="icon-muted" />
      </div>
      <div className="task-list">
        {windows.slice(0, 8).map(w => {
          const urgency  = w.deadline - step;
          const isUrgent = urgency <= 10;
          return (
            <div key={w.order_id} className="task-row">
              <div className="task-icon">
                <Circle size={13} className="icon-pending" />
              </div>
              <div className="task-body">
                <span className="task-id">Order #{w.order_id} — {w.product_type}</span>
                <span className="task-desc">
                  Deadline: step {w.deadline} ({urgency > 0 ? `${urgency} left` : "overdue"})
                </span>
              </div>
              <span className={`prio-badge ${isUrgent ? "prio-3" : urgency <= 25 ? "prio-2" : "prio-1"}`}>
                {isUrgent ? "URGENT" : `${urgency}s`}
              </span>
            </div>
          );
        })}
        {windows.length === 0 && (
          <p className="empty-text">
            <CheckCircle2 size={14} style={{ display: "inline", marginRight: 5 }} />
            All deliveries complete
          </p>
        )}
      </div>
      <div className="task-summary">
        <span><CheckCircle2 size={11} /> {(snapshot?.metrics?.deliveries_completed ?? 0)} delivered</span>
        <span><Package size={11} /> {orders.length} pending orders</span>
      </div>
    </div>
  );
}

// ─── solar conditions ─────────────────────────────────────────────────────────
function SolarConditions({ snapshot }) {
  const solar = snapshot?.solar_conditions ?? {};
  return (
    <div className="card">
      <div className="card-head">
        <div><p className="eyebrow">Power</p><h3>Solar Conditions</h3></div>
        <Sun size={15} className="icon-muted" />
      </div>
      <div className="weather-row">
        {Object.entries(solar).map(([zone, irr]) => (
          <div key={zone} className="weather-pill"
            style={{ "--cloud-pct": `${Math.round(Number(irr) * 100)}%` }}>
            <span className="wregion">{zone.replace(/_/g, " ")}</span>
            <span className="wval">{Math.round(Number(irr) * 100)}%</span>
            <div className="wbar"><div className="wfill solar" /></div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ─── main app ─────────────────────────────────────────────────────────────────
export default function App() {
  const { snapshot, loading, playing, taskName, error, setPlaying, resetDemo, stepDemo } =
    useDemoData();
  const [globeSize, setGlobeSize] = useState(540);
  const panelRef = useRef(null);

  useEffect(() => {
    function resize() {
      if (!panelRef.current) return;
      const { width, height } = panelRef.current.getBoundingClientRect();
      setGlobeSize(Math.floor(Math.min(width, height, 620)));
    }
    resize();
    window.addEventListener("resize", resize);
    return () => window.removeEventListener("resize", resize);
  }, []);

  const score      = snapshot?.mission_score ?? 0;
  const scoreStr   = `${Math.round(score * 100)}%`;
  const scoreClass = score > 0.7 ? "good" : score > 0.4 ? "warn" : "bad";

  return (
    <div className="app-shell">
      <div className="ambient ambient-a" />
      <div className="ambient ambient-b" />

      {/* ── header ── */}
      <header className="topbar">
        <div className="brand">
          <div className="brand-mark"><Factory size={16} /></div>
          <div>
            <p className="eyebrow">OpenEnv · RL Benchmark</p>
            <h2>Space Manufacturing Control</h2>
          </div>
        </div>
        <div className="task-switcher">
          {TASKS.map(t => (
            <button key={t} type="button"
              className={t === taskName ? "task-pill active" : "task-pill"}
              onClick={() => resetDemo(t)}>
              {t}
            </button>
          ))}
        </div>
        <div className="header-right">
          <div className={`score-badge ${scoreClass}`}>
            <span>Mission</span>
            <strong>{scoreStr}</strong>
          </div>
          <div className="header-controls">
            <button type="button" className="action-button primary sm"
              onClick={() => setPlaying(!playing)}>
              {snapshot?.done ? "Done" : playing ? "Pause" : "Play"}
            </button>
            <button type="button" className="action-button sm" onClick={stepDemo}
              disabled={loading || snapshot?.done ||
                (snapshot?.step_count ?? 0) >= (snapshot?.max_steps ?? 0)}>
              Step
            </button>
            <button type="button" className="ghost-button sm" onClick={() => resetDemo(taskName)}>
              <RefreshCcw size={12} /> Reset
            </button>
          </div>
        </div>
      </header>

      {error && <div className="error-banner">{error}</div>}

      {/* ── main grid ── */}
      <main className="main-grid">
        {/* Globe panel */}
        <section className="col-globe" ref={panelRef}>
          {loading
            ? <div className="loading-state">Loading orbital telemetry…</div>
            : <GlobeView snapshot={snapshot} globeSize={globeSize} />}
        </section>

        {/* Middle column */}
        <section className="col-mid">
          <AgentStats snapshot={snapshot} />
          <DeliveryOrders snapshot={snapshot} />
          <SolarConditions snapshot={snapshot} />
        </section>

        {/* Right column */}
        <section className="col-right">
          <PlatformFleet snapshot={snapshot} />
        </section>
      </main>
    </div>
  );
}
