// ── Journal ───────────────────────────────────────────────────────────

const JOURNAL_ENTRIES = [
  {
    id: 'own-the-night',
    title: 'Own The Night',
    category: 'Featured Set',
    date: 'June 2026',
    image: 'assets/journal/jean-luc-vip.jpg?v=7',
    excerpt: 'Command the room in unapologetic luxury with the Jean-Luc leather jacket and pants set — crafted for those who never ask for attention, they attract it.',
    body: `Command the room in unapologetic luxury with the Jean-Luc leather jacket and pants set by JT Atelier, crafted for those who never ask for attention—they attract it. Each panel of rich, crocodile-embossed leather is precision cut and tailored to sculpt your frame, while the high-gloss finish catches every flicker of light, amplifying your presence with every move.

Double-breasted detailing and sharp, structured lines echo the energy of private lounges, velvet ropes, and champagne on ice, creating a silhouette that feels as powerful as it looks.

Elevate your style, own the night, and claim the spotlight—secure your Jean-Luc set from JT Atelier today.`,
    productId: 'p-0332',
    fallback: 'assets/products/men/sets/jean-luc/image_1.jpg',
  },
  {
    id: 'cold-streets-warm-confidence',
    title: 'Cold Streets. Warm Confidence.',
    category: 'Featured Aviator',
    date: 'June 2026',
    image: 'assets/journal/urban-aviator.jpg?v=7',
    fallback: 'assets/products/men/aviator/bertrand/image_1.jpg',
    imgPos: 'center 4%',
    excerpt: 'Introducing the JT Atelier Urban Aviator Shearling Bomber — where classic flight-jacket heritage meets modern city edge.',
    body: `Introducing the JT Atelier Urban Aviator Shearling Bomber – where classic flight-jacket heritage meets modern city edge. Crafted by JT Atelier, this piece blends precision tailoring with bold design, turning every sidewalk into a runway.

The structured shearling collar frames your silhouette, while the tailored cut keeps the profile sharp, never bulky. Contrast zippers and hardware – a JT Atelier signature – add a subtle hit of attitude, catching the light with every step. Slip your hands into the angled pockets, zip up, and you're instantly pulled together – no styling effort required.

Built for late nights, early flights, and everything in between, this JT Atelier bomber doesn't just keep you warm – it makes you unforgettable. Wear it with black denim and boots, and watch how the room, the street, the moment starts paying attention.`,
    productId: 'p-0012',
  },
  {
    id: 'ride-into-legend',
    title: 'Ride Into Legend',
    category: 'Featured Coat',
    date: 'June 2026',
    image: 'assets/journal/shealing_cowboy.jpg?v=2',
    fallback: 'assets/products/men/coat/dion/image_1.png',
    excerpt: 'Built not just to endure the elements, but to command them — the JT Atelier shearling coat, ridden into your own legend across the open plain.',
    body: `The snow was coming in sideways, needling across the open plain, but all I felt was the weight of the reins and the quiet power of the horse beneath me. The world had narrowed to the rhythm of hooves, the sting of winter air, and the way my JT Atelier shearling coat moved like a second skin. Every surge forward snapped the hem into the wind, a long tan banner cutting through the white.

This is what we built this coat for – not just to endure the elements, but to command them. The full-length shearling-lined body sealed in warmth without sacrificing movement, letting me lean into the turns and rise in the stirrups with total ease. The rich suede exterior took the snow and the spray without flinching, its color deepening in the cold light like worn saddle leather.

Out here, there's nowhere to hide poor craftsmanship. Stitching either holds or it fails. Fabric either breathes with you or turns against you. The JT Atelier coat rode clean – no pulling at the shoulders, no stiff seams, just an easy, confident drape that kept its line even as the horse exploded through the drift. In the reflection of the storm-dark sky, I realized: this wasn't just outerwear. It was armor for wide-open spaces and the kind of life that refuses to be lived indoors.

When I finally reined in, snow hanging in the horse's mane and steam curling in the air, the coat looked better than when we started – the patina beginning to tell its own story. That's the promise of JT Atelier: pieces designed not just to be worn, but to be ridden into your own legend.`,
    productId: 'p-0333',
  },
];

function JournalCard({ entry, onClick }) {
  const [hovered, setHovered] = React.useState(false);
  return (
    <article
      onClick={onClick}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      style={{ cursor: 'pointer' }}
      className="fade-up"
    >
      <div style={{ overflow: 'hidden', background: 'var(--surf)', marginBottom: 24 }}>
        <img
          src={entry.image}
          alt={entry.title}
          onError={e => { if (entry.fallback && e.currentTarget.src.indexOf(entry.fallback) < 0) e.currentTarget.src = entry.fallback; }}
          style={{
            width: '100%',
            aspectRatio: '3/2',
            objectFit: 'cover',
            objectPosition: entry.imgPos || 'center',
            display: 'block',
            transform: hovered ? 'scale(1.03)' : 'scale(1)',
            transition: 'transform .55s cubic-bezier(.22,.72,.36,1)',
          }}
        />
      </div>
      <div className="mono" style={{
        fontSize: 10, letterSpacing: '.22em', textTransform: 'uppercase',
        color: 'var(--crimson)', marginBottom: 10,
      }}>
        {entry.category} · {entry.date}
      </div>
      <h2 className="display" style={{
        fontSize: 'clamp(28px, 3.5vw, 48px)', lineHeight: 1.02,
        margin: '0 0 14px', fontWeight: 400,
        color: hovered ? 'var(--fg-2)' : 'var(--fg)',
        transition: 'color .2s',
      }}>{entry.title}</h2>
      <p style={{
        fontSize: 14, lineHeight: 1.72, color: 'var(--fg-2)',
        margin: '0 0 18px', maxWidth: 560,
      }}>{entry.excerpt}</p>
      <div className="mono" style={{
        fontSize: 10, letterSpacing: '.18em', color: 'var(--fg)',
        display: 'flex', alignItems: 'center', gap: 8,
        opacity: hovered ? 1 : 0.55, transition: 'opacity .2s',
      }}>
        Read more{' '}
        <span style={{
          transform: hovered ? 'translateX(4px)' : 'none',
          transition: 'transform .2s', display: 'inline-block',
        }}>→</span>
      </div>
    </article>
  );
}

function JournalEntry({ entry, goTo, onBack }) {
  const mobile = useMobile();
  const loPrice = useCurrency();
  const product = entry.productId
    ? (window.PRODUCTS || []).find(p => p.id === entry.productId)
    : null;

  React.useEffect(() => {
    window.scrollTo({ top: 0, behavior: 'instant' });
  }, []);

  const paragraphs = entry.body.split('\n\n').filter(Boolean);

  return (
    <div>
      {/* Back link */}
      <div className="container" style={{ paddingTop: 32 }}>
        <button
          onClick={onBack}
          className="mono"
          style={{
            color: 'var(--fg-3)', fontSize: 11, letterSpacing: '.12em',
            display: 'flex', alignItems: 'center', gap: 8,
            transition: 'color .15s',
          }}
          onMouseEnter={e => e.currentTarget.style.color = 'var(--fg)'}
          onMouseLeave={e => e.currentTarget.style.color = 'var(--fg-3)'}
        >
          ← The Journal
        </button>
      </div>

      {/* Full-bleed hero image */}
      <div style={{
        width: '100%',
        overflow: 'hidden',
        marginTop: 32,
        background: 'var(--surf)',
        maxHeight: mobile ? 'none' : '68vh',
      }}>
        <img
          src={entry.image}
          alt={entry.title}
          onError={e => { if (entry.fallback && e.currentTarget.src.indexOf(entry.fallback) < 0) e.currentTarget.src = entry.fallback; }}
          style={{
            width: '100%',
            height: mobile ? 'auto' : '68vh',
            objectFit: 'cover',
            objectPosition: entry.imgPos || 'center top',
            display: 'block',
          }}
        />
      </div>

      {/* Article body */}
      <div style={{
        maxWidth: 760, margin: '0 auto',
        padding: mobile ? '48px 24px 100px' : '72px 24px 140px',
      }}>
        <div className="mono" style={{
          fontSize: 10, letterSpacing: '.26em', textTransform: 'uppercase',
          color: 'var(--crimson)', marginBottom: 20,
        }}>
          {entry.category} · {entry.date}
        </div>
        <h1 className="display" style={{
          fontSize: 'clamp(48px, 7.5vw, 100px)', lineHeight: .95,
          margin: '0 0 44px', fontWeight: 400,
        }}>{entry.title}</h1>

        <div style={{ borderTop: '.5px solid var(--line)', paddingTop: 44 }}>
          {paragraphs.map((para, i) => (
            <p key={i} style={{
              fontSize: 16, lineHeight: 1.84, color: 'var(--fg-2)',
              margin: '0 0 28px',
            }}>{para}</p>
          ))}
        </div>

        {/* Product callout */}
        {product && (
          <div style={{
            marginTop: 56,
            padding: mobile ? '24px' : '32px 40px',
            border: '.5px solid var(--line)',
            display: 'flex',
            flexDirection: mobile ? 'column' : 'row',
            alignItems: mobile ? 'flex-start' : 'center',
            gap: mobile ? 20 : 32,
          }}>
            {product.images && product.images[0] && (
              <div style={{ width: 100, flexShrink: 0, background: 'var(--surf)' }}>
                <img
                  src={product.images[0]}
                  alt={product.frenchName || product.name}
                  style={{ width: '100%', display: 'block' }}
                />
              </div>
            )}
            <div style={{ flex: 1 }}>
              <div className="mono" style={{
                fontSize: 10, letterSpacing: '.2em', textTransform: 'uppercase',
                color: 'var(--fg-3)', marginBottom: 6,
              }}>
                Featured in this entry
              </div>
              <div style={{
                fontSize: 20, fontFamily: 'var(--font-display)',
                marginBottom: 4, fontWeight: 400,
              }}>
                {product.frenchName || product.name}
              </div>
              <div className="mono" style={{ color: 'var(--fg-3)', fontSize: 11, marginBottom: 22 }}>
                {loPrice(product.price)}
              </div>
              <button className="btn sm" onClick={() => goTo('product', { product })}>
                View the {product.frenchName || product.name} →
              </button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function Journal({ goTo }) {
  useFadeUp();
  const mobile = useMobile();
  const [selected, setSelected] = React.useState(null);

  if (selected) {
    return (
      <JournalEntry
        entry={selected}
        goTo={goTo}
        onBack={() => {
          setSelected(null);
          window.scrollTo({ top: 0, behavior: 'instant' });
        }}
      />
    );
  }

  return (
    <div>
      {/* Header */}
      <section style={{
        borderBottom: '.5px solid var(--line)',
        padding: mobile
          ? '100px 0 48px'
          : 'clamp(80px, 10vw, 160px) 0 clamp(48px, 5vw, 80px)',
      }}>
        <div className="container">
          <div className="eyebrow" style={{ marginBottom: 18 }}>◇ &nbsp; From the Atelier</div>
          <h1 className="display" style={{
            fontSize: 'clamp(72px, 14vw, 220px)',
            margin: 0, lineHeight: .9, fontWeight: 400,
          }}>The<br /><em>Journal</em></h1>
          <p style={{
            fontSize: 14, lineHeight: 1.75, color: 'var(--fg-2)',
            maxWidth: 460, marginTop: 28, marginBottom: 0,
          }}>
            Editorials, featured sets, and stories from the atelier — one entry at a time.
          </p>
        </div>
      </section>

      {/* Entry grid */}
      <section style={{ padding: mobile ? '56px 0 80px' : 'clamp(64px, 7vw, 120px) 0' }}>
        <div className="container">
          {JOURNAL_ENTRIES.length === 0 ? (
            <div style={{ textAlign: 'center', padding: '80px 0' }}>
              <div className="mono" style={{ color: 'var(--fg-3)', letterSpacing: '.18em' }}>
                Coming soon
              </div>
            </div>
          ) : (
            <div style={{
              display: 'grid',
              gridTemplateColumns: mobile ? '1fr'
                : JOURNAL_ENTRIES.length === 1 ? 'minmax(0, 680px)'
                : '1fr 1fr',
              gap: mobile ? 60 : 'clamp(48px, 5vw, 80px)',
            }}>
              {JOURNAL_ENTRIES.map(entry => (
                <JournalCard
                  key={entry.id}
                  entry={entry}
                  onClick={() => setSelected(entry)}
                />
              ))}
            </div>
          )}
        </div>
      </section>
    </div>
  );
}

// ── Shared editorial card (used by the home-page peel stack) ──────────
function JournalEditorialCard({ entry, goTo, onRead }) {
  const mobile = useMobile();
  const loPrice = useCurrency();
  const product = (window.PRODUCTS || []).find(p => p.id === entry.productId);
  return (
    <div style={{
      display: 'grid',
      gridTemplateColumns: mobile ? '1fr' : '1.05fr 1fr',
      height: '100%', background: 'var(--surf)',
    }}>
      <div style={{ position: 'relative', overflow: 'hidden', background: 'var(--bg)' }}>
        <img
          src={entry.image}
          alt={entry.title}
          draggable="false"
          onError={e => { if (entry.fallback && e.currentTarget.src.indexOf(entry.fallback) < 0) e.currentTarget.src = entry.fallback; }}
          style={{
            width: '100%', height: mobile ? 300 : '100%',
            objectFit: 'cover', objectPosition: entry.imgPos || 'center top', display: 'block',
          }}
        />
      </div>
      <div style={{
        padding: mobile ? '28px 24px 36px' : 'clamp(30px, 3vw, 54px)',
        display: 'flex', flexDirection: 'column', justifyContent: 'center',
      }}>
        <div className="mono" style={{
          fontSize: 10, letterSpacing: '.26em', textTransform: 'uppercase',
          color: 'var(--crimson)', marginBottom: 14,
        }}>
          {entry.category} · {entry.date}
        </div>
        <h2 className="display" style={{
          fontSize: mobile ? 'clamp(30px,8vw,44px)' : 'clamp(32px, 3.1vw, 52px)',
          lineHeight: 1, margin: '0 0 16px', fontWeight: 400,
        }}>{entry.title}</h2>
        <p style={{
          fontSize: 14, lineHeight: 1.7, color: 'var(--fg-2)',
          margin: '0 0 26px', maxWidth: 460,
        }}>{entry.excerpt}</p>

        {product && (
          <div style={{
            display: 'flex', gap: mobile ? 16 : 26,
            alignItems: 'stretch', flexWrap: 'wrap',
          }}>
            {/* The actual product — small, with its price */}
            <div style={{ width: mobile ? 150 : 184, flexShrink: 0 }}>
              <ProductCard product={product} goTo={goTo} />
            </div>
            <div style={{
              display: 'flex', flexDirection: 'column',
              justifyContent: 'center', gap: 12, minWidth: 168,
            }}>
              <button className="btn" onClick={() => goTo('product', { product })} style={{ whiteSpace: 'nowrap' }}>
                View the {product.frenchName || product.name} →
              </button>
              <button className="btn ghost sm" onClick={onRead} style={{ whiteSpace: 'nowrap' }}>
                Read in Journal →
              </button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

// ── Home-page peel stack ──────────────────────────────────────────────
// Desktop: cards are pinned after the hero and "peel" away on scroll —
// even-index cards swing off to the right, odd-index to the left, like
// pieces of leather being pulled aside, revealing a closing CTA.
// Mobile: a plain stacked layout with no scroll effect at all.
function JournalPeelStack({ goTo }) {
  const entries = window.JOURNAL_ENTRIES || [];
  const mobile = useMobile();
  const wrapRef = React.useRef(null);
  const stageRef = React.useRef(null);
  const cardRefs = React.useRef([]);

  React.useEffect(() => {
    if (mobile || entries.length === 0) return;
    let raf = null, lastProgress = -1;
    const render = (progress) => {
      cardRefs.current.forEach((cardEl, i) => {
        if (!cardEl) return;
        const local = progress - i;          // <0 waiting · 0–1 peeling · >1 gone
        const dir = i % 2 === 0 ? 1 : -1;     // even → right, odd → left
        if (local <= 0) {
          const depth = Math.min(-local, 3);
          cardEl.style.transformOrigin = 'center center';
          cardEl.style.transform = `translate(-50%, -50%) translateY(${depth * 16}px) scale(${(1 - depth * 0.05).toFixed(3)})`;
          cardEl.style.opacity = '1';
          cardEl.style.zIndex = String(100 - i);
          cardEl.style.boxShadow = '0 30px 70px rgba(0,0,0,.5)';
          cardEl.style.pointerEvents = depth < 0.5 ? 'auto' : 'none';
        } else if (local < 1) {
          const x = dir * local * 122;
          const rot = dir * local * 16;
          cardEl.style.transformOrigin = dir > 0 ? 'left center' : 'right center';
          cardEl.style.transform = `translate(-50%, -50%) translateX(${x}%) rotate(${rot}deg) scale(${(1 - local * 0.04).toFixed(3)})`;
          cardEl.style.opacity = String(local > 0.8 ? Math.max(0, 1 - (local - 0.8) / 0.2) : 1);
          cardEl.style.zIndex = '200';
          cardEl.style.boxShadow = `0 ${Math.round(30 + local * 60)}px ${Math.round(70 + local * 80)}px rgba(0,0,0,${(0.5 + local * 0.3).toFixed(2)})`;
          cardEl.style.pointerEvents = 'none';
        } else {
          cardEl.style.transform = `translate(-50%, -50%) translateX(${dir * 122}%) rotate(${dir * 16}deg)`;
          cardEl.style.opacity = '0';
          cardEl.style.zIndex = '0';
          cardEl.style.pointerEvents = 'none';
        }
      });
    };
    // rAF loop — scroller-agnostic (works whether window, <html> or a div
    // scrolls) and pauses automatically when the tab is hidden.
    const loop = () => {
      const el = wrapRef.current;
      if (el) {
        const vh = window.innerHeight;
        const rect = el.getBoundingClientRect();
        const total = el.offsetHeight - vh;
        const scrolledRaw = -rect.top;
        const scrolled = Math.min(Math.max(scrolledRaw, 0), total);
        // JS-driven pin via fixed/absolute. This avoids needing position:sticky,
        // so we don't have to globally enable sticky (which would make filter
        // bars etc. on OTHER pages pin too). The pin lives only here, on home.
        const stage = stageRef.current;
        if (stage) {
          if (scrolledRaw <= 0)            { stage.style.position = 'absolute'; stage.style.top = '0px'; }
          else if (scrolledRaw >= total)   { stage.style.position = 'absolute'; stage.style.top = total + 'px'; }
          else                             { stage.style.position = 'fixed';    stage.style.top = '0px'; }
        }
        const progress = total > 0 ? (scrolled / total) * entries.length : 0;
        if (Math.abs(progress - lastProgress) > 0.0008) { lastProgress = progress; render(progress); }
      }
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => { if (raf) cancelAnimationFrame(raf); };
  }, [mobile, entries.length]);

  if (entries.length === 0) return null;

  // ── Mobile: clean stacked layout, no effect ──
  if (mobile) {
    return (
      <section style={{ borderTop: '.5px solid var(--line)' }}>
        <div className="mono" style={{
          textAlign: 'center', padding: '40px 0 8px', fontSize: 11,
          letterSpacing: '.3em', textTransform: 'uppercase', color: 'var(--crimson)',
        }}>◇ &nbsp; From the Journal</div>
        {entries.map(entry => (
          <div key={entry.id} className="container" style={{ padding: '24px 0 40px' }}>
            <div style={{ border: '.5px solid var(--line)', borderRadius: 4, overflow: 'hidden' }}>
              <JournalEditorialCard entry={entry} goTo={goTo} onRead={() => goTo('journal')} />
            </div>
          </div>
        ))}
        <div style={{ textAlign: 'center', padding: '8px 0 56px' }}>
          <button className="btn" onClick={() => goTo('journal')}>Explore all entries →</button>
        </div>
      </section>
    );
  }

  // ── Desktop: pinned peel stack ──
  return (
    <section ref={wrapRef} style={{
      position: 'relative',
      height: `${entries.length * 100 + 60}vh`,
      background: 'linear-gradient(180deg, var(--surf) 0%, var(--bg) 100%)',
      borderTop: '.5px solid var(--line)',
    }}>
      <div ref={stageRef} style={{
        position: 'absolute', top: 0, left: 0, right: 0, height: '100vh', overflow: 'hidden',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        {/* Section eyebrow */}
        <div className="mono" style={{
          position: 'absolute', top: 'clamp(28px,5vh,60px)', left: 0, right: 0,
          textAlign: 'center', fontSize: 11, letterSpacing: '.32em',
          textTransform: 'uppercase', color: 'var(--crimson)', zIndex: 500,
          pointerEvents: 'none',
        }}>◇ &nbsp; From the Journal</div>

        {/* Closing CTA, revealed once every card has peeled away */}
        <div style={{
          position: 'absolute', textAlign: 'center', zIndex: 1,
          maxWidth: 540, padding: 24,
        }}>
          <h2 className="display" style={{
            fontSize: 'clamp(44px,5.5vw,92px)', margin: '0 0 18px',
            lineHeight: .95, fontWeight: 400,
          }}>The <em>Journal</em></h2>
          <p style={{ color: 'var(--fg-2)', fontSize: 14.5, lineHeight: 1.7, margin: '0 0 30px' }}>
            Stories, featured pieces, and dispatches from the atelier.
          </p>
          <button className="btn" onClick={() => goTo('journal')}>Explore all entries →</button>
        </div>

        {/* Peel cards */}
        {entries.map((entry, i) => (
          <div
            key={entry.id}
            ref={el => { cardRefs.current[i] = el; }}
            style={{
              position: 'absolute', left: '50%', top: '50%',
              transform: 'translate(-50%, -50%)',
              transformOrigin: 'center center',
              width: 'min(1200px, 94vw)', height: 'min(740px, 84vh)',
              border: '.5px solid var(--line)', borderRadius: 4, overflow: 'hidden',
              background: 'var(--surf)',
              zIndex: entries.length - i,
              boxShadow: '0 30px 70px rgba(0,0,0,.5)',
              willChange: 'transform, opacity',
            }}
          >
            <JournalEditorialCard entry={entry} goTo={goTo} onRead={() => goTo('journal')} />
          </div>
        ))}
      </div>
    </section>
  );
}

Object.assign(window, { Journal, JournalPeelStack, JOURNAL_ENTRIES });
