/* global React */
/* ============================================================
   OrchardCrossSection — animated SVG hero for Optimize page.
   A single horizontal cross-section showing the four layers
   Revolute works with: satellite/sky → canopy → fruit → soil.
   Subtle continuous animation; no scroll dependency.
   ============================================================ */

(function () {
  const { useEffect, useState, useRef } = React;

  // Stable noise-ish helper (deterministic)
  function pseudo(i, salt = 1) {
    const s = Math.sin(i * 12.9898 + salt * 78.233) * 43758.5453;
    return s - Math.floor(s);
  }

  // 5 trees, evenly spaced
  const TREE_COUNT = 5;
  const TREE_SPACING = 1000 / (TREE_COUNT + 1);

  // EC zone palette (matches site)
  const EC_LOW   = '#D9C28A'; // sandy / low EC
  const EC_MID   = '#A89060';
  const EC_HIGH  = '#5C4A28'; // clay / high EC

  // NDVI palette
  const NDVI_LOW  = '#C8B26A';
  const NDVI_MID  = '#8FB04A';
  const NDVI_HIGH = '#3F6B25';

  window.OrchardCrossSection = function OrchardCrossSection() {
    const [t, setT] = useState(0);
    const reduced = useRef(false);
    const raf = useRef(0);
    const start = useRef(performance.now());

    useEffect(() => {
      try {
        reduced.current = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
      } catch (e) { reduced.current = false; }

      if (reduced.current) {
        setT(0.35); // freeze at a representative frame
        return;
      }

      const tick = () => {
        const elapsed = (performance.now() - start.current) / 1000;
        // 16-second loop
        setT((elapsed % 16) / 16);
        raf.current = requestAnimationFrame(tick);
      };
      raf.current = requestAnimationFrame(tick);
      return () => cancelAnimationFrame(raf.current);
    }, []);

    // EMI rig sweeps left → right over 16s
    const rigX = 60 + t * 880;
    // Satellite arcs across higher up over 16s, slightly slower visually
    const satT = (t * 1.0) % 1;
    const satX = 80 + satT * 840;
    const satY = 38 - Math.sin(satT * Math.PI) * 22;

    // Per-tree canopy "breath" (pulse) and fruit-size cycle
    const trees = Array.from({ length: TREE_COUNT }, (_, i) => {
      const baseX = TREE_SPACING * (i + 1);
      const phase = (t + i / TREE_COUNT) % 1;
      const breath = 0.94 + Math.sin(phase * Math.PI * 2) * 0.04;
      const ndviVal = 0.45 + pseudo(i, 7) * 0.5; // 0..1
      const fruitSize = 60 + pseudo(i, 19) * 14; // mm visual only
      // Highlight tree if EMI rig is currently overhead
      const dist = Math.abs(rigX - baseX);
      const lit = Math.max(0, 1 - dist / 120);
      return { baseX, breath, ndviVal, fruitSize, lit };
    });

    // Soil EC tiles — 3 depth bands × N columns. Stable per render.
    const cols = 40;
    const colWidth = 1000 / cols;
    const soilBands = [
      { y: 250, h: 28, label: '25 cm' },
      { y: 278, h: 36, label: '50 cm' },
      { y: 314, h: 56, label: '90 cm' },
    ];

    // Probe location (between trees 3 and 4)
    const probeX = TREE_SPACING * 3 + TREE_SPACING / 2;

    // Active label cycle (cycle through 4 callouts)
    const labelIdx = Math.floor(t * 4) % 4;

    // Helper for fruit size readout (changes once per ~4s)
    const fruitTreeIdx = Math.floor(t * 3) % TREE_COUNT;
    const fruitTree = trees[fruitTreeIdx];
    const fruitSizeDisplay = (62 + pseudo(fruitTreeIdx, 31) * 12).toFixed(1);

    return (
      <div className="ocs-wrap">
        <svg
          className="ocs-svg"
          viewBox="0 0 1000 380"
          preserveAspectRatio="xMidYMid slice"
          role="img"
          aria-label="Animated orchard cross-section showing the four data layers Revolute works with — satellite, canopy, fruit, and soil."
        >
          <defs>
            {/* Sky gradient */}
            <linearGradient id="ocs-sky" x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%"   stopColor="#0A1408" />
              <stop offset="100%" stopColor="#1B2918" />
            </linearGradient>
            {/* Soil gradient layered on top of EC tiles for atmosphere */}
            <linearGradient id="ocs-soil-vignette" x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%"   stopColor="rgba(0,0,0,0)" />
              <stop offset="100%" stopColor="rgba(0,0,0,0.45)" />
            </linearGradient>
            {/* Satellite cone */}
            <linearGradient id="ocs-cone" x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%" stopColor="rgba(184,220,115,0.55)" />
              <stop offset="100%" stopColor="rgba(184,220,115,0)" />
            </linearGradient>
            {/* EMI ping */}
            <radialGradient id="ocs-ping" cx="0.5" cy="0" r="1">
              <stop offset="0%" stopColor="rgba(184,220,115,0.55)" />
              <stop offset="100%" stopColor="rgba(184,220,115,0)" />
            </radialGradient>
            {/* Tree leaf cluster gradient */}
            <radialGradient id="ocs-canopy" cx="0.5" cy="0.4" r="0.7">
              <stop offset="0%" stopColor="#9BC44E" />
              <stop offset="60%" stopColor="#5F8A2C" />
              <stop offset="100%" stopColor="#2F4717" />
            </radialGradient>
          </defs>

          {/* SKY */}
          <rect x="0" y="0" width="1000" height="180" fill="url(#ocs-sky)" />

          {/* Faint horizon graticule (5-day NDVI grid) */}
          {Array.from({ length: 8 }, (_, i) => (
            <line
              key={`g${i}`}
              x1={(i + 1) * (1000 / 9)} y1="20" x2={(i + 1) * (1000 / 9)} y2="160"
              stroke="rgba(184,220,115,0.06)"
              strokeWidth="1"
            />
          ))}

          {/* Satellite arc trail */}
          <path
            d="M 80 16 Q 500 -28 920 16"
            fill="none"
            stroke="rgba(184,220,115,0.12)"
            strokeWidth="1"
            strokeDasharray="3 6"
          />

          {/* Satellite NDVI cone — sweeps with sat */}
          <polygon
            points={`${satX},${satY + 8} ${satX - 60},180 ${satX + 60},180`}
            fill="url(#ocs-cone)"
          />

          {/* Satellite body */}
          <g transform={`translate(${satX}, ${satY})`}>
            <rect x="-6" y="-3" width="12" height="6" fill="#B8DC73" />
            <rect x="-14" y="-1" width="6" height="2" fill="rgba(184,220,115,0.6)" />
            <rect x="8" y="-1" width="6" height="2" fill="rgba(184,220,115,0.6)" />
          </g>

          {/* GROUND LINE */}
          <rect x="0" y="180" width="1000" height="2" fill="rgba(255,255,255,0.18)" />

          {/* CANOPY BAND — 5 trees */}
          {trees.map((tree, i) => {
            const cx = tree.baseX;
            const trunkY = 230;
            const canopyR = 38 * tree.breath;
            const canopyCY = 178 - canopyR + 4;
            // NDVI tint over canopy gradient (mix in vertical bars)
            const tintColor = tree.ndviVal > 0.7 ? NDVI_HIGH
              : tree.ndviVal > 0.5 ? NDVI_MID : NDVI_LOW;
            return (
              <g key={`tree${i}`}>
                {/* Trunk */}
                <rect x={cx - 2.5} y={canopyCY + canopyR - 6} width="5" height={trunkY - (canopyCY + canopyR - 6)} fill="#3D2F1A" />
                {/* Canopy gradient base */}
                <ellipse cx={cx} cy={canopyCY} rx={canopyR} ry={canopyR * 0.92} fill="url(#ocs-canopy)" />
                {/* NDVI tint */}
                <ellipse cx={cx} cy={canopyCY} rx={canopyR} ry={canopyR * 0.92} fill={tintColor} opacity={0.18 + tree.ndviVal * 0.18} />
                {/* Lit ring when EMI rig passes */}
                {tree.lit > 0.05 && (
                  <ellipse cx={cx} cy={canopyCY} rx={canopyR + 4} ry={canopyR * 0.92 + 4}
                    fill="none" stroke="#B8DC73" strokeWidth="1.2" opacity={tree.lit * 0.6} />
                )}
                {/* Tree-id mono label */}
                <text x={cx} y={244} textAnchor="middle"
                  fill="rgba(255,255,255,0.45)" fontSize="9"
                  fontFamily="JetBrains Mono, monospace" letterSpacing="0.05em">
                  T{(i + 1).toString().padStart(2, '0')}
                </text>
              </g>
            );
          })}

          {/* FRUIT SIZE READOUT (floats above fruitTree) */}
          {fruitTree && (
            <g transform={`translate(${fruitTree.baseX}, ${110})`}>
              <line x1="0" y1="0" x2="0" y2="36" stroke="rgba(184,220,115,0.4)" strokeWidth="1" strokeDasharray="2 3" />
              <rect x="-46" y="-22" width="92" height="22" rx="3"
                fill="rgba(5,13,5,0.92)" stroke="rgba(184,220,115,0.45)" strokeWidth="1" />
              <text x="-40" y="-12" fill="rgba(184,220,115,0.7)" fontSize="7"
                fontFamily="JetBrains Mono, monospace" letterSpacing="0.10em">
                FRUIT · T{(fruitTreeIdx + 1).toString().padStart(2, '0')}
              </text>
              <text x="-40" y="-3" fill="white" fontSize="10"
                fontFamily="JetBrains Mono, monospace" fontWeight="600">
                {fruitSizeDisplay} mm
              </text>
              <text x="40" y="-3" textAnchor="end" fill="#B8DC73" fontSize="8"
                fontFamily="JetBrains Mono, monospace">
                +{(0.6 + pseudo(fruitTreeIdx, 47) * 1.4).toFixed(1)}/wk
              </text>
            </g>
          )}

          {/* SOIL — EC tile bands */}
          {soilBands.map((band, b) => (
            <g key={`band${b}`}>
              {Array.from({ length: cols }, (_, c) => {
                // EC value varies across the row, with a "feature" wider zone in the middle
                const x = c * colWidth;
                const noise = pseudo(c, b * 13 + 1);
                const featureCenter = 500 + Math.sin(b) * 80;
                const featureWidth = 220 + b * 40;
                const distFeature = Math.abs(x + colWidth / 2 - featureCenter) / featureWidth;
                const ecVal = Math.max(0, Math.min(1, 0.3 + (1 - distFeature) * 0.5 + noise * 0.25));
                const fill = ecVal > 0.7 ? EC_HIGH : ecVal > 0.45 ? EC_MID : EC_LOW;
                // EMI rig "lights" the column it's currently over
                const dist = Math.abs(rigX - (x + colWidth / 2));
                const lit = Math.max(0, 1 - dist / 80);
                return (
                  <rect
                    key={`tile${b}_${c}`}
                    x={x} y={band.y}
                    width={colWidth - 0.5} height={band.h}
                    fill={fill}
                    opacity={0.55 + lit * 0.4}
                  />
                );
              })}
              {/* Depth label, right side */}
              <text x="990" y={band.y + band.h / 2 + 3} textAnchor="end"
                fill="rgba(255,255,255,0.55)" fontSize="9"
                fontFamily="JetBrains Mono, monospace" letterSpacing="0.05em">
                {band.label}
              </text>
            </g>
          ))}

          {/* Soil vignette */}
          <rect x="0" y="250" width="1000" height="130" fill="url(#ocs-soil-vignette)" />

          {/* EMI rig icon on surface */}
          <g transform={`translate(${rigX}, 248)`}>
            {/* Cab */}
            <rect x="-12" y="-12" width="24" height="10" fill="#B8DC73" rx="1" />
            {/* Body */}
            <rect x="-16" y="-2" width="32" height="6" fill="#7A9C3F" rx="1" />
            {/* Wheels */}
            <circle cx="-10" cy="6" r="3.5" fill="#1B2918" stroke="#B8DC73" strokeWidth="0.8" />
            <circle cx="10" cy="6" r="3.5" fill="#1B2918" stroke="#B8DC73" strokeWidth="0.8" />
            {/* Sled with EMI coil behind */}
            <rect x="16" y="2" width="22" height="3" fill="#3F5F1F" />
            <rect x="38" y="0" width="14" height="6" fill="#5C7E2C" stroke="#B8DC73" strokeWidth="0.6" />
          </g>

          {/* EMI ping cone — radiates down from rig */}
          <polygon
            points={`${rigX},250 ${rigX - 90},370 ${rigX + 90},370`}
            fill="url(#ocs-ping)"
          />

          {/* PROBE between trees */}
          <g transform={`translate(${probeX}, 180)`}>
            {/* Above-ground head */}
            <rect x="-3" y="-12" width="6" height="12" fill="#B8DC73" />
            <circle cx="0" cy="-14" r="2"
              fill="#B8DC73" opacity={0.4 + 0.6 * Math.abs(Math.sin(t * Math.PI * 4))} />
            {/* Below-ground sensor body */}
            <rect x="-1.5" y="0" width="3" height="160" fill="#5C7E2C" />
            {/* Sensor markers */}
            {[30, 70, 130].map((y, i) => (
              <circle key={i} cx="0" cy={y} r="2.5" fill="#B8DC73" />
            ))}
            {/* Data tag */}
            <line x1="0" y1="-14" x2="32" y2="-30" stroke="rgba(184,220,115,0.4)" strokeWidth="1" />
            <rect x="32" y="-42" width="78" height="22" rx="3"
              fill="rgba(5,13,5,0.92)" stroke="rgba(184,220,115,0.45)" strokeWidth="1" />
            <text x="38" y="-32" fill="rgba(184,220,115,0.7)" fontSize="7"
              fontFamily="JetBrains Mono, monospace" letterSpacing="0.10em">PROBE · P03</text>
            <text x="38" y="-23" fill="white" fontSize="9"
              fontFamily="JetBrains Mono, monospace" fontWeight="600">
              28.4% VWC
            </text>
          </g>
        </svg>

        {/* HUD overlay — labels cycle in sync with animation */}
        <div className="ocs-hud">
          <div className="ocs-hud-eyebrow">CROSS-SECTION · ONE BLOCK</div>
          <div className="ocs-hud-stack">
            {[
              { i: 0, k: 'SAT',   v: 'Satellite · NDVI 5-day · 10 m' },
              { i: 1, k: 'CANOPY', v: 'On-demand canopy · 0.5 — 0.8 m' },
              { i: 2, k: 'FRUIT',  v: 'RevScout · per-tree count + size' },
              { i: 3, k: 'SOIL',   v: 'EMI · 25 / 50 / 90 cm @ 5 × 5 m' },
            ].map(row => (
              <div key={row.k} className={`ocs-hud-row ${labelIdx === row.i ? 'is-active' : ''}`}>
                <span className="ocs-hud-key">{row.k}</span>
                <span className="ocs-hud-val">{row.v}</span>
              </div>
            ))}
          </div>
        </div>
      </div>
    );
  };
})();
