/* global React, Icon, useT */
const { useState: useStateG, useEffect: useEffectG, useCallback: useCallbackG } = React;

/* ============== PHOTOS DATA ==============
   Each photo: src, cat (spaces|rooms|details), aspect (h or v),
   span (gridSpan: 1 or 2 cols), titleKey, descKey
*/
const PHOTOS = [
  // SPACES (8)
  { src:'img/fachada.jpeg',         cat:'spaces',  span:2, h:'tall',  tk:'p_facade_t',  dk:'p_facade_d' },
  { src:'img/cocina-comedor.jpeg',  cat:'spaces',  span:2, h:'tall',  tk:'p_kitchen_t', dk:'p_kitchen_d' },
  { src:'img/cocina-escalera.jpeg', cat:'spaces',  span:1, h:'tall',  tk:'p_stairs_t',  dk:'p_stairs_d' },
  { src:'img/cocina-cafetera.jpeg', cat:'spaces',  span:1, h:'med',   tk:'p_coffee_t',  dk:'p_coffee_d' },
  { src:'img/salon-01.jpeg',        cat:'spaces',  span:1, h:'med',   tk:'p_lounge1_t', dk:'p_lounge1_d' },
  { src:'img/salon-02.jpeg',        cat:'spaces',  span:1, h:'med',   tk:'p_lounge2_t', dk:'p_lounge2_d' },
  { src:'img/patio.jpeg',           cat:'spaces',  span:2, h:'wide',  tk:'p_patio_t',   dk:'p_patio_d' },
  { src:'img/bajo-cubierta.jpeg',   cat:'spaces',  span:2, h:'wide',  tk:'p_attic_t',   dk:'p_attic_d' },
  { src:'img/comedor-sofa.jpeg',    cat:'spaces',  span:2, h:'tall',  tk:'p_dinesofa_t',  dk:'p_dinesofa_d' },
  { src:'img/comedor-vigas.jpeg',   cat:'spaces',  span:1, h:'tall',  tk:'p_dinebeams_t', dk:'p_dinebeams_d' },
  { src:'img/salon-tv.jpeg',        cat:'spaces',  span:1, h:'med',   tk:'p_loungetv_t',  dk:'p_loungetv_d' },
  { src:'img/cocina-office.jpeg',   cat:'spaces',  span:1, h:'med',   tk:'p_kitoffice_t', dk:'p_kitoffice_d' },
  // ROOMS (5) — portrait photos, mark as tall so they get 2 rows
  { src:'img/hab-01.jpeg', cat:'rooms', span:1, h:'tall', tk:'p_h01_t', dk:'p_h01_d' },
  { src:'img/hab-02.jpeg', cat:'rooms', span:1, h:'tall', tk:'p_h02_t', dk:'p_h02_d' },
  { src:'img/hab-03.jpeg', cat:'rooms', span:1, h:'tall', tk:'p_h03_t', dk:'p_h03_d' },
  { src:'img/hab-04.jpeg', cat:'rooms', span:1, h:'tall', tk:'p_h04_t', dk:'p_h04_d' },
  { src:'img/hab-05.jpeg', cat:'rooms', span:1, h:'tall', tk:'p_h05_t', dk:'p_h05_d' },
  // DETAILS (4)
  { src:'img/bajo-cubierta.jpeg',  cat:'details', span:1, h:'med',  tk:'p_hgarret_t', dk:'p_hgarret_d' },
  { src:'img/rincon.jpeg',          cat:'details', span:1, h:'med',  tk:'p_corner_t',  dk:'p_corner_d' },
  { src:'img/rincon-lectura.jpeg',  cat:'details', span:1, h:'med',  tk:'p_readchair_t', dk:'p_readchair_d' },
  { src:'img/bano.jpeg',            cat:'details', span:1, h:'tall', tk:'p_bath1_t',   dk:'p_bath1_d' },
  { src:'img/bano-amarillo.jpeg',   cat:'details', span:1, h:'tall', tk:'p_bath2_t',   dk:'p_bath2_d' },
];

/* ============== HEADER ============== */
function GalleryHeader() {
  const { t } = useT();
  return (
    <section style={GH.wrap}>
      <div style={GH.inner}>
        <a href="index.html" style={GH.back}>
          <span style={{transform:'rotate(180deg)', display:'inline-flex'}}><Icon name="arrow" size={14}/></span>
          {t('gal_back')}
        </a>
        <div style={GH.eyebrow}>{t('gal_eyebrow')}</div>
        <h1 style={GH.h1}>{t('gal_h1_a')}<br/>{t('gal_h1_b')}</h1>
        <p style={GH.lede}>{t('gal_lede')}</p>
      </div>
    </section>
  );
}
const GH = {
  wrap:{ background:'#F5C801', color:'#1A1A1A', padding:'72px 28px 80px' },
  inner:{ maxWidth:1280, margin:'0 auto' },
  back:{ display:'inline-flex', alignItems:'center', gap:8, fontFamily:'Montserrat, sans-serif', fontWeight:700,
         fontSize:12, letterSpacing:'.15em', textTransform:'uppercase', color:'#1A1A1A',
         textDecoration:'none', marginBottom:32 },
  eyebrow:{ fontFamily:'Montserrat, sans-serif', fontWeight:700, fontSize:12, letterSpacing:'.25em', textTransform:'uppercase' },
  h1:{ fontFamily:'Montserrat, sans-serif', fontWeight:900, fontSize:'clamp(40px,5vw,76px)', lineHeight:.95,
       letterSpacing:'-0.02em', margin:'18px 0 22px', textTransform:'uppercase' },
  lede:{ fontFamily:'Inter, sans-serif', fontSize:'clamp(15px,1.2vw,18px)', maxWidth:680, lineHeight:1.55, margin:0 },
};

/* ============== FILTER BAR ============== */
function FilterBar({ filter, setFilter, count }) {
  const { t } = useT();
  const filters = [
    ['all',     t('gal_filter_all')],
    ['spaces',  t('gal_filter_spaces')],
    ['rooms',   t('gal_filter_rooms')],
    ['details', t('gal_filter_details')],
  ];
  const countLbl = count === 1 ? t('gal_count_one') : t('gal_count_n').replace('{n}', count);
  return (
    <div style={FB.wrap}>
      <div style={FB.inner}>
        <div style={FB.chips}>
          {filters.map(([k, lbl]) => (
            <button key={k} onClick={()=>setFilter(k)}
                    style={{...FB.chip, ...(filter===k ? FB.chipActive : null)}}>
              {lbl}
            </button>
          ))}
        </div>
        <div style={FB.count}>{countLbl}</div>
      </div>
    </div>
  );
}
const FB = {
  wrap:{ position:'sticky', top:60, zIndex:40, background:'rgba(255,255,255,.92)', backdropFilter:'blur(10px)',
         borderBottom:'1px solid #ECECEC' },
  inner:{ maxWidth:1280, margin:'0 auto', padding:'14px 28px', display:'flex',
          justifyContent:'space-between', alignItems:'center', gap:20, flexWrap:'wrap' },
  chips:{ display:'flex', gap:8, flexWrap:'wrap' },
  chip:{ background:'transparent', border:'1px solid #E5E5E5', color:'#2B2B2B',
         padding:'8px 16px', borderRadius:999, cursor:'pointer',
         fontFamily:'Montserrat, sans-serif', fontWeight:700, fontSize:12,
         letterSpacing:'.1em', textTransform:'uppercase', transition:'all .15s' },
  chipActive:{ background:'#1A1A1A', color:'#F5C801', borderColor:'#1A1A1A' },
  count:{ fontFamily:'ui-monospace, monospace', fontSize:12, color:'#6B6B6B', letterSpacing:'.05em' },
};

/* ============== GRID ============== */
function GalleryGrid({ photos, onOpen }) {
  const { t } = useT();
  return (
    <section style={GR.wrap}>
      <div style={GR.grid}>
        {photos.map((p, i) => {
          const span = p.span === 2 ? 'span 2' : 'span 1';
          const rowSpan = p.h === 'tall' ? 'span 2' : 'span 1';
          return (
            <button key={p.src + i} style={{...GR.cell, gridColumn:span, gridRow:rowSpan}}
                    onClick={()=>onOpen(i)} aria-label={t(p.tk)}>
              <img src={p.src} alt={t(p.tk)} style={GR.img} loading="lazy"/>
              <div style={GR.lbl}>{t(p.tk)}</div>
              <div style={GR.overlay}>
                <div style={GR.cellTitle}>{t(p.dk)}</div>
              </div>
            </button>
          );
        })}
      </div>
    </section>
  );
}
const GR = {
  wrap:{ padding:'40px 28px 80px', maxWidth:1280, margin:'0 auto' },
  grid:{ display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gridAutoRows:'210px',
         gridAutoFlow:'dense', gap:12 },
  cell:{ position:'relative', overflow:'hidden', borderRadius:14, padding:0, border:'none',
         background:'#F4F4F4', cursor:'pointer', display:'block' },
  img:{ position:'absolute', inset:0, width:'100%', height:'100%', objectFit:'cover',
        transition:'transform .5s ease' },
  lbl:{ position:'absolute', bottom:12, left:12, background:'#1A1A1A', color:'#F5C801',
        padding:'5px 10px', fontFamily:'Montserrat, sans-serif', fontWeight:700, fontSize:10,
        letterSpacing:'.1em', textTransform:'uppercase', borderRadius:4, zIndex:2 },
  overlay:{ position:'absolute', inset:0,
            background:'linear-gradient(180deg, transparent 40%, rgba(0,0,0,.7) 100%)',
            display:'flex', alignItems:'flex-end', padding:'14px 14px 44px',
            opacity:0, transition:'opacity .2s' },
  cellTitle:{ color:'#fff', fontFamily:'Inter, sans-serif', fontWeight:500, fontSize:13,
              lineHeight:1.4 },
};

/* ============== LIGHTBOX ============== */
function Lightbox({ photos, index, onClose, onPrev, onNext }) {
  const { t } = useT();
  const isOpen = index !== -1;
  useEffectG(() => {
    if (!isOpen) return;
    const onKey = (e) => {
      if (e.key === 'Escape') onClose();
      else if (e.key === 'ArrowLeft') onPrev();
      else if (e.key === 'ArrowRight') onNext();
    };
    document.addEventListener('keydown', onKey);
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.removeEventListener('keydown', onKey);
      document.body.style.overflow = prevOverflow;
    };
  }, [isOpen, onClose, onPrev, onNext]);

  // Touch swipe
  const touch = React.useRef({ x:0, y:0 });
  const onTouchStart = (e) => { touch.current = { x:e.touches[0].clientX, y:e.touches[0].clientY }; };
  const onTouchEnd = (e) => {
    const dx = e.changedTouches[0].clientX - touch.current.x;
    const dy = e.changedTouches[0].clientY - touch.current.y;
    if (Math.abs(dx) > 60 && Math.abs(dx) > Math.abs(dy)) {
      if (dx > 0) onPrev(); else onNext();
    }
  };

  if (index === -1) return null;
  const p = photos[index];

  return (
    <div style={LB.backdrop} onClick={onClose}
         onTouchStart={onTouchStart} onTouchEnd={onTouchEnd}>
      <button style={{...LB.btn, ...LB.close}} onClick={(e)=>{e.stopPropagation();onClose();}} aria-label={t('gal_close')}>×</button>
      <button style={{...LB.btn, ...LB.prev}} onClick={(e)=>{e.stopPropagation();onPrev();}} aria-label={t('gal_prev')}>
        <span style={{transform:'rotate(180deg)', display:'inline-flex'}}><Icon name="arrow" size={20}/></span>
      </button>
      <button style={{...LB.btn, ...LB.next}} onClick={(e)=>{e.stopPropagation();onNext();}} aria-label={t('gal_next')}>
        <Icon name="arrow" size={20}/>
      </button>

      <div style={LB.frame} onClick={(e)=>e.stopPropagation()}>
        <img src={p.src} alt={t(p.tk)} style={LB.img} decoding="async"/>
        <div style={LB.cap}>
          <div style={LB.capL}>
            <div style={LB.capT}>{t(p.tk)}</div>
            <div style={LB.capD}>{t(p.dk)}</div>
          </div>
          <div style={LB.capR}>{String(index+1).padStart(2,'0')} / {String(photos.length).padStart(2,'0')}</div>
        </div>
      </div>
    </div>
  );
}
const LB = {
  backdrop:{ position:'fixed', inset:0, background:'rgba(15,15,15,.96)', zIndex:1000,
             display:'flex', alignItems:'center', justifyContent:'center', padding:'40px 60px' },
  frame:{ position:'relative', maxWidth:'min(1200px, 100%)', maxHeight:'100%',
          display:'flex', flexDirection:'column', gap:14, alignItems:'center' },
  img:{ maxWidth:'100%', maxHeight:'calc(100vh - 180px)', objectFit:'contain', borderRadius:8,
        boxShadow:'0 30px 80px rgba(0,0,0,.5)' },
  cap:{ display:'flex', justifyContent:'space-between', alignItems:'flex-end', gap:24,
        width:'100%', color:'#fff', maxWidth:900 },
  capL:{ flex:1 },
  capT:{ fontFamily:'Montserrat, sans-serif', fontWeight:800, fontSize:18, color:'#F5C801',
         letterSpacing:'.02em', textTransform:'uppercase', marginBottom:6 },
  capD:{ fontFamily:'Inter, sans-serif', fontSize:14, color:'#D9D9D9', lineHeight:1.5 },
  capR:{ fontFamily:'ui-monospace, monospace', fontSize:13, color:'rgba(255,255,255,.5)', letterSpacing:'.05em',
         flex:'0 0 auto' },
  btn:{ position:'fixed', background:'rgba(255,255,255,.08)', border:'1px solid rgba(255,255,255,.18)',
        color:'#fff', cursor:'pointer', backdropFilter:'blur(8px)',
        display:'flex', alignItems:'center', justifyContent:'center', borderRadius:999 },
  close:{ top:24, right:24, width:48, height:48, fontFamily:'Montserrat, sans-serif', fontWeight:700, fontSize:28, lineHeight:1 },
  prev:{ left:20, top:'50%', transform:'translateY(-50%)', width:52, height:52 },
  next:{ right:20, top:'50%', transform:'translateY(-50%)', width:52, height:52 },
};

/* ============== APP ============== */
function GalleryApp() {
  const [filter, setFilter] = useStateG('all');
  const [open, setOpen] = useStateG(-1);
  const photos = filter === 'all' ? PHOTOS : PHOTOS.filter(p => p.cat === filter);
  const onOpen = useCallbackG((i) => setOpen(i), []);
  const onClose = useCallbackG(() => setOpen(-1), []);
  const onPrev = useCallbackG(() => setOpen(i => (i - 1 + photos.length) % photos.length), [photos.length]);
  const onNext = useCallbackG(() => setOpen(i => (i + 1) % photos.length), [photos.length]);

  // Reset open if filter changes
  useEffectG(() => { setOpen(-1); }, [filter]);

  return (
    <div data-screen-label="Website · Gallery">
      <Nav/>
      <GalleryHeader/>
      <FilterBar filter={filter} setFilter={setFilter} count={photos.length}/>
      <GalleryGrid photos={photos} onOpen={onOpen}/>
      <Lightbox photos={photos} index={open} onClose={onClose} onPrev={onPrev} onNext={onNext}/>
      <ReservarHome/>
      <Footer/>
    </div>
  );
}

window.GalleryApp = GalleryApp;
