// gate.jsx — THE COVER.
//
// A generative guilloché (the layered engraving on currency) drawn live on
// Canvas, centered on the company seal. Headline in Fraunces; the code box and
// wording carried over from the standard front door. The gate holds NO pricing
// logic — it collects the code and reports the server's answer. Wiring
// (onUnlock → POST /api/unlock → session cookie) is unchanged.
const { useState: useStateG, useRef: useRefG, useEffect: useEffectG } = React;
const DESKTOP = typeof window !== 'undefined' && window.matchMedia('(min-width: 961px)').matches;

// Guilloché — nested hypotrochoid roses, red line-work only, centered on the
// seal so the pattern reads as engraved around it. Canvas because it's a
// mathematical field, not a shape.
function Guilloche() {
  const ref = useRefG(null);
  useEffectG(() => {
    const cv = ref.current;
    if (!cv) return;
    const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    const ctx = cv.getContext('2d');
    let raf = 0, t = 0, w = 0, h = 0, dpr = Math.min(window.devicePixelRatio || 1, 2);

    function size() {
      const r = cv.getBoundingClientRect();
      w = r.width; h = r.height;
      cv.width = w * dpr; cv.height = h * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    }
    // rosette center = the seal's center, so the seal sits in its heart
    function center() {
      const seal = document.querySelector('.cover-seal');
      const cr = cv.getBoundingClientRect();
      if (seal) {
        const sr = seal.getBoundingClientRect();
        return { cx: sr.left + sr.width / 2 - cr.left, cy: sr.top + sr.height / 2 - cr.top };
      }
      return { cx: w / 2, cy: h * 0.4 };
    }
    function rose(cx, cy, R, r, d, turns, stroke, alpha, phase, lw) {
      ctx.beginPath();
      const steps = 1440;
      for (let i = 0; i <= steps; i++) {
        const a = (i / steps) * Math.PI * 2 * turns + phase;
        const k = (R - r) / r;
        const x = cx + (R - r) * Math.cos(a) + d * Math.cos(k * a);
        const y = cy + (R - r) * Math.sin(a) - d * Math.sin(k * a);
        i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
      }
      ctx.strokeStyle = stroke; ctx.globalAlpha = alpha; ctx.lineWidth = lw; ctx.stroke(); ctx.globalAlpha = 1;
    }
    function draw() {
      ctx.clearRect(0, 0, w, h);
      const { cx, cy } = center();
      const base = Math.min(w, h) * 0.92;
      // Ember ramp matching the marketing-site accent (#ff3b2c / #c8102e).
      rose(cx, cy, base * 0.46, base * 0.052, base * 0.200, 26, '#ff3b2c', 0.34, t,        0.8);
      rose(cx, cy, base * 0.38, base * 0.037, base * 0.160, 30, '#c8102e', 0.26, -t * 0.8,  0.75);
      rose(cx, cy, base * 0.30, base * 0.028, base * 0.120, 34, '#ff6a4d', 0.22, t * 1.3,   0.7);
      rose(cx, cy, base * 0.21, base * 0.020, base * 0.090, 22, '#8f1020', 0.20, -t * 1.1,  0.65);
    }
    size(); draw();
    const onResize = () => { size(); draw(); };
    window.addEventListener('resize', onResize);
    if (!reduce) {
      const loop = () => { t += 0.0008; draw(); raf = requestAnimationFrame(loop); };
      raf = requestAnimationFrame(loop);
    }
    const settle = setTimeout(() => { size(); draw(); }, 320); // re-center after layout settles
    return () => { cancelAnimationFrame(raf); clearTimeout(settle); window.removeEventListener('resize', onResize); };
  }, []);
  return <canvas className="guilloche" ref={ref} aria-hidden="true"></canvas>;
}

function Gate({ unlocked, company, onUnlock, onEnterLocked, onContinue, onLock }) {
  const [val, setVal] = useStateG('');
  const [notice, setNotice] = useStateG('');
  const [busy, setBusy] = useStateG(false);

  async function submit(e) {
    e.preventDefault();
    const v = val.trim().toLowerCase();
    if (!v) { setNotice('Enter your clearance code'); return; }
    setBusy(true); setNotice('');
    const res = await onUnlock(v);
    setBusy(false);
    if (!res.ok) setNotice(res.error === 'network' ? "Couldn't reach the server, try again" : "That code wasn't recognized");
  }

  return (
    <div className="cover">
      <Guilloche />
      <div className="cover-stage">
        <div className="cover-seal">
          <img src="assets/tsw-seal-hero.png" alt="Top Secret Workshops" />
        </div>

        <h1 className="cover-headline">
          <span>Specs public.</span>
          <span className="line2">Terms <em className={unlocked ? 'ok' : 'no'}>{unlocked ? 'unsealed.' : 'sealed.'}</em></span>
        </h1>

        {unlocked ? (
          <div className="cover-panel cover-panel-on">
            <div className="token-row"><span className="led led-green"></span><span className="token-label">Clearance verified</span></div>
            <h2 className="cover-panel-title">{company || 'Buyer recognized'}</h2>
            <p className="cover-panel-copy">Wholesale terms are visible across the book for this session.</p>
            <div className="cover-actions">
              <button className="btn-red" onClick={onContinue}>Enter the book →</button>
              <button className="btn-ghost" onClick={onLock}>Re-seal</button>
            </div>
          </div>
        ) : (
          <div className="cover-panel">
            <div className="token-row"><span className="led"></span><span className="token-label">Clearance code</span></div>
            <form className="token-field" onSubmit={submit}>
              <input type="password" placeholder="Enter code here" value={val} autoFocus={DESKTOP}
                autoComplete="off" spellCheck="false" onChange={(e) => setVal(e.target.value)} />
              <button type="submit" disabled={busy}>{busy ? 'Checking…' : 'Lift the seal →'}</button>
            </form>
            <div className="token-notice">{notice || 'Issued in your outreach email · verified server-side'}</div>
            <div className="cover-or"><span>No code?</span></div>
            <button type="button" className="cover-peek" onClick={onEnterLocked}>
              Look inside without clearance
            </button>
            <p className="cover-peek-note">Peek behind the veil — specs stay public, pricing stays sealed.</p>
          </div>
        )}

        <div className="cover-foot">
          <span>Licensed operators only · 21+</span>
          <span className="wax-dot"></span>
          <span>Montana market live</span>
        </div>
      </div>
    </div>);
}

Object.assign(window, { Gate, Guilloche });
