// Shared TSD components
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// Hash router
function useRoute() {
  const [route, setRoute] = useState(window.location.hash.replace(/^#/, '') || '/');
  useEffect(() => {
    const onHash = () => {
      setRoute(window.location.hash.replace(/^#/, '') || '/');
      window.scrollTo({ top: 0, behavior: 'instant' });
    };
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);
  return route;
}

function navigate(to) {
  if (to.startsWith('http')) { window.open(to, '_blank'); return; }
  window.location.hash = to;
}

function Link({ to, children, className, style, onClick }) {
  return React.createElement('a', {
    href: '#' + to,
    className,
    style,
    onClick: (e) => {
      if (onClick) onClick(e);
    }
  }, children);
}

// Reveal-on-scroll
function Reveal({ children, delay = 0, as = 'div', className = '', style = {} }) {
  const ref = useRef(null);
  const [visible, setVisible] = useState(false);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setTimeout(() => setVisible(true), delay); io.disconnect(); }
    }, { threshold: 0.15, rootMargin: '0px 0px -10% 0px' });
    io.observe(el);
    return () => io.disconnect();
  }, [delay]);
  return React.createElement(as, {
    ref,
    className: `reveal ${visible ? 'reveal-in' : ''} ${className}`,
    style
  }, children);
}

// Logo SVG inline (recreated as glyphs, not pixel-perfect)
function TSDLogo({ size = 28, dark = false }) {
  const color = dark ? '#F2EFE8' : '#0F1B3D';
  return (
    <svg width={size * 1.6} height={size} viewBox="0 0 88 56" fill="none" xmlns="http://www.w3.org/2000/svg" style={{ display: 'block' }}>
      <text x="0" y="30" fontFamily="'Newsreader', serif" fontWeight="600" fontSize="36" letterSpacing="-2" fill={color}>TSD</text>
      <text x="0" y="50" fontFamily="'Newsreader', serif" fontWeight="400" fontStyle="italic" fontSize="11" fill={color} letterSpacing="0.5">the strategy division</text>
    </svg>
  );
}

// Standard section intro — used at the top of every major section.
// Headline is the dominant element; the section number is a tiny tag.
function SectionIntro({ num, kicker, title, sub, light = false, compact = false }) {
  return (
    <div className={`sec-intro ${light ? 'sec-intro-light' : ''} ${compact ? 'sec-intro-compact' : ''}`}>
      <div className="sec-intro-main">
        {num && <span className={`sec-intro-tag ${light ? 'sec-intro-tag-light' : ''}`}>§ {num}</span>}
        <h2 className={`sec-intro-headline ${light ? 'sec-intro-headline-light' : ''} ${compact ? 'sec-intro-headline-compact' : ''}`}>{kicker}</h2>
        {title && <div className={`sec-intro-tagline ${light ? 'sec-intro-tagline-light' : ''}`}>{title}</div>}
      </div>
      {sub && <p className={`sec-intro-sub ${light ? 'sec-intro-sub-light' : ''}`}>{sub}</p>}
    </div>
  );
}

// Nav
function Nav({ darkInitial = false }) {
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 40);
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  const route = useRoute();
  const isHome = route === '/' || route === '';
  const dark = darkInitial && !scrolled;

  // Single-page anchors
  const links = [
    { href: '#disciplines', label: 'What We Do' },
    { href: '#showcase', label: 'Showcase' },
    { href: '#map', label: 'Where' },
    { href: '#cases', label: 'Cases' },
    { href: '#testimonials', label: 'Awards' },
    { href: '#team', label: 'Team' }
  ];

  const onAnchor = (e, href) => {
    e.preventDefault();
    const id = href.replace('#','');
    const el = document.getElementById(id);
    if (el) {
      el.scrollIntoView({ behavior: 'smooth', block: 'start' });
      history.replaceState(null, '', href);
    }
  };

  return (
    <nav className={`nav ${scrolled ? 'nav-scrolled' : ''} ${dark ? 'nav-dark' : ''}`}>
      <a href="#top" onClick={(e) => onAnchor(e, '#top')} className="nav-logo" style={{ textDecoration: 'none' }}>
        <TSDLogo size={26} dark={dark} />
      </a>
      <div className="nav-links">
        {links.map(l => (
          <a key={l.href} href={l.href} onClick={(e) => onAnchor(e, l.href)} className="nav-link">{l.label}</a>
        ))}
        <a href="#contact" onClick={(e) => onAnchor(e, '#contact')} className="nav-cta">Contact today →</a>
      </div>
    </nav>
  );
}

// Footer — anchor-based for single-page flow
function Footer() {
  const onAnchor = (e, href) => {
    e.preventDefault();
    const id = href.replace('#','');
    const el = document.getElementById(id);
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
  };
  return (
    <footer className="footer">
      <div className="footer-grid">
        <div className="footer-col">
          <a href="#top" onClick={(e) => onAnchor(e, '#top')} style={{ display: 'inline-block', marginBottom: 20 }}>
            <TSDLogo size={32} dark />
          </a>
          <p className="body-sm" style={{ maxWidth: 360, color: 'var(--paper-on-ink-60)', marginTop: 16 }}>
            An award-winning Democratic political consultancy. Strategy, direct mail, and digital — at the next level.
          </p>
          <div style={{ marginTop: 32, display: 'flex', gap: 12 }}>
            {['LinkedIn', 'Vimeo', 'Instagram'].map(s => (
              <a key={s} href="#top" style={{
                fontSize: 11, fontFamily: 'var(--font-mono)', letterSpacing: '0.1em', textTransform: 'uppercase',
                padding: '8px 12px', border: '1px solid var(--paper-on-ink-12)', borderRadius: 999, color: 'var(--paper-on-ink-60)'
              }}>{s}</a>
            ))}
          </div>
        </div>
        <div className="footer-col">
          <h4>Sections</h4>
          <ul>
            <li><a href="#disciplines" onClick={(e) => onAnchor(e, '#disciplines')}>What We Do</a></li>
            <li><a href="#showcase"    onClick={(e) => onAnchor(e, '#showcase')}>Digital + Mail</a></li>
            <li><a href="#map"         onClick={(e) => onAnchor(e, '#map')}>Where We've Worked</a></li>
            <li><a href="#cases"       onClick={(e) => onAnchor(e, '#cases')}>Case Studies</a></li>
          </ul>
        </div>
        <div className="footer-col">
          <h4>Firm</h4>
          <ul>
            <li><a href="#testimonials" onClick={(e) => onAnchor(e, '#testimonials')}>Testimonials</a></li>
            <li><a href="#testimonials" onClick={(e) => onAnchor(e, '#testimonials')}>Awards</a></li>
            <li><a href="#team"         onClick={(e) => onAnchor(e, '#team')}>Team</a></li>
            <li><a href="#contact"      onClick={(e) => onAnchor(e, '#contact')}>Contact</a></li>
          </ul>
        </div>
        <div className="footer-col">
          <h4>Offices</h4>
          <ul style={{ color: 'var(--paper-on-ink-60)' }}>
            <li>New York</li>
            <li>Colorado</li>
            <li>California</li>
            <li>Nevada</li>
          </ul>
        </div>
      </div>
      <div className="footer-bottom">
        <span>© 2026 The Strategy Division</span>
        <div style={{ display: 'flex', gap: 24 }}>
          <a href="mailto:hello@thestrategydivision.com">hello@thestrategydivision.com</a>
        </div>
      </div>
    </footer>
  );
}

// Mail piece placeholder — abstract editorial card
function MailPlaceholder({ piece, idx = 0 }) {
  const D = window.TSD_DATA;
  const seed = D.hash(piece.id || piece.client || 'x' + idx);
  // 6 design variants based on the type of mail
  const variant = seed % 7;

  const palettes = [
    { bg: '#0E0E12', fg: '#F2EFE8', accent: '#E54A2A' },   // ink + warm red
    { bg: '#0F1B3D', fg: '#F2EFE8', accent: '#F5C147' },   // navy + gold
    { bg: '#1B3A5C', fg: '#F2EFE8', accent: '#FF6B47' },   // deep blue + coral
    { bg: '#7A1F1F', fg: '#F2EFE8', accent: '#F2EFE8' },   // crimson
    { bg: '#0F4232', fg: '#F2EFE8', accent: '#F5C147' },   // forest + gold
    { bg: '#F2EFE8', fg: '#0E0E12', accent: '#E54A2A' },   // paper + red
    { bg: '#1A1A22', fg: '#F2EFE8', accent: '#5575FF' },   // ink + electric
  ];
  const p = palettes[seed % palettes.length];
  const pad = 24;

  // Distinct layouts
  const layouts = [
    // 0: Big headline
    <div key="0" style={{ position: 'absolute', inset: pad, display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
      <div style={{ fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '0.18em', color: p.accent, textTransform: 'uppercase' }}>{piece.race}</div>
      <div style={{ fontFamily: 'var(--font-serif)', fontWeight: 700, fontSize: 'clamp(22px, 3.5cqw, 44px)', lineHeight: 0.95, color: p.fg, letterSpacing: '-0.03em', textTransform: 'uppercase' }}>{piece.client.split(' ')[0]}<br/>{piece.client.split(' ').slice(1).join(' ') || 'NOW'}.</div>
      <div style={{ fontSize: 9, fontFamily: 'var(--font-mono)', color: p.fg, opacity: 0.5, letterSpacing: '0.15em', textTransform: 'uppercase' }}>Mail piece — front</div>
    </div>,
    // 1: Diagonal accent
    <div key="1" style={{ position: 'absolute', inset: 0 }}>
      <div style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '40%', background: p.accent }}></div>
      <div style={{ position: 'absolute', inset: pad, display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
        <div style={{ fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '0.18em', color: p.bg, textTransform: 'uppercase' }}>VOTE {piece.client.split(' ').slice(-1)[0].toUpperCase()}</div>
        <div style={{ fontFamily: 'var(--font-serif)', fontWeight: 700, fontSize: 'clamp(20px, 3.2cqw, 38px)', lineHeight: 1, color: p.fg, letterSpacing: '-0.025em' }}>{piece.client}</div>
      </div>
    </div>,
    // 2: Number block
    <div key="2" style={{ position: 'absolute', inset: pad, display: 'flex', flexDirection: 'column', gap: 12 }}>
      <div style={{ fontFamily: 'var(--font-serif)', fontSize: 'clamp(48px, 8cqw, 96px)', lineHeight: 0.9, fontWeight: 800, color: p.accent, letterSpacing: '-0.06em' }}>{(seed % 90 + 10)}<span style={{ fontSize: '0.4em' }}>%</span></div>
      <div style={{ fontFamily: 'var(--font-sans)', fontSize: 'clamp(11px, 1.4cqw, 14px)', color: p.fg, fontWeight: 500, letterSpacing: '-0.01em' }}>The number that matters in {piece.race}.</div>
      <div style={{ marginTop: 'auto', fontSize: 10, fontFamily: 'var(--font-mono)', letterSpacing: '0.12em', color: p.fg, opacity: 0.6, textTransform: 'uppercase' }}>{piece.client}</div>
    </div>,
    // 3: Photo placeholder portrait
    <div key="3" style={{ position: 'absolute', inset: 0, display: 'grid', gridTemplateRows: '1fr auto' }}>
      <div style={{ background: `linear-gradient(135deg, ${p.accent}33 0%, ${p.bg} 100%)`, position: 'relative' }}>
        <div style={{ position: 'absolute', inset: 0, background: 'repeating-linear-gradient(45deg, transparent 0 8px, rgba(255,255,255,0.04) 8px 9px)' }}></div>
        <div style={{ position: 'absolute', bottom: 12, left: 12, right: 12, fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '0.15em', color: p.fg, opacity: 0.6, textTransform: 'uppercase' }}>Candidate portrait</div>
      </div>
      <div style={{ padding: pad, background: p.fg, color: p.bg }}>
        <div style={{ fontFamily: 'var(--font-serif)', fontWeight: 700, fontSize: 'clamp(16px, 2.2cqw, 26px)', lineHeight: 1, letterSpacing: '-0.02em' }}>{piece.client}</div>
        <div style={{ fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '0.14em', textTransform: 'uppercase', marginTop: 6, opacity: 0.6 }}>{piece.race}</div>
      </div>
    </div>,
    // 4: Quote / pull
    <div key="4" style={{ position: 'absolute', inset: pad, display: 'flex', flexDirection: 'column', justifyContent: 'center', gap: 18 }}>
      <div style={{ fontFamily: 'var(--font-serif)', fontSize: 'clamp(40px, 6cqw, 72px)', lineHeight: 0.9, fontWeight: 300, color: p.accent }}>"</div>
      <div style={{ fontFamily: 'var(--font-serif)', fontSize: 'clamp(13px, 1.8cqw, 20px)', lineHeight: 1.15, color: p.fg, fontStyle: 'italic', letterSpacing: '-0.01em' }}>Enough is enough.</div>
      <div style={{ fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '0.12em', color: p.fg, opacity: 0.6, textTransform: 'uppercase' }}>— {piece.client}</div>
    </div>,
    // 5: Stacked bands
    <div key="5" style={{ position: 'absolute', inset: 0, display: 'grid', gridTemplateRows: '1fr 1fr 1fr' }}>
      <div style={{ background: p.bg, padding: pad, display: 'flex', alignItems: 'center', fontFamily: 'var(--font-serif)', fontWeight: 700, fontSize: 'clamp(14px, 2cqw, 22px)', color: p.fg, letterSpacing: '-0.02em', textTransform: 'uppercase' }}>STOP</div>
      <div style={{ background: p.accent, padding: pad, display: 'flex', alignItems: 'center', fontFamily: 'var(--font-serif)', fontWeight: 700, fontSize: 'clamp(14px, 2cqw, 22px)', color: p.bg, letterSpacing: '-0.02em', textTransform: 'uppercase' }}>THE</div>
      <div style={{ background: p.fg, padding: pad, display: 'flex', alignItems: 'center', fontFamily: 'var(--font-serif)', fontWeight: 700, fontSize: 'clamp(14px, 2cqw, 22px)', color: p.bg, letterSpacing: '-0.02em', textTransform: 'uppercase' }}>{piece.client.split(' ').slice(-1)[0]}</div>
    </div>,
    // 6: Editorial typography
    <div key="6" style={{ position: 'absolute', inset: pad, display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
      <div>
        <div style={{ fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '0.18em', color: p.accent, textTransform: 'uppercase' }}>An open letter</div>
        <div style={{ fontFamily: 'var(--font-serif)', fontWeight: 300, fontStyle: 'italic', fontSize: 'clamp(16px, 2.4cqw, 28px)', lineHeight: 1.05, color: p.fg, letterSpacing: '-0.02em', marginTop: 12 }}>About what's<br/>at stake in {piece.race.split(/[\/—]/)[0].trim()}.</div>
      </div>
      <div style={{ fontSize: 9, fontFamily: 'var(--font-mono)', color: p.fg, opacity: 0.5, letterSpacing: '0.12em', textTransform: 'uppercase' }}>{piece.client}</div>
    </div>
  ];

  return (
    <div style={{
      width: '100%',
      height: '100%',
      background: p.bg,
      color: p.fg,
      position: 'relative',
      overflow: 'hidden',
      containerType: 'inline-size'
    }}>
      {layouts[variant]}
    </div>
  );
}

// Vimeo embed
function VideoEmbed({ id, title }) {
  const [loaded, setLoaded] = useState(false);
  return (
    <div style={{ position: 'relative', aspectRatio: '16 / 9', background: 'var(--ink)', overflow: 'hidden' }}>
      {!loaded && (
        <button onClick={() => setLoaded(true)} style={{
          position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
          background: 'var(--ink)', color: 'var(--paper)', cursor: 'pointer'
        }}>
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 16 }}>
            <div style={{ width: 56, height: 56, borderRadius: '50%', border: '1px solid var(--paper-on-ink-30)', display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all 0.3s' }}>
              <svg width="14" height="16" viewBox="0 0 14 16" fill="none"><path d="M0 0 L14 8 L0 16 Z" fill="currentColor"/></svg>
            </div>
            <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.12em', textTransform: 'uppercase', opacity: 0.6 }}>{title || 'Play'}</div>
          </div>
        </button>
      )}
      {loaded && (
        <iframe
          src={`https://player.vimeo.com/video/${id}?autoplay=1`}
          style={{ width: '100%', height: '100%', border: 0 }}
          allow="autoplay; fullscreen; picture-in-picture"
          allowFullScreen
        ></iframe>
      )}
    </div>
  );
}

// Generic page header
function PageHeader({ eyebrow, title, intro, dark = false, children }) {
  return (
    <header className={`page-header ${dark ? 'page-header-ink' : ''}`}>
      <div className="page-header-grid">
        <div>
          {eyebrow && <div className="eyebrow" style={dark ? {color: 'var(--paper-on-ink-60)'} : {}}>{eyebrow}</div>}
          <h1 className="display-lg" style={{ marginTop: 24 }}>{title}</h1>
        </div>
        <div>
          {intro && <p className="body-lg" style={{ maxWidth: 480, opacity: dark ? 0.8 : 0.7 }}>{intro}</p>}
          {children}
        </div>
      </div>
    </header>
  );
}

Object.assign(window, { useRoute, navigate, Link, Reveal, TSDLogo, SectionIntro, Nav, Footer, MailPlaceholder, VideoEmbed, PageHeader });
