// Landing — the signed-out public homepage. Shares the SAME app header and the
// SAME (black) footer as every other surface. The hero is the animated artlito
// mark over a full-bleed auto-advancing carousel; then the anti-engagement
// promise on a dark band, the audience trio (the three role blobs), recently-
// added feature rows, and a closing "doors" CTA. McQueen only, lowercase.
const LDS = window.ArtlitoDesignSystem_f3b428;
const { Logo: LLogo, Button: LButton } = LDS;

const PAGE = { maxWidth: 'var(--page-max)', margin: '0 auto', padding: '0 var(--gutter-desktop)' };

/* ─────────────────────────── hero — artlito, animated ────────────────────── */
function LandingHero({ works, onEnter }) {
  const [active, setActive] = React.useState(0);
  const [paused, setPaused] = React.useState(false);
  const markRef = React.useRef(null);
  const count = works.length;

  React.useEffect(() => {
    if (count <= 1 || paused) return;
    const id = window.setInterval(() => setActive((i) => (i + 1) % count), 5500);
    return () => window.clearInterval(id);
  }, [count, paused]);

  // mount the official Lottie wordmark — whiten only the wordmark TEXT (the
  // `typo` layer) so it reads over the dark hero, while keeping the brand bubbles
  // (the `rond …`/`Calque …` dot layers) in their true colours.
  React.useEffect(() => {
    if (!window.lottie || !markRef.current) return;
    let anim, cancelled = false;
    fetch('/artlito/assets/artlito-logo-animation.json')
      .then((r) => r.json())
      .then((j) => {
        if (cancelled || !markRef.current) return;
        const data = JSON.parse(JSON.stringify(j));
        const whiten = (o) => {
          if (Array.isArray(o)) { o.forEach(whiten); return; }
          if (o && typeof o === 'object') {
            if ((o.ty === 'fl' || o.ty === 'st') && o.c && o.c.a === 0 && Array.isArray(o.c.k)) {
              const k = o.c.k;
              if (k[0] < 0.18 && k[1] < 0.18 && k[2] < 0.18) o.c.k = [1, 1, 1, k[3] == null ? 1 : k[3]];
            }
            Object.keys(o).forEach((key) => whiten(o[key]));
          }
        };
        (data.layers || []).forEach((L) => { if (!/rond|calque/i.test(L.nm || '')) whiten(L); });
        anim = window.lottie.loadAnimation({
          container: markRef.current, renderer: 'svg', loop: true, autoplay: true, animationData: data,
        });
      })
      .catch(() => {});
    return () => { cancelled = true; if (anim) anim.destroy(); };
  }, []);

  const cur = works[active];

  return (
    <section
      onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)}
      style={{ position: 'relative', height: '100vh', minHeight: 640, maxHeight: 1040, overflow: 'hidden', background: 'var(--black)' }}
      aria-label="artlito — featured work">
      {works.map((w, i) => (
        <div key={w.id} className={`al-slide${i === active ? ' is-active' : ''}`} aria-hidden={i !== active}>
          <img src={w.image} alt="" loading={i === 0 ? 'eager' : 'lazy'} decoding="async" fetchpriority={i === 0 ? 'high' : undefined} />
        </div>
      ))}
      {/* curtain — even darkening so the white mark reads over the imagery */}
      <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.46)' }} aria-hidden />
      <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, rgba(0,0,0,0.35) 0%, rgba(0,0,0,0) 30%, rgba(0,0,0,0) 64%, rgba(0,0,0,0.5) 100%)' }} aria-hidden />

      {/* centred brand composition */}
      <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', color: 'var(--white)', padding: '0 24px' }}>
        <span style={{ fontSize: 13, letterSpacing: '0.2em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.8)' }}>a living archive for art</span>
        {/* animated artlito wordmark — white text, true-colour bubbles */}
        <div ref={markRef} aria-label="artlito" role="img"
          style={{ width: 'min(560px, 78vw)', height: 'auto', margin: '26px 0 6px' }} />
        <p style={{ margin: '18px 0 0', fontSize: 'clamp(19px, 2.1vw, 24px)', lineHeight: 1.45, color: 'rgba(255,255,255,0.9)', maxWidth: 600 }}>
          from process to permanence — a quiet space to archive your work, connect with the ecosystem, and let your practice grow.
        </p>
        <div style={{ marginTop: 36, display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap', justifyContent: 'center' }}>
          <LButton size="lg" onClick={onEnter}>start your archive</LButton>
          <LButton size="lg" variant="secondary" onClick={onEnter}
            style={{ background: 'transparent', color: 'var(--white)', borderColor: 'rgba(255,255,255,0.6)' }}>browse the collection</LButton>
        </div>
      </div>

      {/* current-work credit + dots */}
      <div style={{ position: 'absolute', right: 'var(--gutter-desktop)', bottom: 32, display: 'flex', alignItems: 'center', gap: 18, color: 'rgba(255,255,255,0.82)' }}>
        <span style={{ fontSize: 13, letterSpacing: 'var(--tracking-meta)', textAlign: 'right' }}>{cur.title}</span>
        <span style={{ display: 'flex', gap: 8 }}>
          {works.map((w, i) => (
            <button key={w.id} onClick={() => setActive(i)} aria-label={`show ${i + 1}`} aria-current={i === active}
              style={{ width: 8, height: 8, borderRadius: 999, padding: 0, cursor: 'pointer', border: '1px solid rgba(255,255,255,0.85)',
                background: i === active ? 'var(--white)' : 'transparent' }} />
          ))}
        </span>
      </div>
    </section>
  );
}

/* ─────────────────────────── principles band ─────────────────────────────── */
function LandingPrinciples() {
  return (
    <section style={{ background: 'var(--black)', color: 'var(--white)' }}>
      <div style={{ ...PAGE, paddingTop: 'var(--section-gap)', paddingBottom: 'var(--section-gap)', maxWidth: 1000, textAlign: 'center' }}>
        <span style={{ fontSize: 13, letterSpacing: '0.16em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.6)' }}>how artlito works</span>
        <p style={{ margin: '32px auto 0', fontSize: 'clamp(24px, 2.8vw, 34px)', lineHeight: 1.4, letterSpacing: '-0.01em', textTransform: 'lowercase', maxWidth: 860 }}>
          no feeds, and no public counts on anyone or anything. nothing here is ranked by popularity or sorted by whatever is getting the most attention. you find work because a curator chose it, or because it matches what you searched — never because an algorithm decided it would keep you scrolling.
        </p>
        <p style={{ margin: '28px auto 0', fontSize: 18, lineHeight: 1.6, color: 'rgba(255,255,255,0.7)', maxWidth: 600 }}>
          profiles and works are records, not posts. identity is grounded in verified signals — a portfolio domain, an institution, an orcid — not popularity.
        </p>
      </div>
    </section>
  );
}

/* ─────────────────────────── audience trio ───────────────────────────────── */
const AUDIENCE = [
  { icon: '/artlito/assets/audience/artist.png', title: 'artists', accent: '#5ef05c',
    desc: 'showcase your work, find collaborations, apply for residencies, and connect with galleries worldwide.',
    points: ['professional portfolio', 'research & process sharing', 'collaboration opportunities'],
    price: { big: 'free', sub: 'forever' } },
  { icon: '/artlito/assets/audience/art_lover.png', title: 'art enthusiasts', accent: '#9b66ff',
    desc: 'support artists, discover new work, and engage with the contemporary art scene as a collector or curator.',
    points: ['curated art discovery', 'direct artist contact', 'research resources'],
    price: { big: '$19', sub: 'per month' } },
  { icon: '/artlito/assets/audience/galleries.png', title: 'galleries & institutions', accent: '#b1b1b1',
    desc: 'discover emerging talent, manage exhibitions, and connect with the global art community.',
    points: ['artist discovery tools', 'exhibition management', 'institutional networking'],
    price: { big: '$49', sub: 'per month' } },
];

function LandingAudience({ onEnter }) {
  return (
    <section style={{ ...PAGE, paddingTop: 'var(--section-gap)', paddingBottom: 'var(--section-gap)' }}>
      <div style={{ maxWidth: 'var(--reading-max)' }}>
        <span style={{ fontSize: 13, letterSpacing: '0.16em', textTransform: 'uppercase', color: 'var(--brand-body)' }}>who it's for</span>
        <h2 style={{ margin: '18px 0 0', fontSize: 'clamp(30px, 3.6vw, 44px)', letterSpacing: '-0.02em', textTransform: 'lowercase', lineHeight: 1.05 }}>
          one archive, four kinds of people
        </h2>
      </div>
      <div style={{ marginTop: 56, display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 1, background: 'var(--line)', border: '1px solid var(--line)', borderRadius: 'var(--radius-lg)', overflow: 'hidden' }}>
        {AUDIENCE.map((a) => (
          <div key={a.title} style={{ background: 'var(--white)', padding: '40px 36px', display: 'flex', flexDirection: 'column', gap: 22 }}>
            <img src={a.icon} alt="" loading="lazy" decoding="async" style={{ width: 56, height: 56, objectFit: 'contain' }} />
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
              <h3 style={{ margin: 0, fontSize: 24, letterSpacing: '-0.01em', textTransform: 'lowercase' }}>{a.title}</h3>
              <p style={{ margin: 0, fontSize: 16, lineHeight: 1.55, color: 'var(--brand-body)' }}>{a.desc}</p>
            </div>
            <ul style={{ margin: 0, padding: 0, listStyle: 'none', display: 'flex', flexDirection: 'column', gap: 10, borderTop: '1px solid var(--line)', paddingTop: 22 }}>
              {a.points.map((p) => (
                <li key={p} style={{ display: 'flex', alignItems: 'center', gap: 10, fontSize: 15, color: 'var(--text-primary)' }}>
                  <span style={{ width: 7, height: 7, borderRadius: 999, background: a.accent, flex: 'none', boxShadow: a.accent === '#b1b1b1' ? 'inset 0 0 0 1px rgba(0,0,0,0.15)' : 'none' }} />{p}
                </li>
              ))}
            </ul>
            <div style={{ marginTop: 'auto', paddingTop: 8, display: 'flex', alignItems: 'baseline', gap: 8 }}>
              <span style={{ fontSize: 28, letterSpacing: '-0.01em', textTransform: 'lowercase' }}>{a.price.big}</span>
              <span style={{ fontSize: 14, color: 'var(--brand-body)' }}>· {a.price.sub}</span>
            </div>
          </div>
        ))}
      </div>
    </section>
  );
}

/* ─────────────────────────── recently added (feature rows) ───────────────── */
// Floating "gallery" shadow lifted from the individual work page, so the work
// hangs off the wall instead of sitting in a flat box. Static — no hover
// effects; the images are plain clickable surfaces.
const LAND_ART_SHADOW = '0 40px 72px -30px rgba(0,0,0,0.42), 0 14px 30px -20px rgba(0,0,0,0.20)';
function NewsImage({ w, onOpen }) {
  return (
    <button onClick={() => onOpen(w)}
      aria-label={'view ' + w.title}
      style={{ direction: 'ltr', display: 'block', width: '100%', padding: '10px 10px 22px', border: 'none', background: 'none', cursor: 'pointer' }}>
      <img src={w.image} alt={w.title}
        loading="lazy" decoding="async"
        onLoad={(e) => { e.currentTarget.style.filter = 'none'; }}
        ref={(el) => { if (el && el.complete) el.style.filter = 'none'; }}
        style={{ width: '100%', height: 'clamp(280px, 38vw, 460px)', objectFit: 'cover', display: 'block',
          borderRadius: 'var(--radius-md)', boxShadow: LAND_ART_SHADOW,
          filter: 'blur(14px)', transition: 'filter 0.5s var(--ease)' }} />
    </button>
  );
}
// Rows render in batches — only the first LAND_NEWS_BATCH mount; reaching the
// bottom of what's shown appends the next batch, so the landing opens without
// laying out / fetching all 40 full-width work images at once. NewsImage blurs
// each image until it actually loads.
const LAND_NEWS_BATCH = 4;
function LandingNews({ works, onOpenWork }) {
  const [count, setCount] = React.useState(LAND_NEWS_BATCH);
  const sentinel = React.useRef(null);
  React.useEffect(() => { setCount(LAND_NEWS_BATCH); }, [works]);
  React.useEffect(() => {
    if (count >= works.length) return;
    const el = sentinel.current;
    if (!el) return;
    const io = new IntersectionObserver((es) => {
      if (es[0].isIntersecting) setCount((c) => Math.min(works.length, c + LAND_NEWS_BATCH));
    }, { rootMargin: '700px 0px' });
    io.observe(el);
    return () => io.disconnect();
  }, [count, works]);
  return (
    <section style={{ background: 'var(--plate)' }}>
      <div style={{ ...PAGE, paddingTop: 'var(--section-gap)', paddingBottom: 'var(--section-gap)' }}>
        <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 16, marginBottom: 56 }}>
          <h2 style={{ margin: 0, fontSize: 'clamp(28px, 3.4vw, 40px)', letterSpacing: '-0.02em', textTransform: 'lowercase' }}>recently added to the archive</h2>
          <a href="#" onClick={(e) => { e.preventDefault(); onOpenWork(works[0]); }} style={{ fontSize: 15, textDecoration: 'underline', textUnderlineOffset: 4, textTransform: 'lowercase', whiteSpace: 'nowrap' }}>browse all</a>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 64 }}>
          {works.slice(0, count).map((w, i) => {
            const rtl = i % 2 === 1;
            return (
              <article key={w.id} style={{ display: 'grid', gridTemplateColumns: '1fr 1.6fr', gap: 48, alignItems: 'center', direction: rtl ? 'rtl' : 'ltr' }}>
                <div style={{ direction: 'ltr', display: 'flex', flexDirection: 'column', gap: 16 }}>
                  <span style={{ fontSize: 13, letterSpacing: 'var(--tracking-meta)', color: 'var(--brand-body)' }}>@{w.artist.replace(/[^a-z]/gi, '').slice(0, 8).toLowerCase()}</span>
                  <button onClick={() => onOpenWork(w)} style={{ background: 'none', border: 'none', padding: 0, cursor: 'pointer', textAlign: 'left' }}>
                    <h3 style={{ margin: 0, fontSize: 'clamp(26px, 3vw, 36px)', letterSpacing: '-0.02em', textTransform: 'lowercase', lineHeight: 1.08 }}>{w.title}</h3>
                  </button>
                  <span style={{ fontSize: 14, letterSpacing: 'var(--tracking-meta)', color: 'var(--brand-body)' }}>{[w.medium, w.year].filter(Boolean).join(' · ')}</span>
                  <a href="#" onClick={(e) => { e.preventDefault(); onOpenWork(w); }} style={{ marginTop: 8, fontSize: 15, textDecoration: 'underline', textUnderlineOffset: 4, textTransform: 'lowercase' }}>view work →</a>
                </div>
                <NewsImage w={w} onOpen={onOpenWork} />
              </article>
            );
          })}
        </div>
        {count < works.length && <div ref={sentinel} aria-hidden style={{ height: 1 }} />}
      </div>
    </section>
  );
}

/* ─────────────────────────── closing doors ───────────────────────────────── */
function LandingDoors({ onEnter }) {
  return (
    <section style={{ ...PAGE, paddingTop: 'var(--section-gap)', paddingBottom: 'var(--section-gap)', textAlign: 'center' }}>
      {/* brand cluster — Lottie layout: dots touch (no gap), black TL · purple TR · green BL · gray BR */}
      <div style={{ display: 'inline-grid', gridTemplateColumns: 'repeat(2, 22px)', marginBottom: 28 }}>
        <span style={{ width: 22, height: 22, borderRadius: 999, background: '#000000' }} />
        <span style={{ width: 22, height: 22, borderRadius: 999, background: '#9b66ff' }} />
        <span style={{ width: 22, height: 22, borderRadius: 999, background: '#5ef05c' }} />
        <span style={{ width: 22, height: 22, borderRadius: 999, background: '#b1b1b1' }} />
      </div>
      <h2 style={{ margin: 0, fontSize: 'clamp(34px, 5vw, 64px)', letterSpacing: '-0.025em', textTransform: 'lowercase', lineHeight: 1.02 }}>
        where practice has a place
      </h2>
      <p style={{ margin: '24px auto 0', fontSize: 19, lineHeight: 1.55, color: 'var(--brand-body)', maxWidth: 520 }}>
        begin your archive in minutes — a cover, a title, a few words. the rest grows with your practice.
      </p>
      <div style={{ marginTop: 36, display: 'flex', gap: 16, justifyContent: 'center', flexWrap: 'wrap' }}>
        <LButton size="lg" onClick={onEnter}>start your archive</LButton>
        <LButton size="lg" variant="secondary" onClick={onEnter}>browse the collection</LButton>
      </div>
    </section>
  );
}

/* ─────────────────────────── page ────────────────────────────────────────── */
function LandingPage(props) {
  const p = props || {};
  const { works } = window.ARTLITO_DATA;
  // In the standalone bundle these are supplied as callbacks (state-routed);
  // as a standalone landing.html page they fall back to cross-file links.
  const enter = p.onEnter || (() => { window.location.href = '/discover'; });
  const signUp = p.onSignUp || (() => { window.location.href = '/auth'; });
  const openWork = p.onOpenWork || ((w) => { window.location.href = '/work?w=' + w.id; });
  const nav = p.onNav || ((key) => {
    if (key === 'login' || key === 'signup') { window.location.href = '/auth'; return; }
    enter();
  });
  const footerNav = p.onFooterNav || ((k) => { window.location.href = '/discover#' + k; });
  // Hero slides are drawn from the featured works (so the placeholder imagery
  // applies) rather than the audience icons — the hero reads as "featured work".
  const hero = works.slice(0, 5).map((w, i) => ({ id: 'hero-' + i, image: w.image, title: '', artist: '' }));
  const news = [works[0], works[8], works[5]];

  return (
    <React.Fragment>
      <SiteHeader active="home" onNav={nav} unread={0} heroDark={true} signedIn={false} />
      <LandingHero works={hero} onEnter={signUp} />
      <LandingPrinciples />
      <LandingAudience onEnter={signUp} />
      <LandingNews works={news} onOpenWork={openWork} />
      <LandingDoors onEnter={signUp} />
      <SiteFooter onNav={footerNav} />
    </React.Fragment>
  );
}

window.LandingPage = LandingPage;
