/* global React */
const { useEffect, useRef, useState, useMemo } = React;

/* ============================================================
   Reveal-on-scroll hook
   ============================================================ */
function useReveal() {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;

    // Find all .reveal descendants (plus self if it has the class)
    const targets = Array.from(el.querySelectorAll('.reveal'));
    if (el.classList.contains('reveal')) targets.unshift(el);

    // Hero: trigger immediately on mount (above the fold)
    const isAboveFold = el.getBoundingClientRect().top < window.innerHeight * 0.9;
    if (isAboveFold) {
      el.classList.add('in');
      targets.forEach((t) => t.classList.add('in'));
      return;
    }

    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          el.classList.add('in');
          targets.forEach((t) => t.classList.add('in'));
          io.unobserve(el);
        }
      });
    }, { threshold: 0.15, rootMargin: '0px 0px -60px 0px' });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return ref;
}

/* ============================================================
   Section wrapper — numbered, optional kicker
   ============================================================ */
function Section({ id, num, total = 11, kicker, children, className = '', noTopRule = false, style }) {
  return (
    <section id={id} className={(noTopRule ? '' : 'rule-top ') + className} style={style}>
      <div className="wrap">
        {(num || kicker) && (
          <div className="sec-meta">
            {num && (
              <div className="sec-index">
                <span>—</span> {String(num).padStart(2, '0')} <span>/ {String(total).padStart(2, '0')}</span>
              </div>
            )}
            {kicker && (
              <div className="kicker"><span className="dot" />{kicker}</div>
            )}
          </div>
        )}
        {children}
      </div>
    </section>
  );
}

/* ============================================================
   Placeholder (clearly marked — Stage 1)
   ============================================================ */
function Placeholder({ label, sub, ratio = '4 / 3', minHeight, style, children }) {
  const css = {
    aspectRatio: minHeight ? undefined : ratio,
    minHeight,
    ...style,
  };
  return (
    <div className="ph" style={css}>
      <div>
        <div>{label}</div>
        {sub && <small>{sub}</small>}
        {children}
      </div>
    </div>
  );
}

/* ============================================================
   Brand mark — placeholder logo for the press grid
   ============================================================ */
function PressMark({ name }) {
  return (
    <div className="press-mark">
      <span>{name}</span>
    </div>
  );
}

/* ============================================================
   Anti-pitch line — strikethrough that animates first time it
   enters viewport, then stays "static struck" thereafter.
   ============================================================ */
function StruckLine({ text, delay = 0, played, onPlay }) {
  const ref = useRef(null);
  const [active, setActive] = useState(played); // start struck if already played

  useEffect(() => {
    if (played) { setActive(true); return; }
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          setTimeout(() => { setActive(true); onPlay && onPlay(); }, delay);
          io.unobserve(el);
        }
      });
    }, { threshold: 0.6 });
    io.observe(el);
    return () => io.disconnect();
  }, [played, delay, onPlay]);

  return (
    <div className={'struck ' + (active ? 'is-struck' : '')} ref={ref}>
      <span className="struck-text">{text}</span>
      <span className="struck-line" aria-hidden="true" />
    </div>
  );
}

/* ============================================================
   Hand-strikethrough styles — injected once
   ============================================================ */
(function injectAtomStyles() {
  if (document.getElementById('mvk-atom-styles')) return;
  const css = `
  .sec-meta {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 16px;
    margin-bottom: 56px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--rule);
  }
  @media (max-width: 600px) {
    .sec-meta { margin-bottom: 36px; padding-bottom: 12px; }
  }

  /* Press marks */
  .press-mark {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 56px;
    border: 1px solid var(--rule);
    color: var(--ink-mute);
    font-family: var(--serif);
    font-size: 17px;
    font-style: italic;
    letter-spacing: 0.04em;
    border-radius: 2px;
    background: var(--bg-elev);
    transition: color .2s, border-color .2s;
  }
  .press-mark:hover { color: var(--ink-2); border-color: var(--rule-2); }

  /* Struck line — anti-pitch */
  .struck {
    position: relative;
    display: inline-block;
    font-family: var(--serif);
    font-style: italic;
    color: var(--ink-mute);
    transition: color .6s ease;
    line-height: 1.25;
  }
  .struck.is-struck { color: var(--ink-faint); }
  .struck-line {
    position: absolute;
    left: -2%;
    right: 102%;
    top: 52%;
    height: 2px;
    background: var(--green);
    transform-origin: left center;
    transition: right 0.7s cubic-bezier(.65,.05,.36,1);
    border-radius: 2px;
    box-shadow: 0 0 0 0.5px rgba(151,196,89,0.3);
  }
  .struck.is-struck .struck-line { right: -2%; }
  /* hand-jitter */
  .struck-line::before {
    content: "";
    position: absolute; inset: -1px 0;
    background: inherit;
    transform: translateY(-1px) rotate(-0.4deg);
    opacity: .55;
    border-radius: inherit;
  }
  `;
  const style = document.createElement('style');
  style.id = 'mvk-atom-styles';
  style.textContent = css;
  document.head.appendChild(style);
})();

/* ============================================================
   Export
   ============================================================ */
Object.assign(window, {
  useReveal,
  Section,
  Placeholder,
  PressMark,
  StruckLine,
});
