'use strict';

// The Device — flesh background ripple (window.FleshLayer). A subtle, idle,
// NON-reactive squirm of the flesh-texture layer behind the plate.
//
// IMPORTANT (mobile): the filter is applied to an SVG <image>, NOT to an HTML
// element via `filter: url(#...)`. iOS Safari does not render url()-referenced
// SVG filters on HTML elements (that's why it was static on mobile), but it
// DOES render filters applied to SVG content. The crawl is driven by SMIL
// <animate> (feTurbulence baseFrequency + feDisplacementMap scale) rather than
// JS, because SMIL re-renders the filter reliably on iOS and needs no rAF/timer.
// Two incommensurate durations keep the motion from reading as an obvious loop.
// Runs on its own clock — intentionally NOT synced to the eye's breathing.

// ── Tuning (nudge by eye) ─────────────────────────────────────────────
const RIPPLE_DISPLACEMENT_SCALE = 8;     // max px of warp — keep small/gentle
const RIPPLE_BASE_FREQUENCY     = 0.009; // noise scale (lower = larger, slower features)
const RIPPLE_PERIOD_S           = 14;    // baseFrequency crawl period (long → barely-perceptible)
const RIPPLE_SCALE_PERIOD_S     = 11;    // displacement-depth period (≠ above → non-looping feel)
const RIPPLE_OCTAVES            = 2;     // turbulence detail (raise cost; keep low for mobile)
const RIPPLE_FREQ_WOBBLE        = 0.22;  // ± fraction the baseFrequency breathes
const RIPPLE_SCALE_FLOOR        = 0.55;  // displacement never fully flattens

const FLESH_SRC = '/the-device/assets/flesh-texture.png';

function FleshLayer() {
  const bf = RIPPLE_BASE_FREQUENCY, w = RIPPLE_FREQ_WOBBLE, sc = RIPPLE_DISPLACEMENT_SCALE;
  const f = (n) => n.toFixed(5);
  // smooth, looping value lists (start === end so SMIL loops seamlessly)
  const bfValues = `${f(bf * (1 - w))};${f(bf)};${f(bf * (1 + w))};${f(bf)};${f(bf * (1 - w))}`;
  const scValues = `${(sc * RIPPLE_SCALE_FLOOR).toFixed(2)};${sc.toFixed(2)};${(sc * 0.7).toFixed(2)};${(sc * 0.9).toFixed(2)};${(sc * RIPPLE_SCALE_FLOOR).toFixed(2)}`;

  return (
    <svg
      aria-hidden="true"
      preserveAspectRatio="xMidYMid slice"
      style={{
        position: 'absolute', inset: '-3%', width: '106%', height: '106%',
        zIndex: 0, pointerEvents: 'none', display: 'block',
      }}
    >
      <defs>
        <filter id="flesh-ripple" x="-6%" y="-6%" width="112%" height="112%" colorInterpolationFilters="sRGB">
          <feTurbulence type="fractalNoise" baseFrequency={RIPPLE_BASE_FREQUENCY} numOctaves={RIPPLE_OCTAVES} seed="7" result="noise">
            <animate attributeName="baseFrequency" values={bfValues} dur={`${RIPPLE_PERIOD_S}s`} repeatCount="indefinite" calcMode="spline"
                     keyTimes="0;0.25;0.5;0.75;1" keySplines="0.4 0 0.6 1;0.4 0 0.6 1;0.4 0 0.6 1;0.4 0 0.6 1" />
          </feTurbulence>
          <feDisplacementMap in="SourceGraphic" in2="noise" scale={RIPPLE_DISPLACEMENT_SCALE} xChannelSelector="R" yChannelSelector="G">
            <animate attributeName="scale" values={scValues} dur={`${RIPPLE_SCALE_PERIOD_S}s`} repeatCount="indefinite" calcMode="spline"
                     keyTimes="0;0.25;0.5;0.75;1" keySplines="0.4 0 0.6 1;0.4 0 0.6 1;0.4 0 0.6 1;0.4 0 0.6 1" />
          </feDisplacementMap>
        </filter>
      </defs>

      {/* base fill so any displaced edge never bares the page behind */}
      <rect x="0" y="0" width="100%" height="100%" fill="#060403" />
      {/* the flesh image, covered (slice) and warped by the filter */}
      <image
        href={FLESH_SRC} xlinkHref={FLESH_SRC}
        x="0" y="0" width="100%" height="100%"
        preserveAspectRatio="xMidYMid slice"
        filter="url(#flesh-ripple)"
      />
    </svg>
  );
}

window.FleshLayer = FleshLayer;
