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

/* ---------- reveal-on-scroll wrapper ---------- */
function Reveal({ children, as = 'div', className = '', delay = 0, ...rest }) {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    // Immediate check: anything already within (or near) the viewport reveals at once.
    const reveal = () => setSeen(true);
    const inView = () => {
      const r = el.getBoundingClientRect();
      return r.top < (window.innerHeight || 800) * 0.96 && r.bottom > 0;
    };
    if (inView()) { reveal(); return; }
    let io;
    if ('IntersectionObserver' in window) {
      io = new IntersectionObserver((entries) => {
        entries.forEach((e) => { if (e.isIntersecting) { reveal(); io.disconnect(); } });
      }, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
      io.observe(el);
    }
    // Failsafe: never leave content hidden if the observer never fires.
    const onScroll = () => { if (inView()) { reveal(); cleanup(); } };
    const timer = setTimeout(reveal, 1600);
    window.addEventListener('scroll', onScroll, { passive: true });
    function cleanup() {
      if (io) io.disconnect();
      window.removeEventListener('scroll', onScroll);
      clearTimeout(timer);
    }
    return cleanup;
  }, []);
  const Tag = as;
  return (
    <Tag ref={ref} className={`r71reveal ${seen ? 'r71in' : ''} ${className}`} style={{ animationDelay: `${delay}ms` }} {...rest}>
      {children}
    </Tag>
  );
}

function Placeholder({ label, className = '', style }) {
  return (
    <div className={`ph ${className}`} style={style}>
      <span>{label}</span>
    </div>
  );
}

function Arrow() { return <span className="arw">→</span>; }

/* ---------- shared nav config ---------- */
const IR_EMAIL = 'mailto:investor.relations@1971capital.com';
const navItems = (base) => [
  { label: 'About', href: base + '#about' },
  { label: 'Research', href: 'Research.html' },
  { label: 'Media', href: 'Media.html' },
];

/* ---------- nav ---------- */
function Nav({ base = '' }) {
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 12);
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  // Close the mobile menu if the viewport grows back to desktop.
  useEffect(() => {
    const onResize = () => { if (window.innerWidth > 940) setOpen(false); };
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);
  const close = () => setOpen(false);
  return (
    <nav className={`nav ${scrolled ? 'scrolled' : ''} ${open ? 'open' : ''}`}>
      <div className="wrap nav-inner">
        <a className="brand" href={base || '#top'} onClick={close}>
          <span className="brandmark" aria-hidden="true"></span>
          <span className="mark"><b>1971</b> Capital</span>
        </a>
        <button
          className="nav-toggle" type="button" aria-label="Menu"
          aria-expanded={open} onClick={() => setOpen((o) => !o)}>
          <span></span><span></span><span></span>
        </button>
        <div className="nav-links">
          {navItems(base).map((l) => <a key={l.label} href={l.href} onClick={close}>{l.label}</a>)}
          <a className="navcta" href={IR_EMAIL} onClick={close}>Investor Relations</a>
        </div>
      </div>
    </nav>
  );
}

/* ---------- hero ---------- */
function Hero({ headline, sub, motion, accent, backdrop }) {
  // headline may contain *italic* segment marked with asterisks
  const parts = headline.split(/(\*[^*]+\*)/g).filter(Boolean);
  const Motion = window.HeroMotion;
  return (
    <header className="hero" id="top">
      {Motion && motion && motion !== 'Off' && (
        <div className="hero-motion" aria-hidden="true"><Motion variant={motion} accent={accent} /></div>
      )}
      {backdrop && backdrop !== 'None' && (
        <div className="hero-backdrop" data-v={backdrop} aria-hidden="true"></div>
      )}
      <div className="wrap">
        <Reveal as="h1" delay={60}>
          {parts.map((p, i) => p.startsWith('*')
            ? <em key={i}>{p.slice(1, -1)}</em>
            : <React.Fragment key={i}>{p}</React.Fragment>)}
        </Reveal>
        <Reveal className="hero-sub" delay={140}>{sub}</Reveal>
        <Reveal className="hero-actions" delay={200}>
          <a className="btn btn-primary" href="#research">Read our research <Arrow /></a>
          <a className="btn btn-ghost" href={IR_EMAIL}>Contact investor relations</a>
        </Reveal>
      </div>
    </header>
  );
}

/* ---------- focus strip ---------- */
const FOCUS = [
  { n: '01', t: 'Thematic', d: 'Concentrated positions sourced from structural shifts in policy, liquidity, and the global flow of capital.' },
  { n: '02', t: 'Cross-Asset', d: 'Conviction expressed wherever the opportunity is clearest — equities, rates, commodities, currencies, and digital assets.' },
  { n: '03', t: 'Liquid Markets', d: 'Exposure taken exclusively in liquid public markets, so investors retain access to their capital — never locked away.' },
];
function FocusStrip() {
  return (
    <section className="focus" id="about">
      <div className="wrap focus-grid">
        {FOCUS.map((f, i) => (
          <Reveal className="focus-item" key={f.n} delay={i * 80}>
            <div className="n mono">{f.n}</div>
            <h3>{f.t}</h3>
            <p>{f.d}</p>
          </Reveal>
        ))}
      </div>
    </section>
  );
}

/* ---------- thesis ---------- */
function Thesis({ motion }) {
  const Motion = window.HeroMotion;
  return (
    <section className="thesis">
      {Motion && motion && (
        <div className="thesis-motion" aria-hidden="true"><Motion variant="Markets" ink="#f3efe6" /></div>
      )}
      <div className="wrap thesis-grid">
        <Reveal>
          <div className="mono" style={{ marginBottom: 24 }}>The Thesis · Why 1971</div>
          <h2>The year the monetary constraint <em>fell away</em>.</h2>
          <p>In 1971, the U.S. unlinked the dollar from gold. Eliminating this constraint did not set off hyperinflation or a financial crisis. Instead, the era of fiat currency unleashed unconstrained human progress, productivity growth, and wealth creation.</p>
          <p className="thesis-close">We help investors navigate this unfolding future.</p>
        </Reveal>
        <Reveal delay={120} className="thesis-markwrap">
          <div className="thesis-mark" role="img" aria-label="1971 Capital mark"></div>
        </Reveal>
      </div>
    </section>
  );
}

/* ---------- founder ---------- */
function Founder() {
  const creds = ['Founder & CIO', '20 years in finance', 'Institutional Risk Management'];
  return (
    <section className="founder">
      <div className="wrap founder-grid">
        <Reveal className="founder-head">
          <div className="founder-kicker mono">Leadership</div>
          <h2>Brian Russ</h2>
          <div className="role">Founder &amp; Chief Investment Officer</div>
        </Reveal>
        <Reveal className="founder-photo-wrap" delay={80}>
          <img className="founder-photo" src="assets/brian-russ-real.jpg" alt="Brian Russ, Founder & CIO" />
        </Reveal>
        <Reveal className="founder-detail" delay={140}>
          <p>Brian founded 1971 Capital to help investors position around the dynamic forces reshaping global markets. He brings two decades of experience across institutional finance and investment management.</p>
          <div className="creds">
            {creds.map((c) => <span className="cred" key={c}>{c}</span>)}
          </div>
        </Reveal>
      </div>
    </section>
  );
}

/* ---------- research + media cards ---------- */
const CONTENT = window.SITE_CONTENT || { posts: [], media: [] };
const POSTS = CONTENT.posts || [];
const MEDIA = CONTENT.media || [];
const actionLabel = (type) => type === 'Podcast' ? 'Listen' : (type === 'Video' ? 'Watch' : 'Read');

/* Live research: pull the latest essays straight from the Substack RSS feed
   (served as JSON by the Cloudflare function at /api/research). Falls back to
   the built-in list in content.js when the endpoint isn't available — e.g. in
   local preview, or if the feed is ever unreachable. */
function useResearch() {
  const [posts, setPosts] = useState(POSTS);
  useEffect(() => {
    let alive = true;
    fetch('/api/research', { headers: { accept: 'application/json' } })
      .then((r) => (r.ok ? r.json() : null))
      .then((d) => {
        if (alive && d && d.ok && Array.isArray(d.posts) && d.posts.length) {
          setPosts(d.posts);
        }
      })
      .catch(() => {});
    return () => { alive = false; };
  }, []);
  return posts;
}

function CoverTile({ item, kind }) {
  const kicker = kind === 'media' ? (item.action || 'Media') : 'Research';
  return (
    <div className="cover-tile">
      <span className="ct-mark" aria-hidden="true"></span>
      <span className="ct-body">
        <span className="ct-kicker mono">{kicker}</span>
        <span className="ct-title">{item.title}</span>
      </span>
    </div>
  );
}

function Card({ item, kind, delay }) {
  const isPh = !!item.placeholder;
  const href = isPh ? undefined : (item.url || '#');
  const action = item.action || (kind === 'media' ? 'Watch' : 'Read');
  return (
    <Reveal as={isPh ? 'div' : 'a'} className={`card ${isPh ? 'is-placeholder' : ''}`} delay={delay}
      href={href} target={isPh ? undefined : '_blank'} rel={isPh ? undefined : 'noreferrer'}>
      <div className="card-cover">
        {item.image
          ? <img src={item.image} alt="" loading="lazy" />
          : (isPh
            ? <div className="cover-add"><span className="mono">＋ Add cover</span></div>
            : <CoverTile item={item} kind={kind} />)}
      </div>
      <div className="card-body">
        <div className="card-date mono">{item.date || ''}</div>
        <div className="card-title">{item.title}</div>
        {(item.desc || item.note) && <div className="card-desc">{isPh ? item.note : item.desc}</div>}
        {!isPh && <span className="card-go mono">{action} <span className="arw">→</span></span>}
      </div>
    </Reveal>
  );
}

function CardGrid({ items, kind }) {
  return (
    <div className="card-grid">
      {items.map((it, i) => <Card key={(it.title || '') + i} item={it} kind={kind} delay={i * 70} />)}
    </div>
  );
}

function Research({ limit, showMore = false }) {
  const all = useResearch();
  const items = limit ? all.slice(0, limit) : all;
  return (
    <section className="research collection" id="research">
      <div className="wrap">
        <Reveal className="section-head"><h2>Research</h2></Reveal>
        <CardGrid items={items} kind="research" />
        {showMore && (
          <Reveal className="more-row">
            <a className="more-link mono" href="Research.html">All research <span className="arw">→</span></a>
          </Reveal>
        )}
      </div>
    </section>
  );
}

function Media({ limit, showMore = false }) {
  if (!MEDIA.length) return null;
  const items = limit ? MEDIA.slice(0, limit) : MEDIA;
  return (
    <section className="media collection" id="media">
      <div className="wrap">
        <Reveal className="section-head"><h2>Media</h2></Reveal>
        <CardGrid items={items} kind="media" />
        {showMore && (
          <Reveal className="more-row">
            <a className="more-link mono" href="Media.html">All media <span className="arw">→</span></a>
          </Reveal>
        )}
      </div>
    </section>
  );
}

/* ---------- signup ---------- */
function Signup() {
  const [val, setVal] = useState('');
  const [done, setDone] = useState(false);
  const [busy, setBusy] = useState(false);
  const submit = (e) => {
    e.preventDefault();
    if (!/.+@.+\..+/.test(val) || busy || done) return;
    setBusy(true);
    fetch('/api/subscribe', {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ email: val }),
    })
      .then((r) => r.json())
      .catch(() => ({ ok: false }))
      .then((d) => {
        setBusy(false);
        setDone(true);
        if (!d || !d.ok) {
          window.open('https://1971capital.substack.com/subscribe', '_blank', 'noopener');
        }
      });
  };
  return (
    <section className="signup" id="contact">
      <div className="wrap signup-grid">
        <Reveal>
          <h2>Subscribe to our research.</h2>
          <p className="lede">New essays. Delivered to your inbox. No noise.</p>
        </Reveal>
        <Reveal delay={100}>
          <form className="form" onSubmit={submit}>
            <input
              type="email" placeholder="you@firm.com" value={val}
              onChange={(e) => setVal(e.target.value)} aria-label="Email address" />
            <button className="btn btn-primary" type="submit" disabled={busy}>{done ? 'Subscribed' : (busy ? 'Subscribing…' : 'Subscribe')} <Arrow /></button>
            <div className={`note ${done ? 'ok' : ''}`}>
              {done ? '✓ Thank you — confirm via the email in your inbox.' : 'Delivered through Substack · unsubscribe anytime'}
            </div>
          </form>
        </Reveal>
      </div>
    </section>
  );
}

/* ---------- footer ---------- */
function Footer({ base = '' }) {
  return (
    <footer className="footer">
      <div className="wrap">
        <div className="footer-top">
          <div className="footer-brand">
            <a href={base || '#top'} className="footer-mark" aria-label="1971 Capital home"></a>
            <div className="mark"><b>1971</b> Capital</div>
            <p>Investment Management</p>
          </div>
          <div className="footer-cols">
            <div className="footer-col">
              <h4>Firm</h4>
              {navItems(base).map((l) => <a key={l.label} href={l.href}>{l.label}</a>)}
            </div>
            <div className="footer-col">
              <h4>Connect</h4>
              <a href={IR_EMAIL}>Investor Relations</a>
              <a href="https://1971capital.substack.com" target="_blank" rel="noreferrer">Substack</a>
              <a href="https://x.com/russ_brian" target="_blank" rel="noreferrer">X / Twitter</a>
            </div>
          </div>
        </div>
        <p className="disclaimer">
          The content presented herein is for informational purposes only and does not constitute investment advice or an offer to sell securities. Investment and advisory services are offered only to qualified clients and prospective clients where 1971 Capital and its representatives are properly licensed or exempt from licensure.
        </p>
        <div className="footer-bottom">
          <span>© 2026 1971 Capital Management, LLC. All rights reserved.</span>
          <span className="legal">
            <a href="Privacy.html">Privacy Policy</a>
            <a href="Terms.html">Terms of Use</a>
          </span>
        </div>
      </div>
    </footer>
  );
}

/* ---------- archive page header ---------- */
function ArchiveHeader({ kicker, title, lede }) {
  return (
    <header className="archive-head">
      <div className="wrap">
        <Reveal className="archive-kicker mono">{kicker}</Reveal>
        <Reveal as="h1" delay={60}>{title}</Reveal>
        {lede && <Reveal className="archive-lede" delay={120}>{lede}</Reveal>}
      </div>
    </header>
  );
}

Object.assign(window, {
  Reveal, Placeholder, Nav, Hero, FocusStrip, Thesis, Founder,
  Card, CardGrid, Research, Media, ArchiveHeader, Signup, Footer,
  useResearch,
});
