// Norton-Gauss · Cases main page — animated coverflow carousel
// Renders NG.casesIndex as a 3D coverflow with per-case miniature
// visualizations, drag / wheel / keyboard nav, a thumbnail rail and
// optional gentle autoplay. On-brand: dark, lime sparingly, node motif.

const { useState: cS, useEffect: cE, useRef: cR, useCallback: cCB } = React;
const NGC = window.NG;

// ── Tiny line icons (unique names to avoid cross-file collisions) ──
const CcChevL = () => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M15 18l-6-6 6-6" /></svg>
);
const CcChevR = () => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M9 18l6-6-6-6" /></svg>
);

// ── Per-case miniature visualizations ─────────────────────────────
const LIME = '#D9FF35';
const DIM = '#3C5650';
const FAINT = '#1A2E29';

function CaseMiniViz({ kind, labels }) {
  const common = { viewBox: '0 0 280 124', preserveAspectRatio: 'xMidYMid slice' };
  const L = labels || {};

  if (kind === 'close') {
    // Overnight close — radar clock, 02:00→06:00 arc lit, pulsing nodes
    const cx = 210, cy = 62, r = 42;
    const pol = (deg, rad) => [cx + rad * Math.cos((deg - 90) * Math.PI / 180), cy + rad * Math.sin((deg - 90) * Math.PI / 180)];
    const a0 = 60, a1 = 180; // 02:00 → 06:00 segment on a 12h dial
    const [sx, sy] = pol(a0, r), [ex, ey] = pol(a1, r);
    return (
      <svg {...common}>
        <circle cx={cx} cy={cy} r={r} fill="none" stroke={FAINT} strokeWidth="1.5" />
        {Array.from({ length: 12 }).map((_, i) => {
          const [x1, y1] = pol(i * 30, r - 4), [x2, y2] = pol(i * 30, r);
          return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2} stroke={DIM} strokeWidth="1" />;
        })}
        <path d={`M ${sx} ${sy} A ${r} ${r} 0 0 1 ${ex} ${ey}`} fill="none" stroke={LIME} strokeWidth="2.5" strokeLinecap="round" />
        <line x1={cx} y1={cy} x2={pol(a0, r)[0]} y2={pol(a0, r)[1]} stroke={LIME} strokeWidth="1.5" className="vz-sweep" style={{ transformOrigin: `${cx}px ${cy}px` }} />
        <circle cx={sx} cy={sy} r="3.5" fill={LIME} className="vz-pulse" />
        <circle cx={ex} cy={ey} r="3.5" fill={LIME} className="vz-pulse d2" />
        <circle cx={cx} cy={cy} r="2.4" fill={LIME} />
        <text x="30" y="52" fontFamily="var(--font-mono)" fontSize="13" letterSpacing="1" fill="#C9D6CF">02:00</text>
        <text x="30" y="78" fontFamily="var(--font-mono)" fontSize="13" letterSpacing="1" fill={LIME}>→ 06:00</text>
      </svg>
    );
  }

  if (kind === 'proposal') {
    return (
      <svg {...common}>
        <text x="28" y="34" fontFamily="var(--font-mono)" fontSize="9.5" letterSpacing="1.6" fill={DIM}>BEFORE</text>
        <rect x="28" y="42" width="224" height="11" rx="3" fill={FAINT} />
        <text x="252" y="34" textAnchor="end" fontFamily="var(--font-mono)" fontSize="9.5" letterSpacing="1.4" fill="#7C8F89">{L.before || '6 WEEKS'}</text>
        <text x="28" y="84" fontFamily="var(--font-mono)" fontSize="9.5" letterSpacing="1.6" fill={LIME}>AFTER</text>
        <rect x="28" y="92" width="20" height="11" rx="3" fill={LIME} className="vz-grow" style={{ transformOrigin: 'left' }} />
        <text x="56" y="101" fontFamily="var(--font-mono)" fontSize="9.5" letterSpacing="1.4" fill={LIME}>{L.after || '6 HOURS'}</text>
      </svg>
    );
  }

  if (kind === 'edge') {
    const cols = 16, rows = 7;
    const cells = [];
    for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) {
      const x = 22 + c * 15.2, y = 18 + r * 13.4;
      const lit = (c * 3 + r * 5) % 11 === 0;
      cells.push({ x, y, lit, i: r * cols + c });
    }
    return (
      <svg {...common}>
        {cells.map((p) => p.lit
          ? <circle key={p.i} cx={p.x} cy={p.y} r="2.6" fill={LIME} className={`vz-pulse d${p.i % 4}`} />
          : <circle key={p.i} cx={p.x} cy={p.y} r="1.3" fill={FAINT} />)}
      </svg>
    );
  }

  if (kind === 'claims') {
    // throughput: one input lane fans into 4 stacked output lanes
    const lanes = [0, 1, 2, 3];
    return (
      <svg {...common}>
        <rect x="26" y="56" width="42" height="12" rx="3" fill={DIM} />
        <text x="26" y="48" fontFamily="var(--font-mono)" fontSize="8.5" letterSpacing="1.1" fill={DIM}>{L.inp || 'INPUT'}</text>
        {lanes.map((l) => (
          <g key={l}>
            <path d={`M 70 62 C 110 62, 120 ${30 + l * 22}, 150 ${30 + l * 22}`} fill="none" stroke={FAINT} strokeWidth="1.4" className="vz-dash" />
            <rect x="150" y={`${24 + l * 22}`} width="96" height="11" rx="3" fill={LIME} opacity={0.55 + l * 0.12} className="vz-grow" style={{ transformOrigin: 'left', animationDelay: `${l * 0.12}s` }} />
          </g>
        ))}
        <text x="246" y="20" textAnchor="end" fontFamily="var(--font-mono)" fontSize="8.5" letterSpacing="1.1" fill={LIME}>{L.out || 'OUTPUT'}</text>
      </svg>
    );
  }

  if (kind === 'maint') {
    // predictive waveform with a dip + dashed forecast line and markers
    const w = 280, base = 70, pts = [];
    for (let i = 0; i <= 40; i++) {
      const x = 16 + i * 6.2;
      const dip = i > 22 && i < 30 ? -18 * Math.exp(-Math.pow((i - 26) / 3, 2)) : 0;
      const y = base + Math.sin(i / 2.2) * 9 + dip;
      pts.push(`${x},${y.toFixed(1)}`);
    }
    return (
      <svg {...common}>
        <polyline points={pts.join(' ')} fill="none" stroke="#6E837C" strokeWidth="1.6" />
        <line x1="16" y1="42" x2="264" y2="42" stroke={LIME} strokeWidth="1.2" className="vz-dash" opacity="0.7" />
        <circle cx="177" cy="58" r="4" fill={LIME} className="vz-pulse" />
        <line x1="177" y1="58" x2="177" y2="100" stroke={LIME} strokeWidth="1" strokeDasharray="2 3" opacity="0.6" />
        <text x="177" y="112" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="9" letterSpacing="1" fill={LIME}>SERVICE</text>
        <text x="20" y="34" fontFamily="var(--font-mono)" fontSize="9" letterSpacing="1.2" fill={DIM}>FAILURE THRESHOLD</text>
      </svg>
    );
  }

  if (kind === 'imagine') {
    // invitation: a dashed placeholder node with a glowing "+" and orbiting dots
    const cx = 140, cy = 62;
    const orbit = Array.from({ length: 6 }, (_, i) => {
      const a = (i / 6) * Math.PI * 2;
      return [cx + 64 * Math.cos(a) * 1.0, cy + 38 * Math.sin(a)];
    });
    return (
      <svg {...common}>
        {orbit.map(([x, y], i) => (
          <circle key={i} cx={x} cy={y} r="2.4" fill={DIM} className={`vz-pulse d${i % 4}`} />
        ))}
        <circle cx={cx} cy={cy} r="26" fill="none" stroke={DIM} strokeWidth="1.4" strokeDasharray="4 6" className="vz-sweep" style={{ transformOrigin: `${cx}px ${cy}px` }} />
        <circle cx={cx} cy={cy} r="15" fill="none" stroke={LIME} strokeWidth="1.5" opacity="0.5" className="vz-pulse" />
        <line x1={cx - 8} y1={cy} x2={cx + 8} y2={cy} stroke={LIME} strokeWidth="2" strokeLinecap="round" />
        <line x1={cx} y1={cy - 8} x2={cx} y2={cy + 8} stroke={LIME} strokeWidth="2" strokeLinecap="round" />
      </svg>
    );
  }

  // portal: 8 outer nodes consolidate into one central node
  const N = 8, cx = 140, cy = 62, R = 46;
  const nodes = Array.from({ length: N }, (_, i) => {
    const a = (i / N) * Math.PI * 2 - Math.PI / 2;
    return [cx + R * Math.cos(a) * 1.7, cy + R * Math.sin(a)];
  });
  return (
    <svg {...common}>
      {nodes.map(([x, y], i) => (
        <line key={'l' + i} x1={x} y1={y} x2={cx} y2={cy} stroke={FAINT} strokeWidth="1.2" className="vz-dash" style={{ animationDelay: `${i * 0.1}s` }} />
      ))}
      {nodes.map(([x, y], i) => (
        <circle key={'n' + i} cx={x} cy={y} r="3" fill={DIM} className={`vz-pulse d${i % 4}`} />
      ))}
      <circle cx={cx} cy={cy} r="8" fill="none" stroke={LIME} strokeWidth="1.5" opacity="0.5" />
      <circle cx={cx} cy={cy} r="5" fill={LIME} />
    </svg>
  );
}

// ── Coverflow transforms by offset from active ────────────────────
const CC_CONF = [
  { x: 0, rz: 0, z: 0, s: 1, o: 1 },
  { x: 60, rz: 26, z: -150, s: 0.84, o: 0.6 },
  { x: 112, rz: 30, z: -340, s: 0.66, o: 0.24 },
  { x: 150, rz: 32, z: -520, s: 0.5, o: 0 },
];
function cardStyle(offset) {
  const abs = Math.min(Math.abs(offset), 3);
  const dir = Math.sign(offset);
  const c = CC_CONF[abs];
  return {
    transform: `translateX(${dir * c.x}%) translateZ(${c.z}px) rotateY(${-dir * c.rz}deg) scale(${c.s})`,
    opacity: c.o,
    zIndex: 50 - abs,
  };
}

function CasesPage({ setRoute, openCase }) {
  const cases = (NGC && NGC.casesIndex) || [];
  const [active, setActive] = cS(0);
  const [playing, setPlaying] = cS(false);
  const n = cases.length;
  const drag = cR({ down: false, x: 0, moved: false });
  const wheelLock = cR(false);
  const railRef = cR(null);

  const go = cCB((dir) => setActive((a) => Math.max(0, Math.min(n - 1, a + dir))), [n]);
  const jump = cCB((i) => setActive(Math.max(0, Math.min(n - 1, i))), [n]);

  // keyboard
  cE(() => {
    const onKey = (e) => {
      if (e.key === 'ArrowRight') { go(1); setPlaying(false); }
      else if (e.key === 'ArrowLeft') { go(-1); setPlaying(false); }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [go]);

  // autoplay
  cE(() => {
    if (!playing) return;
    const id = setInterval(() => {
      setActive((a) => (a + 1) % n);
    }, 6000);
    return () => clearInterval(id);
  }, [playing, n]);

  // keep active thumbnail visible in the rail
  cE(() => {
    const rail = railRef.current;
    if (!rail) return;
    const el = rail.children[active];
    if (el) {
      const target = el.offsetLeft - rail.clientWidth / 2 + el.clientWidth / 2;
      rail.scrollTo({ left: target, behavior: 'smooth' });
    }
  }, [active]);

  // wheel (horizontal-ish) with cooldown
  const onWheel = (e) => {
    const d = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? e.deltaX : e.deltaY;
    if (Math.abs(d) < 14 || wheelLock.current) return;
    wheelLock.current = true;
    setPlaying(false);
    go(d > 0 ? 1 : -1);
    setTimeout(() => { wheelLock.current = false; }, 480);
  };

  // pointer drag (threshold step)
  const onDown = (e) => { drag.current = { down: true, x: e.clientX, moved: false }; };
  const onMove = (e) => {
    const d = drag.current;
    if (!d.down || d.moved) return;
    const dx = e.clientX - d.x;
    if (Math.abs(dx) > 56) { d.moved = true; setPlaying(false); go(dx < 0 ? 1 : -1); }
  };
  const onUp = () => { drag.current.down = false; };

  const ac = cases[active] || {};

  return (
    <div className="page-enter cases-page cases-enter">
      <section className="cases-hero">
        <SubpageMesh side="right" size="md" />
        <div className="container">
          <span className="eyebrow">{tr('Case index')} · {tr('Selected engagements')}</span>
          <h1>{tr('Operations,')} <em className="serif-em" style={{ color: 'var(--ng-lime-ink)' }}>{tr('in production.')}</em></h1>
          <p className="lede big" style={{ maxWidth: '52ch' }}>
            {tr('Selected engagements where hyper-automation, Agentic AI and custom software were designed into the operation together — not bought as separate workstreams. Drag, scroll or use the arrows to move through the work.')}
          </p>
          <div className="idx-stats">
            <div><b>04</b>{tr('Live engagements')}</div>
            <div><b>02</b>{tr('Continents served')}</div>
            <div><b><em>∞</em></b>{tr('Yours to imagine')}</div>
          </div>
        </div>
      </section>

      <div className="container">
        <div
          className="cc-stage"
          onWheel={onWheel}
          onPointerDown={onDown}
          onPointerMove={onMove}
          onPointerUp={onUp}
          onPointerLeave={onUp}
          onMouseEnter={() => { if (playing) setPlaying(false); }}
        >
          <div className="cc-track">
            {cases.map((c, i) => {
              const offset = i - active;
              const isActive = i === active;
              const hidden = Math.abs(offset) > 2;
              return (
                <article
                  key={c.id}
                  className={'cc-card' + (isActive ? ' is-active' : ' is-side') + (hidden ? ' is-hidden' : '')}
                  style={cardStyle(offset)}
                  onClick={() => { if (drag.current.moved) return; setPlaying(false); if (isActive) { c.invite ? setRoute('book') : (openCase && openCase(c.id)); } else { jump(i); } }}
                >
                  <div className="cc-card-inner">
                    <div className="cc-viz">
                      <div className="grid" />
                      <CaseMiniViz kind={c.viz} labels={c.vizLabels} />
                      <span className="num-badge">{tr('CASE')} {c.num}</span>
                      <span className="yr-badge">{c.loc}</span>
                    </div>
                    <div className="cc-body">
                      <div className="cc-tag">{c.tag}</div>
                      <div className="cc-client">{c.client} · {c.sector} · {c.region}</div>
                      <h3 className="cc-title">{c.titleA}<em>{c.titleEm}</em>{c.titleB}</h3>
                      <p className="cc-summary">{c.summary}</p>
                      <div className="cc-foot">
                        <div className="cc-metrics">
                          {c.metrics.map((m, j) => (
                            <div key={j}>
                              <div className="v">{m.v}</div>
                              <div className="k">{m.k}</div>
                            </div>
                          ))}
                        </div>
                        <button className="cc-cta" onClick={(e) => { e.stopPropagation(); setPlaying(false); c.invite ? setRoute('book') : (openCase && openCase(c.id)); }}>
                          <span className="ln" />{c.invite ? tr('Start a conversation') : tr('Read the full case study')}
                        </button>
                      </div>
                    </div>
                  </div>
                </article>
              );
            })}
          </div>
        </div>

        <div className="cc-controls">
          <div className="cc-arrows">
            <button className="cc-arrow" aria-label="Previous case" onClick={() => { setPlaying(false); go(-1); }} disabled={active === 0}><CcChevL /></button>
            <button className="cc-arrow" aria-label="Next case" onClick={() => { setPlaying(false); go(1); }} disabled={active === n - 1}><CcChevR /></button>
          </div>
          <div className="cc-counter">{String(active + 1).padStart(2, '0')} <span>/ {String(n).padStart(2, '0')}</span></div>
          <button className={'cc-playbtn' + (playing ? ' is-playing' : '')} onClick={() => setPlaying((p) => !p)}>
            <span className="dot" />{playing ? tr('Auto-play on') : tr('Auto-play')}
          </button>
        </div>

        <div className="cc-rail" ref={railRef}>
          {cases.map((c, i) => (
            <button
              key={c.id}
              className={'cc-thumb' + (i === active ? ' is-active' : '') + (i === active && playing ? ' is-progressing' : '')}
              style={{ '--cc-dur': '6s' }}
              onClick={() => { setPlaying(false); jump(i); }}
            >
              <div className="t-num">{c.num} · {c.sector}</div>
              <div className="t-title">{c.titleA}{c.titleEm}{c.titleB}</div>
              <span className="t-bar" />
            </button>
          ))}
        </div>
      </div>

      <FinalCTA />
    </div>
  );
}

Object.assign(window, { CasesPage });
