// ============================================================
// SECTIONS v2 — pinned scrollytelling + kinetic typography
// ============================================================

// Kinetic text helper — splits a string into per-char spans driven by --ep
function KineticText({ text, mode = 'char', className = '', stagger = 0.012, italic = false }) {
  const html = React.useMemo(() => window.splitText(text, mode), [text, mode]);
  return (
    <span
      className={"kinetic " + className}
      style={{ '--stagger': stagger, fontStyle: italic ? 'italic' : 'normal' }}
      dangerouslySetInnerHTML={{ __html: html }}
    />
  );
}

// Phase indicator removed — the section-tag + scroll already communicate progress.

// React hook to read live --p from a pin-frame
function usePinProgress(frameRef) {
  const [p, setP] = React.useState(0);
  React.useEffect(() => {
    const el = frameRef.current;
    if (!el) return;
    let raf;
    const read = () => {
      const v = parseFloat(el.style.getPropertyValue('--p') || '0');
      setP(v);
      raf = requestAnimationFrame(read);
    };
    raf = requestAnimationFrame(read);
    return () => cancelAnimationFrame(raf);
  }, []);
  return p;
}

// Dynamic availability — today + 14 days, formatted like "AUG 12"
function useAvailability() {
  return React.useMemo(() => {
    const d = new Date();
    d.setDate(d.getDate() + 14);
    return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }).toUpperCase();
  }, []);
}

// ──────────────────────────────────────────────────────────
// 01 IDENTITY  (cinematic 3-act — layer-stacked phases)
// ──────────────────────────────────────────────────────────
function Identity() {
  const frameRef = React.useRef(null);
  const availability = useAvailability();

  return (
    <section id="identity" className="pin-wrap pin-identity" data-pin="3" data-screen-label="01 Identity">
      <div className="pin-frame" ref={frameRef}>
        <div className="pin-stage stage-layered">

          {/* PHASE A — name on land */}
          <div className="phase" data-anim data-from="-0.30" data-to="0.36">
            <div className="hero-meta">
              <span className="pill glass">Singapore → Global</span>
              <span className="sep"></span>
              <span>Principal · Cloud &amp; AI Architect</span>
              <span className="sep"></span>
              <span className="accent">● Booking from {availability}</span>
            </div>
            <h1 className="kx-name">
              <span className="row">
                <KineticText text="Mayer" stagger={0.018} />
              </span>
              <span className="row italic">
                <KineticText text="Putra." stagger={0.018} italic />
              </span>
            </h1>
            <p className="kx-byline">
              <span>cloud architect</span>
              <span className="dot"></span>
              <span>ai engineer</span>
              <span className="dot"></span>
              <span>venture principal</span>
            </p>
          </div>

          {/* PHASE B — doctrine */}
          <div className="phase" data-anim data-from="0.30" data-to="0.62">
            <p className="kx-doctrine">
              <KineticText
                text="Big Six pedigree. Enterprise cloud architecture, agentic AI systems, and venture infrastructure — engineered end-to-end for institutions that can't afford to fail."
                mode="word"
                stagger={0.012}
              />
            </p>
          </div>

          {/* PHASE C — creed + delivered metrics */}
          <div className="phase" data-anim data-from="0.58" data-to="1.05">
            <div className="kx-creed">
              Built on raw conviction. <em>An evolution of pure grit.</em>
            </div>
            <div className="identity-statline">
              <div className="stat glass">
                <div className="num">99.5<small>% SLA</small></div>
                <div className="lbl">IBM Service Tier</div>
              </div>
              <div className="stat glass">
                <div className="num">↓85<small>%</small></div>
                <div className="lbl">Manual Overhead</div>
              </div>
              <div className="stat glass">
                <div className="num">↓25<small>%</small></div>
                <div className="lbl">Azure Spend</div>
              </div>
              <div className="stat glass">
                <div className="num">24<small>/7</small></div>
                <div className="lbl">Agentic Coverage</div>
              </div>
            </div>
          </div>

        </div>
      </div>
    </section>
  );
}

// ──────────────────────────────────────────────────────────
// 02 INFRASTRUCTURE  (pinned, scroll-assembling cluster)
// ──────────────────────────────────────────────────────────
function ClusterDiagramPin({ progress }) {
  const nodes = [
    { id: 'edge1', x: 12, y: 18 },
    { id: 'edge2', x: 12, y: 50 },
    { id: 'edge3', x: 12, y: 82 },
    { id: 'gw1',   x: 38, y: 28, gateway: true },
    { id: 'gw2',   x: 38, y: 72, gateway: true },
    { id: 'core',  x: 64, y: 50, core: true },
    { id: 'svc1',  x: 88, y: 22 },
    { id: 'svc2',  x: 88, y: 50 },
    { id: 'svc3',  x: 88, y: 78 },
  ];
  const edges = [
    ['edge1','gw1'], ['edge2','gw1'], ['edge2','gw2'], ['edge3','gw2'],
    ['gw1','core'], ['gw2','core'],
    ['core','svc1'], ['core','svc2'], ['core','svc3'],
  ];
  const idx = Object.fromEntries(nodes.map((n,i)=>[n.id,i]));

  // node reveal order, mapped to overall progress range
  const order = ['edge1','edge2','edge3','gw1','gw2','core','svc1','svc2','svc3'];
  // Assembly happens within section progress 0.15..0.70
  const assemblyFrom = 0.15, assemblyTo = 0.70;
  const local = Math.max(0, Math.min(1, (progress - assemblyFrom) / (assemblyTo - assemblyFrom)));
  const nodeT = (id) => Math.max(0, Math.min(1, (local - order.indexOf(id) / order.length) * 6));

  return (
    <div className="cluster-wrap">
      <span className="cluster-label glass tl">CLUSTER · AP-SOUTHEAST</span>
      <span className="cluster-label glass tr">● LIVE</span>
      <span className="cluster-label glass bl">9 NODES</span>
      <span className="cluster-label glass br">{Math.round(local * 100)}% SYNC</span>

      <svg className="cluster-svg" viewBox="0 0 100 100" preserveAspectRatio="none">
        {/* edges */}
        {edges.map(([a, b], i) => {
          const na = nodes[idx[a]], nb = nodes[idx[b]];
          const t = nodeT(a);
          return (
            <line key={i}
              x1={na.x} y1={na.y} x2={nb.x} y2={nb.y}
              stroke="var(--accent)" strokeWidth="0.18"
              strokeOpacity={0.45 * t}
              strokeDasharray={`${t * 100} 100`}
              vectorEffect="non-scaling-stroke"
            />
          );
        })}

        {/* nodes */}
        {nodes.map((n) => {
          const t = nodeT(n.id);
          const r = n.core ? 1.7 : n.gateway ? 1.2 : 0.9;
          const ringR = n.core ? 3.6 : 2.2;
          return (
            <g key={n.id} style={{ opacity: t }}>
              <circle cx={n.x} cy={n.y} r={r * t} fill="var(--accent)" />
              <circle cx={n.x} cy={n.y} r={ringR}
                fill="none" stroke="var(--accent)" strokeWidth="0.12"
                strokeOpacity={0.6 * t}
                vectorEffect="non-scaling-stroke" />
              {n.core && t > 0.5 && (
                <circle cx={n.x} cy={n.y} r={5.8}
                  fill="none" stroke="var(--accent)" strokeWidth="0.08"
                  strokeOpacity={(t - 0.5) * 0.4}
                  vectorEffect="non-scaling-stroke">
                  <animate attributeName="r" values="5.6;7;5.6" dur="3s" repeatCount="indefinite" />
                </circle>
              )}
            </g>
          );
        })}

        {/* data packets (only after assembly mostly done) */}
        {local > 0.85 && edges.map(([a,b], i) => {
          const na = nodes[idx[a]], nb = nodes[idx[b]];
          return (
            <circle key={'p'+i} r="0.5" fill="var(--accent)" opacity="0.95">
              <animate attributeName="cx" values={`${na.x};${nb.x}`} dur={`${1.6 + i * 0.18}s`} repeatCount="indefinite" />
              <animate attributeName="cy" values={`${na.y};${nb.y}`} dur={`${1.6 + i * 0.18}s`} repeatCount="indefinite" />
              <animate attributeName="opacity" values="0;1;1;0" dur={`${1.6 + i * 0.18}s`} repeatCount="indefinite" />
            </circle>
          );
        })}
      </svg>
    </div>
  );
}

function Infrastructure() {
  const frameRef = React.useRef(null);
  const p = usePinProgress(frameRef);

  const rows = [
    { idx: '01', label: 'Solutions Architect Expert',    meta: 'AZURE' },
    { idx: '02', label: 'DevOps Engineer Expert',         meta: 'CI/CD · IaC' },
    { idx: '03', label: 'Cloud Cost Optimisation',        meta: '↓25% SPEND' },
    { idx: '04', label: 'End-to-End Security Compliance', meta: '100% AUDIT' },
    { idx: '05', label: 'Process Orchestration · RPA',    meta: 'ENTERPRISE' },
    { idx: '06', label: 'IBM Service Tier · 99.5% SLA',   meta: 'OPERATIONAL' },
  ];

  return (
    <section id="infrastructure" className="pin-wrap pin-infra" data-pin="3" data-screen-label="02 Infrastructure">
      <div className="pin-frame" ref={frameRef}>
        <div className="pin-stage">

          <div className="infra-left stage-layered">

            {/* PHASE A — declaration */}
            <div className="phase" data-anim data-from="-0.30" data-to="0.50">
              <div className="section-tag">
                <span className="section-index">02</span>
                <span>Cloud Architecture</span>
              </div>
              <h2 className="infra-head">
                Infrastructure that <em>compounds</em>,<br />
                not collapses.
              </h2>
              <p className="infra-lede">
                End-to-end cloud architecture engineered for scale —
                multi-region orchestration, hardened security postures,
                and cost surfaces that shrink as workload grows.
              </p>
            </div>

            {/* PHASE B — capability list */}
            <div className="phase" data-anim data-from="0.45" data-to="1.05">
              <div className="section-tag soft">
                <span className="section-index">02</span>
                <span>Capabilities</span>
              </div>
              <ul className="infra-list-pin">
                {rows.map((r) => (
                  <li className="infra-row glass" key={r.idx}>
                    <span className="idx">{r.idx}</span>
                    <span className="label">{r.label}</span>
                    <span className="meta">{r.meta}</span>
                  </li>
                ))}
              </ul>
            </div>

          </div>

          <div className="infra-right">
            <ClusterDiagramPin progress={p} />
          </div>

        </div>
      </div>
    </section>
  );
}

// ──────────────────────────────────────────────────────────
// 03 INTELLIGENCE  (pinned, neural activates over scroll)
// ──────────────────────────────────────────────────────────
function NeuralPanelPin({ progress }) {
  const layers = [4, 6, 6, 3];
  const W = 100, H = 122;
  const padX = 14, padY = 22;
  const layerX = (li) => padX + (li * (W - padX * 2)) / (layers.length - 1);
  const nodeY = (li, ni) => {
    const n = layers[li];
    const span = H - padY * 2;
    return padY + (n === 1 ? span / 2 : (ni * span) / (n - 1));
  };

  // Each layer activates within a sub-range of progress
  const layerT = (li) => {
    const from = 0.20 + li * 0.18;
    const to = from + 0.20;
    return Math.max(0, Math.min(1, (progress - from) / (to - from)));
  };

  // Pulsing activations (animated locally, no time-based dependency)
  const [activations, setActivations] = React.useState(() => layers.map(n => Array(n).fill(0.5)));
  React.useEffect(() => {
    let raf;
    const tick = () => {
      const t = performance.now() / 1000;
      setActivations(layers.map((n, li) =>
        Array.from({ length: n }, (_, i) =>
          0.4 + 0.6 * (0.5 + 0.5 * Math.sin(t * (1.0 + li * 0.25) + i * 1.7))
        )
      ));
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  return (
    <div className="neural-panel-pin">
      <div className="corner-label glass">
        <span className="dot"></span>
        AGENTIC RUNTIME
      </div>
      <div className="corner-label glass right">INFERENCE · 12ms</div>

      <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="xMidYMid meet">
        {layers.slice(0,-1).map((n, li) => {
          const tA = layerT(li);
          const tB = layerT(li+1);
          const visible = Math.min(tA, tB);
          if (visible <= 0) return null;
          return Array.from({ length: n }).map((_, i) =>
            Array.from({ length: layers[li+1] }).map((__, j) => {
              const a = activations[li]?.[i] ?? 0.5;
              const b = activations[li+1]?.[j] ?? 0.5;
              const w = a * b;
              return (
                <line key={`${li}-${i}-${j}`}
                  x1={layerX(li)} y1={nodeY(li,i)}
                  x2={layerX(li+1)} y2={nodeY(li+1,j)}
                  stroke="var(--accent)"
                  strokeOpacity={(0.08 + w * 0.4) * visible}
                  strokeWidth="0.18"
                  vectorEffect="non-scaling-stroke"
                />
              );
            })
          );
        })}
        {layers.map((n, li) => {
          const t = layerT(li);
          if (t <= 0) return null;
          return Array.from({ length: n }).map((_, i) => {
            const a = activations[li]?.[i] ?? 0.5;
            return (
              <g key={`n-${li}-${i}`} style={{ opacity: t }}>
                <circle cx={layerX(li)} cy={nodeY(li,i)} r={2.4}
                  fill="var(--bg-1)" stroke="var(--accent)" strokeWidth="0.2"
                  vectorEffect="non-scaling-stroke" />
                <circle cx={layerX(li)} cy={nodeY(li,i)} r={1.4 * a}
                  fill="var(--accent)" opacity={0.5 + a * 0.5} />
              </g>
            );
          });
        })}
        {['INPUT','HIDDEN','HIDDEN','OUTPUT'].map((lbl, li) => {
          const t = layerT(li);
          return (
            <text key={lbl + li} x={layerX(li)} y={H - 4}
              fontSize="2.4" fill="var(--fg-mute)" textAnchor="middle"
              fontFamily="var(--f-mono)" letterSpacing="0.4" opacity={t}>
              {lbl}
            </text>
          );
        })}
      </svg>

      <div className="readout">
        <span>MODEL · MX-7 AGENTIC</span>
        <span className="v">● ACTIVE</span>
      </div>
    </div>
  );
}

function Intelligence() {
  const frameRef = React.useRef(null);
  const p = usePinProgress(frameRef);

  const certs = [
    { badge: 'A1', title: 'Fabric Analytics Engineer', sub: 'DATA · AI' },
    { badge: 'A2', title: 'Azure Data Engineer',       sub: 'ETL · SYNAPSE' },
    { badge: 'A3', title: 'Agentic AI Engineer',       sub: 'ORCHESTRATION' },
    { badge: 'A4', title: 'AI-Roadmap Design',         sub: 'C-SUITE ADVISORY' },
    { badge: 'A5', title: 'Venture Architecture',      sub: 'PRINCIPAL' },
    { badge: 'A6', title: 'Process Orchestration · RPA', sub: 'ENTERPRISE' },
  ];

  return (
    <section id="intelligence" className="pin-wrap pin-intel" data-pin="3" data-screen-label="03 Intelligence">
      <div className="pin-frame" ref={frameRef}>
        <div className="pin-stage">

          <div className="intel-left stage-layered">

            {/* PHASE A — declaration */}
            <div className="phase" data-anim data-from="-0.30" data-to="0.50">
              <div className="section-tag">
                <span className="section-index">03</span>
                <span>AI / Neural Systems</span>
              </div>
              <h2 className="intel-head">
                Intelligence as <em>infrastructure</em>.
              </h2>
              <p className="intel-lede">
                Agentic AI funnels, social &amp; e-commerce automation, healthcare
                availability at 24/7 — designed not as features bolted on, but as
                a substrate the business runs on.
              </p>
            </div>

            {/* PHASE B — credentials */}
            <div className="phase" data-anim data-from="0.45" data-to="1.05">
              <div className="section-tag soft">
                <span className="section-index">03</span>
                <span>Credentialed</span>
              </div>
              <div className="cert-grid-pin">
                {certs.map((c) => (
                  <div className="cert-cell glass" key={c.badge}>
                    <div className="badge">{c.badge}</div>
                    <div className="title">{c.title}</div>
                    <div className="sub">{c.sub}</div>
                  </div>
                ))}
              </div>
            </div>

          </div>

          <div className="intel-right">
            <NeuralPanelPin progress={p} />
          </div>

        </div>
      </div>
    </section>
  );
}

// ──────────────────────────────────────────────────────────
// 04 HORIZON  (normal scroll)
// ──────────────────────────────────────────────────────────
function Horizon() {
  const cells = [
    { delta: '↓85', unit: '%', what: 'Manual operations overhead, replaced by AI-powered growth engines.', tag: 'OPERATIONS' },
    { delta: '↓25', unit: '%', what: 'Azure spend, recovered through cost optimisation surfaces.',         tag: 'CLOUD COST' },
    { delta: '100', unit: '%', what: 'Audit pass — end-to-end security &amp; compliance posture.',         tag: 'GOVERNANCE' },
    { delta: '∞',  unit: '',  what: 'Strategic partnerships powering the business with AI.',              tag: 'ECOSYSTEM' },
  ];
  return (
    <section id="horizon" className="section" data-screen-label="04 Horizon">
      <div className="section-tag reveal">
        <span className="section-index">04</span>
        <span>Emergent Frontiers</span>
      </div>
      <h2 className="horizon-headline reveal" data-d="1">
        Anticipated <em>horizons</em>.<br />
        Intelligence ascendant, human becoming.
      </h2>
      <p className="horizon-lede reveal" data-d="2">
        The metrics that follow are not projections. They are the deltas already
        delivered to ventures under private advisory.
      </p>
      <div className="horizon-grid reveal" data-d="3">
        {cells.map((c,i) => (
          <div className="horizon-cell glass" key={i}>
            <div className="delta">{c.delta}<small>{c.unit}</small></div>
            <div className="what" dangerouslySetInnerHTML={{ __html: c.what }}></div>
            <div className="tag">{c.tag}</div>
          </div>
        ))}
      </div>
      <div className="partners reveal" data-d="4">
        <span className="lbl">Ecosystem Access</span>
        <span className="partner glass">Microsoft Solutions Partner · AI Cloud</span>
        <span className="partner glass">TikTok MCN · Cross-Border E-commerce</span>
        <span className="partner glass">Google Account · Automation Scale</span>
        <span className="partner glass">IBM Service Excellence</span>
      </div>
    </section>
  );
}

// ──────────────────────────────────────────────────────────
// 05 CONTACT (normal scroll)
// ──────────────────────────────────────────────────────────
function Magnetic({ children, href }) {
  const ref = React.useRef(null);
  const onMove = (e) => {
    const el = ref.current;
    if (!el) return;
    const r = el.getBoundingClientRect();
    const x = e.clientX - (r.left + r.width / 2);
    const y = e.clientY - (r.top + r.height / 2);
    // Soft pull; the transition on the element does the easing.
    el.style.transform = `translate(${x * 0.22}px, ${y * 0.30}px)`;
  };
  const onLeave = () => { if (ref.current) ref.current.style.transform = ''; };
  return (
    <a ref={ref} className="magnet glass" href={href}
       onMouseMove={onMove} onMouseLeave={onLeave}
       data-magnetic="true">
      {children}
    </a>
  );
}

function Contact() {
  return (
    <section id="contact" className="contact" data-screen-label="05 Contact">
      <div className="contact-inner">
        <div className="contact-kicker reveal"><span>05 · Engage</span></div>
        <h2 className="contact-headline reveal" data-d="1">
          Shape the <em>horizon</em>.
        </h2>
        <div className="contact-pair reveal" data-d="2">
          Isolating the core friction.<br />
          Engineering the resolution.
        </div>
        <div className="reveal" data-d="3">
          <Magnetic href="mailto:hello@mayerputra.com">
            <span>hello@mayerputra.com</span>
            <span className="arrow"></span>
          </Magnetic>
        </div>
        <div className="contact-meta reveal" data-d="4">
          <div className="contact-card glass">
            <div className="col-h">Advisory</div>
            <div className="col-v">Principal AI Architect</div>
            <div className="col-sub">Private engagements only · select retainers</div>
          </div>
          <div className="contact-card glass">
            <div className="col-h">Locale</div>
            <div className="col-v">Singapore → Global</div>
            <div className="col-sub">Operating across Asia-Pacific, EMEA &amp; the Americas</div>
          </div>
          <div className="contact-card glass">
            <div className="col-h">Response</div>
            <div className="col-v">Within 48 hours</div>
            <div className="col-sub">NDA on first contact · discreet by design</div>
          </div>
        </div>
      </div>
    </section>
  );
}

window.Identity = Identity;
window.Infrastructure = Infrastructure;
window.Intelligence = Intelligence;
window.Horizon = Horizon;
window.Contact = Contact;
window.KineticText = KineticText;
