/* Site Intelligence — Digital Twin (Three.js panel grid) + overlays + right rail */

function TwinCanvas({ viewMode, overlays, selectedPanel, onSelect }) {
  const mountRef = useRef(null);
  const stateRef = useRef({});
  const applyRef = useRef(null);
  const propsRef = useRef({ viewMode, overlays, selectedPanel });
  propsRef.current = { viewMode, overlays, selectedPanel };

  useEffect(() => {
    const mount = mountRef.current;
    if (!mount || !window.THREE) return;
    const THREE = window.THREE;
    const w = mount.clientWidth, h = mount.clientHeight;

    const scene = new THREE.Scene();
    scene.background = new THREE.Color(0x0a0e1a);
    scene.fog = new THREE.Fog(0x0a0e1a, 30, 120);

    const camera = new THREE.PerspectiveCamera(38, w / h, 0.1, 500);
    camera.position.set(22, 22, 28);
    camera.lookAt(0, 0, 0);

    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false });
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    renderer.setSize(w, h);
    mount.innerHTML = "";
    mount.appendChild(renderer.domElement);

    // Ground
    const ground = new THREE.Mesh(
      new THREE.PlaneGeometry(80, 80),
      new THREE.MeshBasicMaterial({ color: 0x0f172a })
    );
    ground.rotation.x = -Math.PI / 2;
    ground.position.y = -0.02;
    scene.add(ground);

    // Subtle grid
    const grid = new THREE.GridHelper(80, 40, 0x1e293b, 0x18223a);
    grid.position.y = 0;
    scene.add(grid);

    // Panel grid: rows x cols
    const ROWS = 18, COLS = 28;
    const GAP = 0.12;
    const PW = 0.88, PH = 0.56;
    const group = new THREE.Group();
    const panelsMeta = [];
    const geom = new THREE.BoxGeometry(PW, 0.06, PH);

    // Deterministic PRNG so panel attributes are stable
    let seed = 7;
    const r = () => { seed = (seed * 16807) % 2147483647; return seed / 2147483647; };

    for (let z = 0; z < ROWS; z++) {
      for (let x = 0; x < COLS; x++) {
        const wx = (x - (COLS - 1) / 2) * (PW + GAP);
        const wz = (z - (ROWS - 1) / 2) * (PH + GAP);
        const mat = new THREE.MeshBasicMaterial({ color: 0x1e293b });
        const mesh = new THREE.Mesh(geom, mat);
        mesh.position.set(wx, 0.25, wz);
        mesh.rotation.x = -0.22; // tilt
        const meta = {
          id: `MOD-${String(z * COLS + x + 1).padStart(4, "0")}`,
          row: z, col: x,
          health: 0.6 + r() * 0.4,
          temp: 58 + r() * 22, // °C
          power: 290 + r() * 30, // W
          string: `INV-${String(1 + Math.floor(x / 8)).padStart(2,"0")}.CMB-${String(1 + Math.floor(z / 5)).padStart(2,"0")}.STR-${String(1 + (x % 8)).padStart(2,"0")}`,
          inverter: 1 + Math.floor(x / 8),
          anomaly: null,
        };
        panelsMeta.push({ mesh, meta });
        group.add(mesh);
      }
    }

    // Seed some anomalies
    const anomalies = [
      { row: 4, col: 6, kind: "hot_cell", sev: "critical" },
      { row: 5, col: 6, kind: "hot_cell", sev: "critical" },
      { row: 9, col: 14, kind: "activated_bypass", sev: "high" },
      { row: 10, col: 14, kind: "activated_bypass", sev: "high" },
      { row: 3, col: 22, kind: "tilt_fault", sev: "high" },
      { row: 4, col: 22, kind: "tilt_fault", sev: "high" },
      { row: 13, col: 3, kind: "offline_string", sev: "critical" },
      { row: 14, col: 3, kind: "offline_string", sev: "critical" },
      { row: 14, col: 4, kind: "offline_string", sev: "critical" },
      { row: 7, col: 20, kind: "soiling", sev: "medium" },
      { row: 8, col: 20, kind: "soiling", sev: "medium" },
      { row: 11, col: 9, kind: "vegetation", sev: "medium" },
      { row: 16, col: 25, kind: "warm_module", sev: "low" },
    ];
    anomalies.forEach(a => {
      const pm = panelsMeta.find(p => p.meta.row === a.row && p.meta.col === a.col);
      if (pm) { pm.meta.anomaly = a.kind; pm.meta.severity = a.sev;
               if (a.kind === "hot_cell") pm.meta.temp = 86.2;
               if (a.kind === "offline_string") { pm.meta.health = 0.08; pm.meta.power = 0; }
               if (a.kind === "activated_bypass") pm.meta.temp = 72.4;
      }
    });

    // Coverage-gap markers
    const gapCells = [
      { row: 1, col: 1, w: 3, h: 2 },
      { row: 15, col: 18, w: 4, h: 2 },
    ];

    // Gap overlays (red dashed rect)
    const gapGroup = new THREE.Group();
    gapCells.forEach(g => {
      const gw = g.w * (PW + GAP), gh = g.h * (PH + GAP);
      const cx = (g.col + g.w / 2 - 0.5 - (COLS - 1) / 2) * (PW + GAP);
      const cz = (g.row + g.h / 2 - 0.5 - (ROWS - 1) / 2) * (PH + GAP);
      const edgeGeom = new THREE.EdgesGeometry(new THREE.PlaneGeometry(gw, gh));
      const edge = new THREE.LineSegments(edgeGeom, new THREE.LineDashedMaterial({ color: 0xef4444, dashSize: 0.15, gapSize: 0.1 }));
      edge.computeLineDistances();
      edge.rotation.x = -Math.PI / 2;
      edge.position.set(cx, 0.3, cz);
      gapGroup.add(edge);

      const fillMat = new THREE.MeshBasicMaterial({ color: 0xef4444, transparent: true, opacity: 0.08 });
      const fill = new THREE.Mesh(new THREE.PlaneGeometry(gw, gh), fillMat);
      fill.rotation.x = -Math.PI / 2;
      fill.position.set(cx, 0.31, cz);
      gapGroup.add(fill);
    });
    scene.add(gapGroup);

    // HUMINT markers — little pins
    const humintGroup = new THREE.Group();
    const humintPos = [
      { row: 6, col: 10 }, { row: 12, col: 17 },
    ];
    humintPos.forEach(p => {
      const wx = (p.col - (COLS - 1) / 2) * (PW + GAP);
      const wz = (p.row - (ROWS - 1) / 2) * (PH + GAP);
      const pin = new THREE.Mesh(
        new THREE.ConeGeometry(0.18, 0.5, 12),
        new THREE.MeshBasicMaterial({ color: 0xd4910c })
      );
      pin.position.set(wx, 0.7, wz);
      pin.rotation.x = Math.PI;
      humintGroup.add(pin);
    });
    scene.add(humintGroup);

    // Satellite diff overlay
    const satGroup = new THREE.Group();
    const satRect = new THREE.Mesh(
      new THREE.PlaneGeometry(8, 6),
      new THREE.MeshBasicMaterial({ color: 0x8b5cf6, transparent: true, opacity: 0.18, side: THREE.DoubleSide })
    );
    satRect.rotation.x = -Math.PI / 2;
    satRect.position.set(-4, 0.05, 2);
    satGroup.add(satRect);
    scene.add(satGroup);

    scene.add(group);

    // Selection outline
    const outline = new THREE.Mesh(
      new THREE.BoxGeometry(PW + 0.08, 0.1, PH + 0.08),
      new THREE.MeshBasicMaterial({ color: 0x4a90d9, transparent: true, opacity: 0.35 })
    );
    outline.visible = false;
    scene.add(outline);

    // Picking
    const raycaster = new THREE.Raycaster();
    const mouse = new THREE.Vector2();
    const onClick = (ev) => {
      const rect = renderer.domElement.getBoundingClientRect();
      mouse.x = ((ev.clientX - rect.left) / rect.width) * 2 - 1;
      mouse.y = -((ev.clientY - rect.top) / rect.height) * 2 + 1;
      raycaster.setFromCamera(mouse, camera);
      const hits = raycaster.intersectObjects(group.children, false);
      if (hits.length) {
        const hit = hits[0].object;
        const pm = panelsMeta.find(p => p.mesh === hit);
        if (pm) { onSelect(pm.meta); }
      }
    };
    renderer.domElement.addEventListener("click", onClick);

    // Orbit (manual — no controls lib needed)
    let yaw = 0.7, pitch = 0.85, dist = 32;
    let dragging = false, lastX = 0, lastY = 0;
    const updateCam = () => {
      const r = dist * Math.cos(pitch);
      camera.position.x = r * Math.sin(yaw);
      camera.position.y = dist * Math.sin(pitch);
      camera.position.z = r * Math.cos(yaw);
      camera.lookAt(0, 0, 0);
    };
    updateCam();

    const onDown = (e) => { dragging = true; lastX = e.clientX; lastY = e.clientY; };
    const onMove = (e) => {
      if (!dragging) return;
      const dx = e.clientX - lastX, dy = e.clientY - lastY;
      yaw += dx * 0.01;
      pitch = Math.max(0.18, Math.min(1.4, pitch + dy * 0.01));
      lastX = e.clientX; lastY = e.clientY;
      updateCam();
    };
    const onUp = () => { dragging = false; };
    const onWheel = (e) => {
      e.preventDefault();
      dist = Math.max(14, Math.min(70, dist + e.deltaY * 0.04));
      updateCam();
    };
    renderer.domElement.addEventListener("mousedown", onDown);
    window.addEventListener("mousemove", onMove);
    window.addEventListener("mouseup", onUp);
    renderer.domElement.addEventListener("wheel", onWheel, { passive: false });

    // Resize
    const onResize = () => {
      const w = mount.clientWidth, h = mount.clientHeight;
      renderer.setSize(w, h);
      camera.aspect = w / h;
      camera.updateProjectionMatrix();
    };
    const ro = new ResizeObserver(onResize);
    ro.observe(mount);

    // Animate
    let raf;
    let running = true;
    const tick = () => {
      if (!running) return;
      renderer.render(scene, camera);
      raf = requestAnimationFrame(tick);
    };
    tick();
    // Fallback: if rAF throttled (e.g., page hidden), still re-render periodically
    const fallback = setInterval(() => { if (running) renderer.render(scene, camera); }, 250);

    stateRef.current = { panelsMeta, outline, group, gapGroup, humintGroup, satGroup, PW, PH, GAP, ROWS, COLS };

    // Define apply function bound to this mount's state
    const applyColors = () => {
      const { viewMode, overlays, selectedPanel } = propsRef.current;
      const sevColor = { critical: 0xef4444, high: 0xf97316, medium: 0xeab308, low: 0x22c55e };
      const INVERTER_COLORS = [0x3b82f6, 0x22d3ee, 0x8b5cf6, 0xeab308, 0x22c55e, 0xef4444, 0xf97316, 0x4a90d9];
      panelsMeta.forEach(({ mesh, meta }) => {
        let color = 0x1e293b;
        if (viewMode === "health") {
          if (meta.anomaly) color = sevColor[meta.severity] || 0x1e293b;
          else if (meta.health > 0.9) color = 0x16a34a;
          else if (meta.health > 0.75) color = 0x22c55e;
          else color = 0x84cc16;
        } else if (viewMode === "temperature") {
          const t = Math.min(1, Math.max(0, (meta.temp - 55) / 35));
          const r = Math.floor(0x3b + (0xef - 0x3b) * t);
          const g = Math.floor(0x82 + (0x44 - 0x82) * t);
          const b = Math.floor(0xf6 + (0x44 - 0xf6) * t);
          color = (r << 16) | (g << 8) | b;
        } else if (viewMode === "power") {
          const p = Math.min(1, Math.max(0, meta.power / 320));
          const g = Math.floor(40 + p * 210);
          color = (0x0a << 16) | (g << 8) | 0x24;
        } else if (viewMode === "string") {
          const i = (meta.row + Math.floor(meta.col / 8) * 3) % 8;
          color = INVERTER_COLORS[i];
        } else if (viewMode === "inverter") {
          color = INVERTER_COLORS[(meta.inverter - 1) % 8];
        }
        mesh.material.color.setHex(color);
        mesh.material.needsUpdate = true;
      });
      gapGroup.visible = overlays.coverage;
      humintGroup.visible = overlays.humint;
      satGroup.visible = overlays.sat;
      if (selectedPanel) {
        const pm = panelsMeta.find(p => p.meta.id === selectedPanel.id);
        if (pm) { outline.position.set(pm.mesh.position.x, 0.32, pm.mesh.position.z); outline.visible = true; }
      } else { outline.visible = false; }
    };
    applyRef.current = applyColors;
    applyColors();

    return () => {
      running = false;
      cancelAnimationFrame(raf);
      clearInterval(fallback);
      ro.disconnect();
      renderer.domElement.removeEventListener("click", onClick);
      renderer.domElement.removeEventListener("mousedown", onDown);
      window.removeEventListener("mousemove", onMove);
      window.removeEventListener("mouseup", onUp);
      renderer.domElement.removeEventListener("wheel", onWheel);
      renderer.dispose();
      mount.innerHTML = "";
    };
  }, []);

  // Apply view mode + overlays + selection on every prop change
  useEffect(() => {
    if (applyRef.current) applyRef.current();
  }, [viewMode, overlays, selectedPanel]);

  return <div ref={mountRef} style={{ width: "100%", height: "100%", minHeight: 420, background: "var(--bg-inset)", borderRadius: 10, overflow: "hidden" }} />;
}

function SitePage({ siteId, go, setActiveMic, openCompare, tab: tabProp, setTab: setTabProp, setWsStage }) {
  const site = SITES.find(s => s.id === siteId) || SITES[2];
  const [tabLocal, setTabLocal] = useState("twin");
  const tab = tabProp || tabLocal;
  const setTab = setTabProp || setTabLocal;
  const [viewMode, setViewMode] = useState("health");
  const [overlays, setOverlays] = useState({ coverage: true, humint: true, sat: false });
  const [selectedPanel, setSelectedPanel] = useState(null);

  return (
    <div className="page">
      <div className="page-head">
        <div className="title">
          <div className="kicker">Site intelligence · the site is alive between inspections</div>
          <h1>{site.name}</h1>
          <div className="sub">
            <span className="mono">{site.id.toUpperCase()}</span> · {site.region} · {site.capacity_mw.toFixed(1)} MWp · {site.panels.toLocaleString()} modules{window.siteProfile && (() => { const pr = window.siteProfile(site); return <> · {pr.mount} · {pr.area.toFixed(1)} ha · {pr.zones.length} zones · {pr.cadence.toLowerCase()} cadence</>; })()}
          </div>
        </div>
        <div className="actions">
          <button className="btn btn-secondary" onClick={() => go("siteconfig")}><Icon name="settings" size={12}/>Edit site</button>
          <div className="row" style={{ gap: 8 }}>
            <div className="col" style={{ alignItems: "flex-end", gap: 0 }}>
              <span className="caps">Last inspection</span>
              <span className="mono" style={{ fontSize: 12 }}>{site.lastInspection}</span>
            </div>
            <div className="col" style={{ alignItems: "flex-end", gap: 0 }}>
              <span className="caps">Next</span>
              <span className="mono" style={{ fontSize: 12, color: "var(--accent-mission)" }}>{site.nextInspection}</span>
            </div>
          </div>
          <button className="btn btn-secondary"><Icon name="file" />Latest report</button>
          <button className="btn btn-primary" onClick={() => window.dispatchEvent(new CustomEvent("skyops:new-insp",{detail:{siteId: site.id}}))}><Icon name="plus" />New inspection</button>
        </div>
      </div>

      <div className="tabs" style={{ marginBottom: 16 }}>
        {[
          ["overview","Overview"], ["twin","Twin"], ["inspections","Inspections"],
          ["compare","Compare cycles"], ["calendar","Calendar"], ["workorders","Work orders"], ["trends","Trends"], ["team","Team"],
        ].map(([v,l]) => (
          <button key={v} className={tab===v?"on":""} onClick={()=>setTab(v)}>{l}</button>
        ))}
      </div>

      <div className="grid-4" style={{ marginBottom: 16 }}>
        <div className="card stat">
          <span className="lbl">Site health</span>
          <div style={{ display:"flex", alignItems:"center", gap: 12 }}>
            <Ring pct={site.health} />
            <div>
              <div className="val num" style={{ fontSize: 20 }}>{site.health}<span className="unit">/100</span></div>
              <div className="sub"><span className="trend-dn">▼ 2.4</span> last 30d</div>
            </div>
          </div>
        </div>
        <div className="card stat">
          <span className="lbl">Open detections</span>
          <span className="val num">{site.criticals + site.warnings}</span>
          <div style={{ display: "flex", gap: 6, marginTop: 4 }}>
            <Pill tone="crit"><span className="dot"/>{site.criticals} critical</Pill>
            <Pill tone="warn"><span className="dot"/>{site.warnings} other</Pill>
          </div>
        </div>
        <div className="card stat">
          <span className="lbl">Coverage (last)</span>
          <span className="val num">{site.coverage}<span className="unit">%</span></span>
          <span className="sub">7.6% gap flagged for re-fly</span>
        </div>
        <div className="card stat">
          <span className="lbl">Conditions now</span>
          <div style={{ display: "flex", gap: 12, alignItems: "baseline", marginTop: 2 }}>
            <span className="num" style={{ fontSize: 18, fontWeight: 600 }}>{site.ambient.toFixed(1)}°C</span>
            <span className="num sec" style={{ fontSize: 12 }}>{site.irradiance} W/m²</span>
            <span className="num sec" style={{ fontSize: 12 }}><Icon name="wind" size={11}/> {site.wind} km/h</span>
          </div>
          <span className="sub">Above flight-window threshold</span>
        </div>
      </div>

      {tab === "twin" && (
        <div className="grid-3" style={{ gridTemplateColumns: "1fr 340px", gap: 16 }}>
          <div className="card" style={{ padding: 0 }}>
            <div className="card-hd" style={{ borderBottom: "1px solid var(--border-base)" }}>
              Digital twin
              <span className="sub">sample block · 504 of {site.panels.toLocaleString()} modules · orbit to navigate · click any panel</span>
              <div className="actions">
                <div className="seg">
                  {[
                    ["health","Health"], ["temperature","Temp"], ["power","Power"],
                    ["string","String"], ["inverter","Inverter"],
                  ].map(([v,l]) => (
                    <button key={v} className={viewMode===v?"on":""} onClick={()=>setViewMode(v)}>{l}</button>
                  ))}
                </div>
              </div>
            </div>
            <div style={{ position: "relative", height: 500 }}>
              <TwinCanvas viewMode={viewMode} overlays={overlays} selectedPanel={selectedPanel} onSelect={setSelectedPanel} />
              <div style={{ position: "absolute", left: 12, bottom: 12, display: "flex", flexDirection: "column", gap: 6 }}>
                {[
                  ["coverage","Coverage gaps","var(--sev-critical)"],
                  ["humint","HUMINT markers","var(--accent-mission)"],
                  ["sat","Satellite diff","#8b5cf6"],
                ].map(([k,l,c]) => (
                  <label key={k} style={{ display:"flex", alignItems:"center", gap:8, padding:"5px 10px", background:"rgba(15,23,42,0.92)", border:"1px solid var(--border-elevated)", borderRadius:6, fontSize:11, cursor:"pointer", backdropFilter:"blur(4px)" }}>
                    <input type="checkbox" checked={overlays[k]} onChange={e => setOverlays({...overlays, [k]: e.target.checked})}/>
                    <span style={{ width:8, height:8, borderRadius:2, background:c }}/>
                    {l}
                  </label>
                ))}
              </div>
              <div style={{ position: "absolute", right: 12, top: 12, display: "flex", flexDirection: "column", gap: 4, background: "rgba(15,23,42,0.92)", border: "1px solid var(--border-elevated)", borderRadius: 8, padding: 10, fontSize: 10, minWidth: 140, backdropFilter: "blur(4px)" }}>
                <div className="caps">Legend · {viewMode}</div>
                {viewMode === "health" && (
                  <>
                    <div style={{ display:"flex",alignItems:"center", gap:6 }}><span style={{ width:10,height:10,background:"#16a34a", borderRadius:2}}/>Healthy</div>
                    <div style={{ display:"flex",alignItems:"center", gap:6 }}><span style={{ width:10,height:10,background:"#eab308", borderRadius:2}}/>Medium</div>
                    <div style={{ display:"flex",alignItems:"center", gap:6 }}><span style={{ width:10,height:10,background:"#f97316", borderRadius:2}}/>High</div>
                    <div style={{ display:"flex",alignItems:"center", gap:6 }}><span style={{ width:10,height:10,background:"#ef4444", borderRadius:2}}/>Critical</div>
                  </>
                )}
                {viewMode === "temperature" && (
                  <>
                    <div style={{height:8,background:"linear-gradient(90deg,#3b82f6,#22d3ee,#eab308,#ef4444)", borderRadius:2}}/>
                    <div className="row" style={{ justifyContent:"space-between", color:"var(--fg-muted)" }}><span>55 °C</span><span>90 °C</span></div>
                  </>
                )}
              </div>
            </div>
          </div>

          <aside className="card" style={{ padding: 0, height: "fit-content" }}>
            <div className="card-hd">Inspector</div>
            {selectedPanel ? (
              <div style={{ padding: 14 }}>
                <div className="caps">Panel</div>
                <div style={{ fontFamily: "var(--font-mono)", fontSize: 13, fontWeight: 600, marginBottom: 2 }}>{selectedPanel.id}</div>
                <div className="sec mono" style={{ fontSize: 11, marginBottom: 12 }}>{selectedPanel.string}</div>

                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10, marginBottom: 12 }}>
                  <div>
                    <div className="caps">Temp</div>
                    <div className="num" style={{ fontSize: 16, fontWeight: 600, color: selectedPanel.temp > 75 ? "var(--sev-critical)" : "var(--fg-primary)" }}>{selectedPanel.temp.toFixed(2)} °C</div>
                  </div>
                  <div>
                    <div className="caps">Power</div>
                    <div className="num" style={{ fontSize: 16, fontWeight: 600 }}>{Math.round(selectedPanel.power)} W</div>
                  </div>
                  <div>
                    <div className="caps">Health</div>
                    <div className="num" style={{ fontSize: 16, fontWeight: 600 }}>{Math.round(selectedPanel.health * 100)}</div>
                  </div>
                  <div>
                    <div className="caps">Inverter</div>
                    <div className="num" style={{ fontSize: 16, fontWeight: 600 }}>{selectedPanel.inverter}</div>
                  </div>
                </div>

                {selectedPanel.anomaly ? (
                  <div style={{ borderTop: "1px solid var(--border-base)", paddingTop: 12 }}>
                    <div className="caps" style={{ marginBottom: 6 }}>Active observation</div>
                    <div className="row" style={{ gap: 6, marginBottom: 8, flexWrap: "wrap" }}>
                      <Sev level={selectedPanel.severity} />
                      <Tstat v="NEW" />
                      <Src v="INSPECTION_SYSTEM" />
                    </div>
                    <div style={{ fontSize: 12, marginBottom: 10 }}>{ANOMALY_CLASS[selectedPanel.anomaly]?.label}</div>
                    <div className="row" style={{ gap: 6 }}>
                      <button className="btn btn-info btn-xs" onClick={() => go("review")}>Open in review</button>
                      <button className="btn btn-secondary btn-xs">Timeline</button>
                    </div>
                  </div>
                ) : (
                  <div style={{ borderTop: "1px solid var(--border-base)", paddingTop: 12, fontSize: 11, color: "var(--fg-muted)" }}>
                    No active observations on this panel.
                  </div>
                )}
              </div>
            ) : (
              <div style={{ padding: 14, fontSize: 12, color: "var(--fg-muted)" }}>
                Select a panel to inspect. Use the view-mode switcher to recolor by health, temperature, power, string, or inverter.
              </div>
            )}

            <div style={{ borderTop: "1px solid var(--border-base)", padding: 14 }}>
              <div className="caps" style={{ marginBottom: 8 }}>Channels · alive between inspections</div>
              <div className="col" style={{ gap: 8 }}>
                <div className="row" style={{ fontSize: 11 }}><Icon name="radio" size={12} style={{color:"var(--health-ok)"}}/><span>SCADA</span><span className="grow"/><span className="mono muted">32 s ago</span></div>
                <div className="row" style={{ fontSize: 11 }}><Icon name="cloud" size={12} style={{color:"var(--accent-primary)"}}/><span>Weather API</span><span className="grow"/><span className="mono muted">4 min ago</span></div>
                <div className="row" style={{ fontSize: 11 }}><Icon name="satellite" size={12} style={{color:"#8b5cf6"}}/><span>Sentinel-2 diff</span><span className="grow"/><span className="mono muted">2d ago</span></div>
                <div className="row" style={{ fontSize: 11 }}><Icon name="flag" size={12} style={{color:"var(--accent-mission)"}}/><span>Field reports</span><span className="grow"/><span className="mono muted">1h ago</span></div>
              </div>
            </div>
          </aside>
        </div>
      )}

      {tab === "inspections" && (
        <InspectionsList siteId={site.id} go={go} setActiveMic={setActiveMic} openCompare={openCompare}/>
      )}

      {tab === "workorders" && (
        <WorkOrdersPage go={go} setActiveSite={() => {}} setActiveMic={setActiveMic} setWsStage={setWsStage || (() => {})} siteFilter={site.id}/>
      )}

      {tab === "calendar" && (
        <SiteCalendar site={site} go={go} setActiveMic={setActiveMic}/>
      )}

      {tab === "compare" && <div style={{ margin: "0 -24px" }}><TemporalIntel siteId={site.id} go={go}/></div>}

      {tab === "trends" && window.SiteTrendsTab && <SiteTrendsTab site={site}/>}
      {tab === "team" && <window.SiteTeamTab site={site} go={go}/>}
      {tab === "overview" && <window.SiteOverviewTab site={site} go={go} setTab={setTab} setActiveMic={setActiveMic}/>}

      {!["twin", "inspections", "calendar", "workorders", "compare", "trends", "team", "overview"].includes(tab) && (
        <div className="card" style={{ padding: 48, textAlign: "center", color: "var(--fg-muted)" }}>
          <Icon name={tab === "reports" ? "file" : tab === "alerts" ? "alert" : tab === "timeline" ? "activity" : "layers"} size={28} />
          <div style={{ marginTop: 12, fontSize: 14, fontWeight: 500, color: "var(--fg-secondary)" }}>
            {tab.charAt(0).toUpperCase() + tab.slice(1)} view
          </div>
          <div style={{ marginTop: 6, fontSize: 12 }}>Switch to the Digital twin tab to explore the interactive site model.</div>
        </div>
      )}
    </div>
  );
}

window.SitePage = SitePage;
