// scene_satellite.jsx — light cartographic version.
function ForestPlot({ x, y, w, h, filled = 0, color = PAL.result }) {
  const pts = [
    [0, 0.2], [0.15, 0.05], [0.45, 0], [0.72, 0.08],
    [0.92, 0.22], [1, 0.48], [0.94, 0.72], [0.78, 0.9],
    [0.5, 0.98], [0.22, 0.94], [0.06, 0.78], [0, 0.52],
  ];
  const d = pts.map(([px, py], i) => `${i === 0 ? 'M' : 'L'} ${x + px * w} ${y + py * h}`).join(' ') + ' Z';
  return (
    <g>
      <path d={d} fill={color} fillOpacity={0.1 * filled} stroke={color} strokeWidth="2" />
    </g>
  );
}

function TileMosaic({ cx, cy, size, cols, rows, progress }) {
  const tiles = [];
  const tileW = size / cols;
  const tileH = size / rows;
  const total = cols * rows;
  const visibleCount = Math.floor(progress * total);
  const order = Array.from({ length: total }, (_, i) => i);
  for (let i = 0; i < total; i++) {
    const j = (i * 7 + 3) % total;
    [order[i], order[j]] = [order[j], order[i]];
  }
  const visibleSet = new Set(order.slice(0, visibleCount));
  for (let r = 0; r < rows; r++) {
    for (let c = 0; c < cols; c++) {
      const idx = r * cols + c;
      if (!visibleSet.has(idx)) continue;
      const x = cx - size / 2 + c * tileW;
      const y = cy - size / 2 + r * tileH;
      const s = (idx * 9301 + 49297) % 233280;
      const rnd = s / 233280;
      // Realistic forest tones: greens, olives, some browns
      const hue = 110 + rnd * 50;
      const lum = 38 + rnd * 18;
      const chroma = 0.05 + rnd * 0.06;
      tiles.push(
        <rect key={idx}
          x={x} y={y}
          width={tileW - 1} height={tileH - 1}
          fill={`oklch(${lum}% ${chroma} ${hue})`}
          opacity="0.92"
        />
      );
    }
  }
  return <g>{tiles}</g>;
}

function SceneSatellite() {
  const { localTime, duration } = useSprite();
  const t = useTime();
  const introT = Easing.easeOutCubic(clamp(localTime / 1.2, 0, 1));
  const plotT = Easing.easeOutCubic(clamp((localTime - 0.8) / 1.0, 0, 1));
  const scanT = clamp((localTime - 1.5) / 2.5, 0, 1);
  const scanY = 260 + scanT * 560;
  const tileT = Easing.easeInOutCubic(clamp((localTime - 1.8) / 3.2, 0, 1));
  const zoom = 1 + Easing.easeInOutCubic(clamp(localTime / duration, 0, 1)) * 0.06;
  const satProg = clamp((localTime - 0.3) / 5.5, 0, 1);
  const satX = -100 + satProg * 2120;
  const outT = Easing.easeInCubic(clamp((localTime - (duration - 0.5)) / 0.5, 0, 1));

  const cx = 1180, cy = 560;
  const plotW = 620, plotH = 470;

  return (
    <div style={{ position: 'absolute', inset: 0, background: PAL.bg, opacity: 1 - outT }}>
      <GridPaper opacity={0.22} />
      <TopoLines opacity={0.22} color="oklch(45% 0.1 240 / 0.35)" />

      <div style={{
        position: 'absolute', inset: 0,
        transform: `scale(${zoom})`, transformOrigin: '60% 55%',
      }}>
        <svg width="1920" height="1080" style={{ position: 'absolute', inset: 0 }}>
          <g opacity={plotT}>
            <ForestPlot x={cx - plotW / 2} y={cy - plotH / 2} w={plotW} h={plotH} filled={plotT} />
          </g>

          <defs>
            <clipPath id="plotClip">
              <path d={(() => {
                const pts = [
                  [0, 0.2], [0.15, 0.05], [0.45, 0], [0.72, 0.08],
                  [0.92, 0.22], [1, 0.48], [0.94, 0.72], [0.78, 0.9],
                  [0.5, 0.98], [0.22, 0.94], [0.06, 0.78], [0, 0.52],
                ];
                const x0 = cx - plotW / 2, y0 = cy - plotH / 2;
                return pts.map(([px, py], i) => `${i === 0 ? 'M' : 'L'} ${x0 + px * plotW} ${y0 + py * plotH}`).join(' ') + ' Z';
              })()} />
            </clipPath>
          </defs>
          <g clipPath="url(#plotClip)">
            <TileMosaic cx={cx} cy={cy} size={720} cols={22} rows={17} progress={tileT} />
          </g>

          {/* Scan sweep */}
          {scanT > 0 && scanT < 1 && (
            <g>
              <rect x="0" y={scanY - 1} width="1920" height="2" fill={PAL.sat} opacity="0.7" />
              <rect x="0" y={scanY - 30} width="1920" height="60" fill={PAL.sat} opacity="0.06" />
            </g>
          )}

          {/* Satellite */}
          <g opacity={introT} transform={`translate(${satX}, 180)`}>
            <rect x="-14" y="-5" width="28" height="10" fill={PAL.ink} />
            <rect x="-40" y="-2" width="20" height="4" fill={PAL.sat} />
            <rect x="20" y="-2" width="20" height="4" fill={PAL.sat} />
            <circle cx="0" cy="0" r="16" fill={PAL.sat} opacity="0.12" />
          </g>

          {/* Crosshairs on plot corners */}
          <g opacity={plotT}>
            {[[cx - plotW/2, cy - plotH/2], [cx + plotW/2, cy - plotH/2],
              [cx - plotW/2, cy + plotH/2], [cx + plotW/2, cy + plotH/2]].map(([px, py], i) => (
              <g key={i}>
                <line x1={px - 12} y1={py} x2={px + 12} y2={py} stroke={PAL.sat} strokeWidth="1.5" />
                <line x1={px} y1={py - 12} x2={px} y2={py + 12} stroke={PAL.sat} strokeWidth="1.5" />
              </g>
            ))}
          </g>
        </svg>

        <div style={{
          position: 'absolute',
          left: cx + plotW / 2 + 30, top: cy - plotH / 2 - 10,
          fontFamily: FONT_MONO, fontSize: 12,
          color: PAL.sat, letterSpacing: '0.08em',
          opacity: plotT,
        }}>
          PLOT #A-7142 · 248.6 HA
        </div>
        <div style={{
          position: 'absolute',
          left: cx - plotW / 2 - 200, top: cy + plotH / 2 - 20,
          fontFamily: FONT_MONO, fontSize: 12,
          color: PAL.inkSoft, letterSpacing: '0.08em', textAlign: 'right',
        }}>
          SENTINEL-2 L2A<br/>
          10M / PX · 4 BANDS
        </div>
      </div>

      <ChapterHead
        num="01"
        title={<>{tr('sat.title1')}<br/>{tr('sat.title2')}</>}
        subtitle={tr('sat.subtitle')}
        color={PAL.sat}
        x={60} y={240}
      />

      <StepIndicator active={0} />
      <FrameChrome
        label="LAYER 01 / SAT"
        coords="SWATH 290KM · REVISIT 5 DAYS"
        step="01"
      />

      <div style={{
        position: 'absolute',
        right: 140, top: 160, width: 260,
        fontFamily: FONT_MONO, fontSize: 11,
        color: PAL.inkSoft, letterSpacing: '0.1em',
        opacity: introT,
      }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
          <span>{tr('sat.acqLabel')}</span>
          <span style={{ color: PAL.sat }}>{Math.round(tileT * 100)}%</span>
        </div>
        <div style={{ width: '100%', height: 2, background: PAL.line, position: 'relative' }}>
          <div style={{
            position: 'absolute', left: 0, top: 0, height: '100%',
            width: `${tileT * 100}%`, background: PAL.sat,
          }}/>
        </div>
        <div style={{ marginTop: 14, color: PAL.inkDim, fontSize: 10 }}>
          TILES {Math.floor(tileT * 432)} / 432
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { SceneSatellite });
