var {useState,useEffect,useRef,useCallback} = React;

/* ============================================================
   GALLERY / PORTFOLIO
   ============================================================ */
const SHOTS=[
  {t:"Heritage cottages",l:"Darjeeling, India",tone:"t-himalaya",src:"assets/gallery/darj-cottages.webp",h:0.75,cat:"India"},
  {t:"The Big Buddha",l:"Phuket, Thailand",tone:"t-night",src:"assets/gallery/thai-bigbuddha.webp",h:1.33,cat:"Thailand"},
  {t:"Colonial verandahs",l:"Darjeeling, India",tone:"t-night",src:"assets/gallery/darj-verandah.webp",h:0.56,cat:"India"},
  {t:"Phi Phi waters",l:"Krabi, Thailand",tone:"t-ocean",src:"assets/gallery/thai-phiphi.webp",h:1.33,cat:"Thailand"},
  {t:"The Swiss Hotel",l:"Darjeeling, India",tone:"t-rose",src:"assets/gallery/darj-swiss-hotel.webp",h:1.33,cat:"India"},
  {t:"Toy train at Ghum",l:"Darjeeling Himalayan Railway",tone:"t-himalaya",src:"assets/gallery/darj-toytrain.webp",h:0.75,cat:"India"},
  {t:"Wat Chalong",l:"Phuket, Thailand",tone:"t-sunset",src:"assets/gallery/thai-watchalong.webp",h:1.33,cat:"Thailand"},
  {t:"Castaway shore",l:"Krabi, Thailand",tone:"t-ocean",src:"assets/gallery/thai-beach.webp",h:1.33,cat:"Thailand"},
];

function GalleryHero(){
  return (
    <section className="gl-hero">
      <div className="wrap gl-hero-copy">
          <h1 className="display gl-hero-title">
            <span className="tline"><span style={{transitionDelay:'.1s'}}>The gallery</span></span>
            <span className="tline"><span style={{transitionDelay:'.2s'}}>&amp; <em className="serif-it tcolor">journals.</em></span></span>
          </h1>
          <window.Reveal variant="fade" delay={200} className="gl-hero-sub">
            <p className="lead col-moss">Frames from the field and stories from the road: a cinematic gallery of moments, and a hundred travel journals from across India and the world.</p>
          </window.Reveal>
      </div>
    </section>
  );
}

function SectionBand({title}){
  return (
    <div className="gl-band">
      <window.Reveal as="h2" className="gl-band-t">{title}</window.Reveal>
    </div>
  );
}

function Gallery({navigate}){
  const cats=["All","India","Thailand"];
  const [cat,setCat]=useState("All");
  const [light,setLight]=useState(null);
  const list=cat==="All"?SHOTS:SHOTS.filter(s=>s.cat===cat);

  const openAt=useCallback((shot)=>{
    setLight(SHOTS.indexOf(shot));
  },[]);
  const step=useCallback((d)=>{
    setLight(p=>{ if(p===null) return p; return (p+d+SHOTS.length)%SHOTS.length; });
  },[]);

  useEffect(()=>{
    if(light===null) return;
    const onKey=(e)=>{
      if(e.key==='Escape') setLight(null);
      if(e.key==='ArrowRight') step(1);
      if(e.key==='ArrowLeft') step(-1);
    };
    window.addEventListener('keydown',onKey);
    document.body.style.overflow='hidden';
    return ()=>{window.removeEventListener('keydown',onKey);document.body.style.overflow='';};
  },[light,step]);

  return (
    <section className="section tight gl-sec" id="gallery">
      <div className="wrap">
        <SectionBand title="Frames from the field"/>
        <div className="tabs-row">
          <div className="tabs">
            {cats.map(c=>(
              <button key={c} className={`tab ${cat===c?'on':''}`} onClick={()=>setCat(c)}>
                {c}{cat===c && <span className="tab-pill"></span>}
              </button>
            ))}
          </div>
          <span className="mono tabs-count">{String(list.length).padStart(2,'0')} frames</span>
        </div>

        <div className="masonry">
          {list.map((s,i)=>(
            <GalleryItem key={s.t} shot={s} index={i} onOpen={openAt}/>
          ))}
        </div>
      </div>

      {light!==null && (
        <Lightbox shot={SHOTS[light]} onClose={()=>setLight(null)} onStep={step}
                  index={light} total={SHOTS.length}/>
      )}
    </section>
  );
}

function GalleryItem({shot,index,onOpen}){
  const ref=window.useReveal({margin:'0px 0px -4% 0px'});
  return (
    <div ref={ref} className="reveal scale masonry-item" style={{transitionDelay:(index%3*70)+'ms'}}
         onClick={()=>onOpen(shot)}>
      <div className="frame mi-frame" style={{aspectRatio:'1 / '+shot.h}}>
        <div className={`ph-grad ${shot.tone}`}></div>
        <img src={shot.src} alt={shot.t} loading="lazy"
          style={{position:'absolute',inset:0,width:'100%',height:'100%',objectFit:'cover',zIndex:1}}/>
        <div className="ph-grain"></div>
        <div className="mi-over">
          <span className="mi-zoom"><window.Icon name="plus" size={22}/></span>
        </div>
      </div>
    </div>
  );
}

function Lightbox({shot,onClose,onStep,index,total}){
  return (
    <div className="lightbox" onClick={onClose}>
      <button className="lb-close" onClick={onClose} aria-label="Close"><window.Icon name="close" size={22}/></button>
      <button className="lb-arrow left" onClick={(e)=>{e.stopPropagation();onStep(-1);}} aria-label="Previous">
        <window.Icon name="arrow" size={24} style={{transform:'rotate(180deg)'}}/>
      </button>
      <div className="lb-stage" onClick={e=>e.stopPropagation()}>
        <div className="frame lb-frame" key={shot.t}>
          <div className={`ph-grad ${shot.tone}`}></div>
          <img src={shot.src} alt={shot.t}
            style={{position:'absolute',inset:0,width:'100%',height:'100%',objectFit:'cover',zIndex:1}}/>
          <div className="ph-grain"></div>
          <span className="ph-tag">{shot.cat.toUpperCase()}</span>
        </div>
        <div className="lb-meta">
          <div>
            <h3 className="h3">{shot.t}</h3>
            <span className="col-moss" style={{color:'rgba(238,244,250,.6)'}}><window.Icon name="pin" size={14}/> {shot.l}</span>
          </div>
          <span className="mono lb-count">{String(index+1).padStart(2,'0')} / {String(total).padStart(2,'0')}</span>
        </div>
      </div>
      <button className="lb-arrow right" onClick={(e)=>{e.stopPropagation();onStep(1);}} aria-label="Next">
        <window.Icon name="arrow" size={24}/>
      </button>
    </div>
  );
}

/* ============================================================
   JOURNALS ARCHIVE: search + region filter + pagination
   ============================================================ */
function goJournal(id){
  const c=document.getElementById('curtain');
  if(c){ c.classList.remove('reveal'); c.classList.add('cover'); }
  setTimeout(()=>{ window.location.href='journal.html?id='+id; }, 480);
}
const JR_PER_PAGE = 9;

function Journals(){
  const all = window.JOURNALS || [];
  const [region,setRegion] = useState("All");
  const [q,setQ] = useState("");
  const [page,setPage] = useState(1);
  const regions = ["All","India","International"];

  const query = q.trim().toLowerCase();
  const filtered = all.filter(a=>{
    if(region!=="All" && a.region!==region) return false;
    if(!query) return true;
    return (a.title+" "+a.location+" "+a.excerpt).toLowerCase().includes(query);
  });
  const pages = Math.max(1, Math.ceil(filtered.length/JR_PER_PAGE));
  const cur = Math.min(page, pages);
  const slice = filtered.slice((cur-1)*JR_PER_PAGE, cur*JR_PER_PAGE);

  // reset to page 1 whenever the filter/search changes
  useEffect(()=>{ setPage(1); },[region,q]);
  const gridRef = useRef(null);
  const toPage=(n)=>{ setPage(n); if(gridRef.current) window.scrollTo({top:gridRef.current.offsetTop-90,behavior:'smooth'}); };

  return (
    <section className="section tight jl-sec" id="journals">
      <div className="wrap">
        <SectionBand title="Stories from the road"/>

        <div className="jl-controls">
          <div className="tabs">
            {regions.map(r=>(
              <button key={r} className={`tab ${region===r?'on':''}`} onClick={()=>setRegion(r)}>
                {r}{region===r && <span className="tab-pill"></span>}
              </button>
            ))}
          </div>
          <div className="jl-search">
            <window.Icon name="search" size={16}/>
            <input value={q} onChange={e=>setQ(e.target.value)} placeholder="Search journals…"
              aria-label="Search journals"/>
            {q && <button className="jl-clear" onClick={()=>setQ("")} aria-label="Clear search"><window.Icon name="close" size={14}/></button>}
          </div>
        </div>

        <div className="jl-meta mono">
          {filtered.length===0 ? 'No journals match your search'
            : `Showing ${(cur-1)*JR_PER_PAGE+1}–${Math.min(cur*JR_PER_PAGE,filtered.length)} of ${filtered.length}`}
        </div>

        <div className="jl-grid" ref={gridRef}>
          {slice.map((a,i)=>(
            <window.Reveal key={a.id} delay={(i%3)*70} className="jl-card">
              <div className="jl-card-top">
                <span className="jl-eyebrow mono">{a.region} · {a.location}</span>
                <h3 className="jl-card-t">{a.title}</h3>
                <p className="jl-card-x col-moss">{a.excerpt}</p>
              </div>
              <button className="jl-open" onClick={()=>goJournal(a.id)}>
                Open journal <window.Icon name="arrow" size={15} className="arrow"/>
              </button>
            </window.Reveal>
          ))}
        </div>

        {pages>1 && (
          <div className="jl-pager">
            <button className="jl-pg-arrow" disabled={cur===1} onClick={()=>toPage(cur-1)} aria-label="Previous page">
              <window.Icon name="chevronLeft" size={18}/>
            </button>
            <div className="jl-pg-nums">
              {Array.from({length:pages},(_,k)=>k+1).map(n=>(
                <button key={n} className={`jl-pg ${n===cur?'on':''}`} onClick={()=>toPage(n)}>{n}</button>
              ))}
            </div>
            <button className="jl-pg-arrow" disabled={cur===pages} onClick={()=>toPage(cur+1)} aria-label="Next page">
              <window.Icon name="chevronRight" size={18}/>
            </button>
          </div>
        )}
      </div>
    </section>
  );
}

window.GalleryPage = function({navigate}){
  return (
    <div className="page-pad gallery">
      <GalleryHero/>
      <Gallery navigate={navigate}/>
      <Journals/>
    </div>
  );
};

/* ============================================================
   GALLERY STYLES
   ============================================================ */
(function(){
  if(document.getElementById('gl-style'))return;
  const s=document.createElement('style');s.id='gl-style';
  s.textContent=`
.gl-hero{padding:clamp(40px,7vw,90px) 0 clamp(26px,4vw,46px)}
.gl-hero-title{margin-top:20px}
.gl-hero-sub{max-width:52ch;margin-top:24px}

/* section band (Gallery / Journals dividers) */
.gl-band{margin-bottom:clamp(28px,4vw,44px);padding-bottom:24px;border-bottom:1px solid var(--line)}
.gl-band-t{font-size:clamp(26px,3.4vw,40px);font-weight:700;letter-spacing:-.025em;line-height:1.08;color:var(--ink)}

/* journals archive */
.jl-sec{padding-top:clamp(48px,7vw,90px)}
.jl-controls{display:flex;justify-content:space-between;align-items:center;gap:18px;flex-wrap:wrap;margin-bottom:14px}
.jl-search{display:flex;align-items:center;gap:9px;padding:10px 14px;border-radius:100px;min-width:240px;
  background:var(--cream);border:1px solid var(--line-strong);box-shadow:var(--shadow-sm)}
.jl-search svg{color:var(--accent-blue);flex:0 0 auto}
.jl-search input{flex:1;min-width:0;border:none;background:transparent;outline:none;color:var(--ink);
  font-family:inherit;font-size:14px;font-weight:500}
.jl-search input::placeholder{color:var(--moss)}
.jl-clear{display:flex;color:var(--moss);transition:color .3s}
.jl-clear:hover{color:var(--terra)}
.jl-meta{font-size:11.5px;letter-spacing:.08em;color:var(--moss);margin-bottom:20px}

.jl-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,2vw,24px)}
.jl-card{display:flex;flex-direction:column;justify-content:space-between;gap:20px;
  padding:clamp(22px,2vw,28px);border:1px solid var(--line);border-radius:18px;background:var(--cream);
  box-shadow:var(--shadow-sm);transition:transform .45s var(--ease-out),box-shadow .45s,border-color .45s}
.jl-card:hover{transform:translateY(-5px);box-shadow:var(--shadow);border-color:transparent}
.jl-eyebrow{font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--terra)}
.jl-card-t{font-size:19px;font-weight:700;letter-spacing:-.02em;line-height:1.22;margin-top:11px;color:var(--ink);text-wrap:balance}
.jl-card-x{font-size:13.5px;line-height:1.6;margin-top:11px;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.jl-open{align-self:flex-start;display:inline-flex;align-items:center;gap:8px;padding:9px 16px;border-radius:100px;
  background:var(--accent-blue);color:#fff;font-size:13px;font-weight:600;
  transition:background .3s,transform .3s}
.jl-open:hover{background:var(--ink);transform:translateX(2px)}
.jl-open .arrow{transition:transform .3s}
.jl-open:hover .arrow{transform:translateX(3px)}
@media(max-width:880px){.jl-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.jl-grid{grid-template-columns:1fr}.jl-controls{flex-direction:column;align-items:stretch}.jl-search{min-width:0}}

/* pagination */
.jl-pager{display:flex;align-items:center;justify-content:center;gap:10px;margin-top:clamp(36px,5vw,56px)}
.jl-pg-nums{display:flex;gap:6px;flex-wrap:wrap;justify-content:center}
.jl-pg{min-width:38px;height:38px;padding:0 10px;border-radius:10px;font-size:14px;font-weight:600;
  border:1px solid var(--line-strong);background:var(--cream);color:var(--ink);transition:all .3s}
.jl-pg:hover{border-color:var(--accent-blue);color:var(--accent-blue)}
.jl-pg.on{background:var(--accent-blue);border-color:transparent;color:#fff}
.jl-pg-arrow{width:38px;height:38px;border-radius:10px;display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line-strong);background:var(--cream);color:var(--ink);transition:all .3s}
.jl-pg-arrow:hover:not(:disabled){border-color:var(--accent-blue);color:var(--accent-blue)}
.jl-pg-arrow:disabled{opacity:.35;cursor:not-allowed}

.masonry{columns:3;column-gap:22px;margin-top:8px}
.masonry-item{break-inside:avoid;margin-bottom:22px;cursor:pointer}
.mi-frame{border-radius:16px;box-shadow:var(--shadow);transition:transform .6s var(--ease-out)}
.masonry-item:hover .mi-frame{transform:translateY(-5px)}
.mi-over{position:absolute;inset:0;z-index:3;display:flex;align-items:center;justify-content:center;
  background:rgba(12,17,56,.32);opacity:0;transition:opacity .45s}
.masonry-item:hover .mi-over{opacity:1}
.mi-zoom{width:58px;height:58px;border-radius:50%;background:rgba(255,255,255,.16);backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,.4);color:#fff;display:flex;align-items:center;justify-content:center;
  transform:scale(.7);transition:transform .45s var(--ease-out)}
.masonry-item:hover .mi-zoom{transform:scale(1)}
@media(max-width:900px){.masonry{columns:2}}
@media(max-width:560px){.masonry{columns:1}}

/* lightbox */
.lightbox{position:fixed;inset:0;z-index:9500;background:rgba(8,11,34,.92);backdrop-filter:blur(10px);
  display:flex;align-items:center;justify-content:center;padding:40px;animation:lbfade .35s ease}
@keyframes lbfade{from{opacity:0}to{opacity:1}}
.lb-close{position:absolute;top:26px;right:30px;width:52px;height:52px;border-radius:50%;
  border:1px solid rgba(255,255,255,.22);color:#fff;display:flex;align-items:center;justify-content:center;
  transition:all .4s var(--ease-out)}
.lb-close:hover{background:var(--terra);border-color:var(--terra);transform:rotate(90deg)}
.lb-arrow{position:absolute;top:50%;transform:translateY(-50%);width:58px;height:58px;border-radius:50%;
  border:1px solid rgba(255,255,255,.22);color:#fff;display:flex;align-items:center;justify-content:center;
  transition:all .4s var(--ease-out);z-index:2}
.lb-arrow.left{left:30px}.lb-arrow.right{right:30px}
.lb-arrow:hover{background:var(--terra);border-color:var(--terra)}
.lb-arrow.left:hover{transform:translateY(-50%) translateX(-3px)}
.lb-arrow.right:hover{transform:translateY(-50%) translateX(3px)}
.lb-stage{width:min(900px,80vw);animation:lbpop .45s var(--ease-out)}
@keyframes lbpop{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}
.lb-frame{aspect-ratio:16/10;border-radius:18px}
.lb-meta{display:flex;justify-content:space-between;align-items:flex-end;gap:20px;margin-top:22px;color:var(--cream)}
.lb-meta span{display:inline-flex;align-items:center;gap:6px}
.lb-count{color:var(--terra-soft);font-size:13px;letter-spacing:.08em}
@media(max-width:700px){
  .lb-arrow{width:46px;height:46px}.lb-arrow.left{left:12px}.lb-arrow.right{right:12px}
  .lb-stage{width:90vw}.lightbox{padding:20px}
}
`;
  document.head.appendChild(s);
})();
