/* global React */
// ShowgazeProcess — scroll-triggered animated process section
// Usage: add <script type="text/babel" src="ShowgazeProcess.jsx"></script>
//        then use <ShowgazeProcess /> wherever it fits in the page

const { useState, useEffect, useRef } = React;

// Respect OS-level reduced-motion preference — checked once at parse time
const REDUCE_MOTION = typeof window !== 'undefined'
  && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

// ── Design tokens (mirrors Sections.jsx) ──────────────────────────────────────
const C = {
  bg: '#0B0C0E', bg1: '#141518', bg2: '#1A1C20',
  bone: '#E6DCCB', grey: '#8A8A86', mute: '#52524F',
  border: '#1F2024', borderHi: '#33353A',
  cyan: '#59A3B3', cyanHi: '#7EBFCD',
};
const F = {
  display: "'Playfair Display', Georgia, serif",
  sans:    "'IBM Plex Sans', system-ui, sans-serif",
  mono:    "'IBM Plex Mono', monospace",
};
const E = 'cubic-bezier(0.2,0.7,0.2,1)';

// ── Animation helper ───────────────────────────────────────────────────────────
// Returns opacity + translateY transition styles. Strips motion if user prefers it.
function anim(on, delay, dur = 400, dy = 16) {
  if (REDUCE_MOTION) {
    return { opacity: on ? 1 : 0, transition: `opacity 160ms ${E} ${delay}ms` };
  }
  return {
    opacity: on ? 1 : 0,
    transform: on ? 'none' : `translateY(${dy}px)`,
    transition: `opacity ${dur}ms ${E} ${delay}ms, transform ${dur}ms ${E} ${delay}ms`,
  };
}

// ── Pipeline step icons ────────────────────────────────────────────────────────
function ISync() {
  return (
    <svg width="14" height="12" viewBox="0 0 14 12" fill="none">
      <path d="M1 6H3L4.5 1.5L6.5 10.5L8.5 4.5L9.5 7.5L11 6H13" 
        stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round"/>
      <circle cx="7" cy="6" r="5" stroke="currentColor" strokeWidth="0.8" opacity="0.3" strokeDasharray="2 2"/>
    </svg>
  );
}
function IBars() {
  return (
    <svg width="14" height="13" viewBox="0 0 14 13" fill="none">
      <rect x="1" y="8" width="2" height="4" rx="0.5" fill="currentColor" opacity="0.4"/>
      <rect x="4" y="5" width="2" height="7" rx="0.5" fill="currentColor" opacity="0.6"/>
      <rect x="7" y="2" width="2" height="10" rx="0.5" fill="currentColor" opacity="0.8"/>
      <rect x="10" y="6" width="2" height="6" rx="0.5" fill="currentColor"/>
      <path d="M1 12H13" stroke="currentColor" strokeWidth="0.8" opacity="0.3"/>
    </svg>
  );
}
function INodes() {
  return (
    <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
      <circle cx="7" cy="3" r="1.5" stroke="currentColor" strokeWidth="1"/>
      <circle cx="3" cy="11" r="1.5" stroke="currentColor" strokeWidth="1"/>
      <circle cx="11" cy="11" r="1.5" stroke="currentColor" strokeWidth="1"/>
      <path d="M7 4.5V7L4.5 9.5M7 7L9.5 9.5" stroke="currentColor" strokeWidth="0.8" strokeLinecap="round" opacity="0.6"/>
      <circle cx="7" cy="7" r="0.8" fill="currentColor" opacity="0.4"/>
    </svg>
  );
}
function IFace() {
  return (
    <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
      <path d="M1 4V1H4M10 1H13V4M13 10V13H10M4 13H1V10" stroke="currentColor" strokeWidth="1" strokeLinecap="round"/>
      <path d="M7 3.5C5.5 3.5 4 4.5 4 6.5C4 8.5 5.5 10.5 7 10.5C8.5 10.5 10 8.5 10 6.5C10 4.5 8.5 3.5 7 3.5Z" 
        stroke="currentColor" strokeWidth="1" opacity="0.8"/>
      <circle cx="5.5" cy="6" r="0.6" fill="currentColor"/>
      <circle cx="8.5" cy="6" r="0.6" fill="currentColor"/>
      <path d="M5.5 8.5C6 9 8 9 8.5 8.5" stroke="currentColor" strokeWidth="0.8" strokeLinecap="round"/>
    </svg>
  );
}
function IShield() {
  return (
    <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
      <path d="M7 1L12.5 3.2V7.5C12.5 10.5 10.5 12.8 7 13.5C3.5 12.8 1.5 10.5 1.5 7.5V3.2L7 1Z" 
        stroke="currentColor" strokeWidth="1.2" fill="none"/>
      <path d="M4.5 7L6 8.5L9.5 5" stroke="currentColor" strokeWidth="1" strokeLinecap="round" strokeLinejoin="round" opacity="0.6"/>
    </svg>
  );
}
function ICheck() {
  return (
    <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
      <circle cx="7" cy="7" r="6" stroke="currentColor" strokeWidth="1.2"/>
      <path d="M4 7.5L6 9.5L10 5.5" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}


// ── Viewfinder corner brackets (matches site's Corner component style) ─────────
function Corners() {
  const b = '1px solid rgba(89,163,179,0.2)';
  const s = { position: 'absolute', width: 9, height: 9 };
  return (
    <React.Fragment>
      <div style={{ ...s, top: 7, left: 7,   borderTop: b, borderLeft: b   }} />
      <div style={{ ...s, top: 7, right: 7,  borderTop: b, borderRight: b  }} />
      <div style={{ ...s, bottom: 7, left: 7,  borderBottom: b, borderLeft: b  }} />
      <div style={{ ...s, bottom: 7, right: 7, borderBottom: b, borderRight: b }} />
    </React.Fragment>
  );
}

// ── Connecting arrow between phases ───────────────────────────────────────────
// marginTop: 54 aligns the arrow with the card top.
// Phase header = num(~14px) + label(~17px) + desc(~17px) + margins(~6px) ≈ 54px.
// If the header layout changes, adjust this value to match.
function Arrow({ on, delay }) {
  return (
    <div style={{
      flexShrink: 0,
      width: 28,
      marginTop: 54,
      display: 'flex',
      alignItems: 'center',
      opacity: on ? 1 : 0,
      transform: on ? 'scaleX(1)' : 'scaleX(0)',
      transformOrigin: 'left center',
      transition: `opacity 260ms ${E} ${delay}ms, transform 260ms ${E} ${delay}ms`,
    }}>
      <div style={{ flex: 1, height: 1, background: `${C.cyan}88` }} />
      <svg width="7" height="9" viewBox="0 0 7 9" fill="none" style={{ flexShrink: 0 }}>
        <path d="M0 0.5 L6.5 4.5 L0 8.5Z" fill={C.cyan} fillOpacity="0.7"/>
      </svg>
    </div>
  );
}

// ── Phase 1: Filming ───────────────────────────────────────────────────────────
function CardFilming({ on }) {
  return (
    <div style={{ padding: '10px 4px', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14 }}>
      <svg width="148" height="100" viewBox="0 0 148 100" fill="none"
        style={{ display: 'block', ...anim(on, 160, 520, 6) }}>
        {/* Stage light beams — [x1, x2, y2]; y1 is always 0 */}
        {[[22,36,27],[50,52,27],[82,64,27],[110,78,27],[130,90,27]].map(([x1,x2,y2], i) => (
          <line key={i} x1={x1} y1={0} x2={x2} y2={y2}
            stroke={C.mute} strokeWidth="0.7" opacity="0.38"/>
        ))}
        {/* Stage platform */}
        <rect x="8" y="27" width="132" height="2" rx="1" fill={C.mute} opacity="0.4"/>
        {/* Band silhouettes — three shapes */}
        {[[36,18,5,5],[74,16,5.5,6.5],[112,18,5,5]].map(([cx,cy,rx,ry], i) => (
          <g key={i} opacity={0.32 + i * 0.04}>
            <ellipse cx={cx} cy={cy} rx={rx} ry={ry} fill={C.mute}/>
            <rect x={cx - rx + 1} y={23} width={(rx - 1) * 2} height={9} rx="1" fill={C.mute} opacity="0.8"/>
          </g>
        ))}
        {/* Crowd — row 1 */}
        {[9,22,35,48,61,74,87,100,113,126,138].map((x, i) => (
          <ellipse key={i} cx={x} cy={42} rx={5.5} ry={6.5}
            fill={i % 3 === 1 ? C.borderHi : C.border} opacity="0.95"/>
        ))}
        {/* Crowd — row 2 */}
        {[15,28,41,54,67,80,93,106,119,132].map((x, i) => (
          <ellipse key={i} cx={x} cy={56} rx={6} ry={7}
            fill={C.border} opacity="0.85"/>
        ))}
        {/* Three highlighted phones */}
        {[[28,34],[74,32],[120,34]].map(([cx, cy], i) => (
          <g key={i}>
            <rect x={cx - 5} y={cy} width={10} height={14} rx="1.5"
              stroke={C.cyan} strokeWidth="1.3" fill={C.bg2}/>
            <rect x={cx - 3.5} y={cy + 2} width={7} height={9} rx="0.5" fill={C.bg}/>
            {/* recording dot */}
            <circle cx={cx} cy={cy - 1.5} r="1.6" fill={C.cyan} opacity="0.85"/>
          </g>
        ))}
        {/* Dashed lines converging to a point */}
        <path d="M28 48 Q28 78 74 90" stroke={C.cyan} strokeWidth="0.9"
          strokeDasharray="4 3" opacity="0.28"/>
        <line x1="74" y1="46" x2="74" y2="90"
          stroke={C.cyan} strokeWidth="0.9" strokeDasharray="4 3" opacity="0.28"/>
        <path d="M120 48 Q120 78 74 90" stroke={C.cyan} strokeWidth="0.9"
          strokeDasharray="4 3" opacity="0.28"/>
        <circle cx="74" cy="90" r="3.5" fill={C.cyan} opacity="0.25"/>
        <circle cx="74" cy="90" r="1.8" fill={C.cyan} opacity="0.55"/>
      </svg>
      <p style={{
        fontFamily: F.mono, fontSize: 10, color: C.grey,
        textAlign: 'center', lineHeight: 1.65, margin: 0,
        ...anim(on, 360, 360),
      }}>
        Multiple angles,<br/>captured simultaneously
      </p>
    </div>
  );
}

// ── Phase 2: Capture & Send ────────────────────────────────────────────────────
function CardCapture({ on }) {
  const items = [
    { sym: '↑', label: 'Footage Uploads',     sub: 'Via QR code' },
    { sym: '◈', label: 'Dropbox File Request', sub: 'Organised folder' },
    { sym: '≋', label: 'Reference Audio',      sub: 'Sound desk feed' },
  ];
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      {items.map((it, i) => (
        <div key={i} style={{
          display: 'flex', alignItems: 'center', gap: 10,
          padding: '8px 10px',
          background: C.bg, borderRadius: 4, border: `1px solid ${C.border}`,
          ...anim(on, 120 + i * 100),
        }}>
          <div style={{
            width: 26, height: 26, borderRadius: 3, flexShrink: 0,
            background: 'rgba(89,163,179,0.07)', border: '1px solid rgba(89,163,179,0.18)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: C.cyan, fontFamily: F.mono, fontSize: 14,
          }}>
            {it.sym}
          </div>
          <div>
            <div style={{ fontFamily: F.sans, fontSize: 12, color: C.bone, lineHeight: 1.3 }}>{it.label}</div>
            <div style={{ fontFamily: F.mono, fontSize: 10, color: C.mute, marginTop: 2 }}>{it.sub}</div>
          </div>
        </div>
      ))}
    </div>
  );
}

// ── Phase 3: Processing & QC ───────────────────────────────────────────────────
function CardProcessing({ cardOn, pipeOn }) {
  const steps = [
    { label: 'Sync',            sub: null,             Icon: ISync   },
    { label: 'Audio analysis',  sub: null,             Icon: IBars   },
    { label: 'CV',              sub: 'Computer Vision', Icon: INodes  },
    { label: 'Face tracking',   sub: 'Reframing',      Icon: IFace   },
    { label: 'NSFW filter',     sub: null,             Icon: IShield },
    { label: 'Quality control', sub: null,             Icon: ICheck  },
  ];
  return (
    <div>
      <p style={{
        fontFamily: F.mono, fontSize: 9, letterSpacing: '0.12em', textTransform: 'uppercase',
        color: C.grey, margin: '0 0 8px',
        ...anim(cardOn, 80, 300),
      }}>
        Automated
      </p>
      <div style={{ position: 'relative' }}>
        {/* Vertical guide line */}
        <div style={{
          position: 'absolute', left: 12, top: 14, bottom: 14, width: 1,
          background: `linear-gradient(to bottom, ${C.cyan}44, transparent)`,
          opacity: pipeOn ? 1 : 0,
          transition: `opacity 600ms ${E} 80ms`,
        }} />
        <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
          {steps.map((step, i) => (
            <div key={i} style={{
              display: 'flex', alignItems: 'center', gap: 9,
              padding: '5px 8px', borderRadius: 3,
              background: 'rgba(26,28,32,0.8)', border: `1px solid ${C.border}`,
              ...anim(pipeOn, i * 80, 320, 6),
            }}>
              <div style={{
                width: 24, height: 24, borderRadius: 2, flexShrink: 0,
                background: 'rgba(89,163,179,0.08)', border: '1px solid rgba(89,163,179,0.2)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                color: C.cyan,
                filter: 'drop-shadow(0 0 4px rgba(89,163,179,0.3))',
              }}>
                <step.Icon />
              </div>
              <div>
                <div style={{ fontFamily: F.sans, fontSize: 11.5, color: C.bone }}>{step.label}</div>
                {step.sub && (
                  <div style={{ fontFamily: F.mono, fontSize: 9.5, color: C.mute }}>{step.sub}</div>
                )}
              </div>
            </div>
          ))}
        </div>
      </div>
      {/* Review checkpoint */}
      <div style={{
        marginTop: 10, padding: '8px 10px', borderRadius: 4,
        border: '1px solid rgba(89,163,179,0.22)',
        background: 'rgba(89,163,179,0.04)',
        ...anim(pipeOn, steps.length * 80 + 60, 360),
      }}>
        <div style={{
          fontFamily: F.mono, fontSize: 9, color: C.cyan,
          letterSpacing: '0.14em', textTransform: 'uppercase', marginBottom: 3,
        }}>Review</div>
        <div style={{ fontFamily: F.sans, fontSize: 11.5, color: C.grey }}>Manual QC checkpoint</div>
      </div>
    </div>
  );
}

// ── Phase 4: Deliver & Share ───────────────────────────────────────────────────
function CardDeliver({ on }) {
  const outputs = [
    { sym: '▶', label: 'Finished Video',      sub: 'Download & stream' },
    { sym: '◉', label: 'Host / Artist',        sub: 'Direct access' },
    { sym: '⊕', label: 'Online Distribution', sub: 'Social ready' },
  ];
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      {outputs.map((out, i) => (
        <div key={i} style={{
          padding: '8px 10px', borderRadius: 4,
          background: C.bg, border: `1px solid ${C.border}`,
          ...anim(on, 100 + i * 110),
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 3 }}>
            <span style={{ color: C.cyan, fontSize: 12, fontFamily: F.mono, opacity: 0.85 }}>{out.sym}</span>
            <span style={{ fontFamily: F.sans, fontSize: 12, color: C.bone, fontWeight: 500 }}>{out.label}</span>
          </div>
          <div style={{ fontFamily: F.mono, fontSize: 10, color: C.mute, paddingLeft: 20 }}>{out.sub}</div>
        </div>
      ))}
    </div>
  );
}

// ── Main component ─────────────────────────────────────────────────────────────
function ShowgazeProcess() {
  const ref  = useRef(null);
  const [vis,  setVis]  = useState(false);
  const [pipe, setPipe] = useState(false);

  // Inject scoped styles into <head> once — avoids a <style> tag in the document
  // body and prevents duplicate injection if the component is mounted more than once.
  useEffect(() => {
    const id = 'sgp-styles';
    if (document.getElementById(id)) return;
    const el = document.createElement('style');
    el.id = id;
    el.textContent = `
      .sgp-row   { display: flex; flex-direction: row; align-items: flex-start; }
      .sgp-arrow { display: flex; }
      @media (max-width: 720px) {
        .sgp-row   { flex-direction: column; gap: 24px; }
        .sgp-arrow { display: none !important; }
        .sgp-phase { width: 100% !important; }
      }
    `;
    document.head.appendChild(el);
  }, []);

  // Trigger on scroll into view. IntersectionObserver is primary; the scroll
  // listener + immediate check() are a fallback for environments where IO
  // doesn't fire on already-visible elements (e.g. some headless renderers).
  useEffect(() => {
    const el = ref.current;
    if (!el) return;

    function reveal() { setVis(true); cleanup(); }

    function check() {
      if (el.getBoundingClientRect().top < window.innerHeight * 0.92) reveal();
    }

    const obs = new IntersectionObserver(
      ([entry]) => { if (entry.isIntersecting) reveal(); },
      { threshold: 0.08 }
    );

    // Use capture:false explicitly so removeEventListener matches reliably
    function cleanup() {
      obs.disconnect();
      window.removeEventListener('scroll', check, false);
    }

    obs.observe(el);
    window.addEventListener('scroll', check, { passive: true, capture: false });
    check(); // handles already-in-viewport on mount
    return cleanup;
  }, []);

  // Pipeline cascade — skip the delay if reduced motion is preferred
  useEffect(() => {
    if (!vis) return;
    const t = setTimeout(() => setPipe(true), REDUCE_MOTION ? 0 : 700);
    return () => clearTimeout(t);
  }, [vis]);

  // Per-phase stagger delays
  const delays = [0, 220, 440, 660];

  const phases = [
    { num: '01', label: 'Filming',         desc: 'Audience footage from multiple phones' },
    { num: '02', label: 'Capture & Send',  desc: 'Scan QR and upload footage' },
    { num: '03', label: 'Processing & QC', desc: null },
    { num: '04', label: 'Deliver & Share', desc: 'Finished video ready to share' },
  ];

  const cards = [
    <CardFilming    on={vis} />,
    <CardCapture    on={vis} />,
    <CardProcessing cardOn={vis} pipeOn={pipe} />,
    <CardDeliver    on={vis} />,
  ];

  // Build flat array of phase cols + arrows (avoids React fragment key issue)
  const cols = [];
  phases.forEach((ph, i) => {
    if (i > 0) {
      cols.push(
        <div key={`arrow-${i}`} className="sgp-arrow">
          <Arrow on={vis} delay={delays[i] - 80} />
        </div>
      );
    }
    cols.push(
      <div key={ph.num} className="sgp-phase" style={{ flex: '1 1 0', minWidth: 0 }}>
        {/* Phase label cluster */}
        <div style={{ marginBottom: 12 }}>
          <div style={{
            fontFamily: F.mono, fontSize: 10, letterSpacing: '0.18em',
            color: C.cyan, marginBottom: 4,
            ...anim(vis, delays[i], 360, 8),
          }}>
            {ph.num}
          </div>
          <div style={{
            fontFamily: F.sans, fontSize: 12, fontWeight: 600, letterSpacing: '0.1em',
            color: C.bone, textTransform: 'uppercase', marginBottom: 5,
            ...anim(vis, delays[i] + 40, 360, 8),
          }}>
            {ph.label}
          </div>
          {ph.desc && (
            <div style={{
              fontFamily: F.sans, fontSize: 11, color: C.grey, lineHeight: 1.55,
              ...anim(vis, delays[i] + 80, 360, 8),
            }}>
              {ph.desc}
            </div>
          )}
        </div>
        {/* Card */}
        <div style={{
          background: `linear-gradient(135deg, ${C.bg1} 0%, ${C.bg2} 100%)`,
          border: `1px solid ${C.border}`,
          borderRadius: 8, padding: 14,
          position: 'relative', overflow: 'hidden',
          minHeight: i === 0 ? 210 : undefined,
          boxShadow: '0 4px 24px rgba(0,0,0,0.2)',
          backdropFilter: 'blur(10px)',
          ...anim(vis, delays[i] + 60, 480),
        }}>
          <Corners />
          {cards[i]}
        </div>
      </div>
    );
  });

  return (
    <React.Fragment>
      <section ref={ref} style={{ background: C.bg, padding: '88px 24px' }}>
        <div style={{ width: 'min(1080px, calc(100% - 48px))', margin: '0 auto' }}>

          {/* Section header */}
          <div style={{ marginBottom: 52, ...anim(vis, 0, 500) }}>
            <p style={{
              fontFamily: F.mono, fontSize: 9, letterSpacing: '0.22em',
              color: C.cyan, textTransform: 'uppercase', margin: '0 0 10px',
            }}>
              How it works
            </p>
            <h2 style={{
              fontFamily: F.display,
              fontSize: 'clamp(22px, 2.8vw, 32px)',
              fontWeight: 400, color: C.bone,
              margin: 0, lineHeight: 1.2,
            }}>
              The Showgaze Process
            </h2>
          </div>

          {/* Phase columns */}
          <div className="sgp-row">
            {cols}
          </div>

          {/* Loop indicator */}
          <div style={{
            marginTop: 36, paddingTop: 20,
            borderTop: `1px solid ${C.border}`,
            display: 'flex', justifyContent: 'space-between',
            alignItems: 'center', flexWrap: 'wrap', gap: 8,
            ...anim(vis, 940, 380),
          }}>
            <span style={{ fontFamily: F.mono, fontSize: 10, color: C.mute, letterSpacing: '0.08em' }}>
              ↺&nbsp;&nbsp;Repeat for every event
            </span>
            <span style={{ fontFamily: F.mono, fontSize: 10, color: C.mute }}>
              Audience footage → Finished video
            </span>
          </div>

        </div>
      </section>
    </React.Fragment>
  );
}

window.ShowgazeProcess = ShowgazeProcess;
