const { useState, useEffect } = React;

function Slider({ label, value, onChange, min, max, step, symbol, unit }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 4, minWidth: 0 }}>
      <div className="slider-head">
        <span>
          {symbol && <em className="slider-sym">{symbol}</em>}
          <span>{label}</span>
        </span>
        <span className="slider-val">{value.toFixed(2)}{unit}</span>
      </div>
      <input
        type="range"
        min={min}
        max={max}
        step={step}
        value={value}
        onChange={(e) => onChange(parseFloat(e.target.value))}
        className="nat-slider"
      />
    </div>
  );
}

window.FigureLame = function FigureLame() {
  const [n, setN] = useState(2.5);
  const [a, setA] = useState(1.0);
  const [b, setB] = useState(0.72);
  const pts = window.lameEgg({ a, b, n });

  return (
    <figure className="mini-figure">
      <div className="mini-figure-plate">
        <svg viewBox="0 0 260 260" width="260" height="260" style={{ position: 'absolute', inset: 0 }}>
          <g opacity="0.22" fill="none" stroke="var(--ink-2)" strokeWidth="0.6" strokeDasharray="3 3">
            <ellipse cx="130" cy="130" rx={a * 80} ry={b * 80} />
          </g>
        </svg>
        <window.EggSVG
          points={pts}
          width={260}
          height={260}
          shell={{ base: '#ecdcb2', accent: null, speckles: null }}
          showLabel
          figNumber="I"
          flipX={false}
        />
      </div>
      <figcaption>
        <div className="mini-figure-controls">
          <Slider label="exponent" symbol="n" value={n} onChange={setN} min={1.4} max={6} step={0.05} />
          <Slider label="half-length" symbol="a" value={a} onChange={setA} min={0.6} max={1.2} step={0.02} />
          <Slider label="half-width" symbol="b" value={b} onChange={setB} min={0.4} max={1.0} step={0.02} />
        </div>
        <div className="mini-figure-eq">
          <span>|x/a|<sup>n</sup> + |y/b|<sup>n</sup> = 1</span>
          <em>— Lamé, 1818. Symmetric: rotate 180° and the shape is unchanged.</em>
        </div>
      </figcaption>
    </figure>
  );
};

window.FigureHugel = function FigureHugel() {
  const [w, setW] = useState(0.15);
  const [a, setA] = useState(1.0);
  const [b, setB] = useState(0.72);
  const pts = window.hugelschafferEgg({ a, b, w });

  return (
    <figure className="mini-figure">
      <div className="mini-figure-plate">
        <svg viewBox="0 0 260 260" width="260" height="260" style={{ position: 'absolute', inset: 0 }}>
          <g opacity="0.2" fill="none" stroke="var(--ink-2)" strokeWidth="0.6" strokeDasharray="3 3">
            <circle cx="130" cy="130" r={a * 80} />
            <circle cx={130 + w * 80} cy="130" r={b * 80} />
          </g>
        </svg>
        <window.EggSVG
          points={pts}
          width={260}
          height={260}
          shell={{ base: '#c8b593', accent: null, speckles: null }}
          showLabel
          figNumber="II"
        />
      </div>
      <figcaption>
        <div className="mini-figure-controls">
          <Slider label="offset" symbol="w" value={w} onChange={setW} min={0} max={0.35} step={0.01} />
          <Slider label="half-length" symbol="a" value={a} onChange={setA} min={0.7} max={1.2} step={0.02} />
          <Slider label="half-width" symbol="b" value={b} onChange={setB} min={0.4} max={0.9} step={0.02} />
        </div>
        <div className="mini-figure-eq">
          <span>2wxy² + b²x² + (a²+w²)y² − a²b² = 0</span>
          <em>— Hügelschäffer, 1944. Slide w to see one circle drift off-axis.</em>
        </div>
      </figcaption>
    </figure>
  );
};

window.FigurePreston = function FigurePreston() {
  const [c1, setC1] = useState(0.12);
  const [c2, setC2] = useState(-0.05);
  const [c3, setC3] = useState(0.0);
  const pts = window.prestonEgg({ a: 1, b: 0.72, c1, c2, c3 });

  return (
    <figure className="mini-figure">
      <div className="mini-figure-plate">
        <window.EggSVG
          points={pts}
          width={260}
          height={260}
          shell={{
            base: '#b5a67e',
            accent: '#281b11',
            speckles: { count: 80, sizeMin: 0.01, sizeMax: 0.025, distribution: 'polar', variance: 0.6 },
          }}
          showLabel
          figNumber="III"
          speckleSeed={Math.round((c1 + c2 + c3 + 5) * 100)}
        />
      </div>
      <figcaption>
        <div className="mini-figure-controls">
          <Slider label="asymmetry" symbol="c₁" value={c1} onChange={setC1} min={-0.3} max={0.4} step={0.01} />
          <Slider label="bicone" symbol="c₂" value={c2} onChange={setC2} min={-0.25} max={0.25} step={0.01} />
          <Slider label="fine taper" symbol="c₃" value={c3} onChange={setC3} min={-0.2} max={0.2} step={0.01} />
        </div>
        <div className="mini-figure-eq">
          <span>y = b·sinθ·(1 + c₁cosθ + c₂cos²θ + c₃cos³θ)</span>
          <em>— Preston, 1953. Four parameters; fits nearly any real egg.</em>
        </div>
      </figcaption>
    </figure>
  );
};

window.FigureNarushin = function FigureNarushin() {
  const [w, setW] = useState(0.22);
  const [p, setP] = useState(0.35);
  const pts = window.narushinEgg({ L: 2, B: 1.3, w, p });

  return (
    <figure className="mini-figure">
      <div className="mini-figure-plate">
        <window.EggSVG
          points={pts}
          width={260}
          height={260}
          shell={{
            base: '#c3cba8',
            accent: '#231912',
            speckles: { count: 140, sizeMin: 0.012, sizeMax: 0.048, distribution: 'polar', variance: 0.7 },
          }}
          showLabel
          figNumber="IV"
          speckleSeed={42}
        />
      </div>
      <figcaption>
        <div className="mini-figure-controls">
          <Slider label="offset" symbol="w" value={w} onChange={setW} min={0} max={0.35} step={0.01} />
          <Slider label="pyriformity" symbol="p" value={p} onChange={setP} min={0} max={0.55} step={0.01} />
        </div>
        <div className="mini-figure-eq">
          <span>ovoid(L,B,w) × (1 − p·σ(x))</span>
          <em>— Narushin, 2021. Push p up to summon a guillemot.</em>
        </div>
      </figcaption>
    </figure>
  );
};

Object.assign(window, {
  FigureLame: window.FigureLame,
  FigureHugel: window.FigureHugel,
  FigurePreston: window.FigurePreston,
  FigureNarushin: window.FigureNarushin,
});
