// Day/Night cinematic section — real time-lapse video, scrubbed by toggle
function DayNight() {
  const [mode, setMode] = useState('day'); // day | night
  const rootRef = useRef(null);
  const videoRef = useRef(null);
  const animRef = useRef(null);

  // Video time anchors. Source clip is a 5s day → night transition;
  // the final two seconds hold a stable night view.
  const DAY_T = 0.0;
  const NIGHT_T = 4.9;
  const SCRUB_MS = 2200; // a beat slower than the original 2.5s for that wow

  // Smoothly scrub video.currentTime to a target. Throttled to ~12fps so
  // each seek can actually decode and paint before the next one preempts it
  // — rAF-rate seeks (~60fps) cause the browser to discard frames mid-flight
  // and the video appears frozen. Reverse playback via playbackRate is not
  // reliable across browsers, so we step the timestamp explicitly in both
  // directions.
  //
  // iOS Safari note: the decoder won't paint any frame until play() succeeds.
  // Setting currentTime alone produces a black box on iOS even after seek
  // completes. Calling play() inside the click handler counts as a user
  // gesture and unlocks the decoder even in Low Power Mode; we immediately
  // pause and let the seek loop drive the rest.
  const seekTo = useCallback((target) => {
    const v = videoRef.current;
    if (!v) return;
    const reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    const wake = v.play();
    const startScrub = () => {
      v.pause();
      if (animRef.current) clearTimeout(animRef.current);
      // prefers-reduced-motion: jump straight to the endpoint, no scrub loop.
      if (reduceMotion) {
        try { v.currentTime = target; } catch {}
        return;
      }
      const start = v.currentTime;
      const t0 = performance.now();
      const tick = () => {
        const t = Math.min((performance.now() - t0) / SCRUB_MS, 1);
        const eased = t < 0.5 ? 2*t*t : -1 + (4 - 2*t)*t;
        try { v.currentTime = start + (target - start) * eased; } catch {}
        if (t < 1) animRef.current = setTimeout(tick, 80);
      };
      tick();
    };
    if (wake && typeof wake.then === 'function') {
      wake.then(startScrub).catch(startScrub);
    } else {
      startScrub();
    }
  }, []);

  useEffect(() => {
    if (!rootRef.current) return;
    rootRef.current.style.setProperty('--dn', mode === 'night' ? '1' : '0');
  }, [mode]);

  // On mount, park the video at the day frame. iOS Safari additionally
  // requires a successful play()/pause() handshake before currentTime
  // changes will paint anything; we attempt that opportunistically so
  // non-LPM iPhones see the day frame on first paint. LPM iPhones will
  // still see black until the user taps the Day/Night toggle, where the
  // user gesture wakes the decoder — that's recovered in seekTo().
  useEffect(() => {
    const v = videoRef.current;
    if (!v) return;
    const park = () => {
      const p = v.play();
      const settle = () => {
        v.pause();
        try { v.currentTime = DAY_T; } catch {}
      };
      if (p && typeof p.then === 'function') p.then(settle).catch(settle);
      else settle();
    };
    if (v.readyState >= 1) park();
    else v.addEventListener('loadedmetadata', park, { once: true });
    return () => { if (animRef.current) clearTimeout(animRef.current); };
  }, []);

  const handleToggle = (next) => {
    if (next === mode) return;
    setMode(next);
    seekTo(next === 'night' ? NIGHT_T : DAY_T);
  };

  return (
    <section id="daynight" ref={rootRef} className="dn-section" style={{ padding: '140px 0 140px', overflow: 'hidden' }}>
      <div className="container-x">
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'end', gap: 40, flexWrap: 'wrap', marginBottom: 40 }}>
          <div style={{ maxWidth: 720 }}>
            <Reveal><div className="eyebrow" style={{ color: mode === 'night' ? 'rgba(250,247,241,.7)' : 'var(--forest-800)' }}><span className="kicker-num" style={{ color: mode === 'night' ? 'var(--wheat-400)' : undefined }}>08</span><span className="dot" /> Dark‑sky standards</div></Reveal>
            <Reveal delay={1}><h2 className="h2" style={{ marginTop: 18 }}>A quiet presence,<br/><span className="civic-emphasis" style={{ color: mode === 'night' ? 'var(--accent)' : 'var(--accent-deep)' }}>day and night.</span></h2></Reveal>
          </div>
          <Reveal delay={2}>
            <p className="dn-muted" style={{ fontSize: 16, lineHeight: 1.6, maxWidth: 420 }}>
              Lighting and fencing standards are written to reduce glare, protect night skies, and allow wildlife to maintain movement patterns. Toggle between day and night to see how the campus settles into the landscape after sundown.
            </p>
          </Reveal>
        </div>

        {/* Scene */}
        <Reveal delay={2}>
          <div style={{ position: 'relative', borderRadius: 'var(--r-lg)', overflow: 'hidden', border: '1px solid rgba(255,255,255,.08)', boxShadow: 'var(--shadow-lg)' }}>
            <div style={{ position: 'relative', aspectRatio: '16 / 9', background: '#000' }}>
              <video
                ref={videoRef}
                src="/video/daynight.mp4?v=2026-08-04-master-clock"
                poster="/images/daynight-poster.webp?v=2026-08-04-master-clock"
                muted
                playsInline
                preload="metadata"
                style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
              />

              {/* Bottom gradient — adds depth + kills the "Veo" watermark contrast */}
              <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', background: 'linear-gradient(180deg, rgba(0,0,0,0) 55%, rgba(0,0,0,.55) 100%)' }} />

              {/* Toggle */}
              <div style={{ position: 'absolute', left: 20, top: 20, display: 'flex', gap: 10 }}>
                <span className="pill pill-dark" style={{ background: 'rgba(0,0,0,.45)', color: 'white' }} aria-live="polite">
                  {mode === 'day' ? 'Daytime view' : 'Nighttime view · dark‑sky compliant'}
                </span>
              </div>
              <div style={{ position: 'absolute', right: 20, top: 20 }}>
                <div className="glass-dark" role="group" aria-label="Day or night view" style={{ display: 'inline-flex', padding: 4, borderRadius: 'var(--r-pill)', gap: 2 }}>
                  {[{k:'day', label:'Day', Icon: Icons.Sun}, {k:'night', label:'Night', Icon: Icons.Moon}].map(opt => (
                    <button key={opt.k} onClick={() => handleToggle(opt.k)} aria-pressed={mode === opt.k} style={{
                      display: 'inline-flex', alignItems: 'center', gap: 8,
                      padding: '10px 16px', borderRadius: 'var(--r-pill)', border: 'none', cursor: 'pointer',
                      background: mode === opt.k ? 'white' : 'transparent',
                      color: mode === opt.k ? 'var(--ink)' : 'rgba(255,255,255,.85)',
                      fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 13,
                      transition: 'background .3s, color .3s'
                    }}>
                      <opt.Icon size={16} /> {opt.label}
                    </button>
                  ))}
                </div>
              </div>

            </div>
          </div>
        </Reveal>

        {/* Caption — what actually changes at night, sourced from the lights brief */}
        <p className="dn-muted" style={{ marginTop: 16, fontSize: 13, lineHeight: 1.5, maxWidth: 640 }}>
          At night: full cut-off fixtures direct no light above 80° from straight down, color temperature shifts warmer (3000K or below), and no fixture aims uplight — the same specification &ldquo;DarkSky Approved&rdquo; certification checks for.
        </p>

        {/* Stat row */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 18, marginTop: 28 }}>
          {[
            { k: 'Dark‑sky', v: 'Lighting standards', text: 'Glare reduced; night skies and wildlife movement protected.' },
            { k: 'Inward', v: 'Equipment oriented', text: 'Generators and cooling face the interior — away from property lines.' },
            { k: 'Before 4pm', v: 'Generator testing', text: 'Limited to Monday–Friday before 4pm; required by design.' },
          // elev-lift only (not elev-sm): dn-card's border-color is driven
          // by the protected --dn CSS-variable day/night formula in
          // index.html — a shadow-only lift avoids fighting it.
          ].map((s, i) => (
            <Reveal key={i} delay={i+1} className="dn-card elev-lift" style={{ padding: 22, borderRadius: 'var(--r-md)', border: '1px solid rgba(10,24,18,.08)', boxShadow: 'var(--shadow-xs)', transition: 'background-color 2.5s ease, border-color 2.5s ease, box-shadow .25s ease, transform .25s ease' }}>
              <div className="font-display" style={{ fontWeight: 600, fontSize: 22 }}>{s.k}</div>
              <div className="tag-mono" style={{ marginTop: 4 }}>{s.v}</div>
              <div className="dn-muted" style={{ fontSize: 14.5, lineHeight: 1.55, marginTop: 10 }}>{s.text}</div>
            </Reveal>
          ))}
        </div>
      </div>

      {/* Noise sub-block (U8) — pairs with the "quiet at night" theme */}
      <NoiseComparison />

      <style>{`@media(max-width: 820px){ #daynight > .container-x > div:last-child { grid-template-columns: 1fr !important; } }`}</style>
    </section>
  );
}
window.DayNight = DayNight;
