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

// ============== Brand SVG icons (no emojis) ==============
const CP_ICONS = {
  breakfast: () => (
    <svg viewBox="0 0 64 64" width="34" height="34" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <path d="M26 10c2 3-2 5 0 8M32 8c2 3-2 5 0 8M38 10c2 3-2 5 0 8" opacity="0.85"/>
      <path d="M18 24h28l-2 18a8 8 0 0 1-8 7h-8a8 8 0 0 1-8-7z"/>
      <ellipse cx="32" cy="26" rx="13" ry="2.2"/>
      <path d="M30 26c1-1 3-1 4 0" opacity="0.6"/>
      <path d="M46 28c5 0 8 3 8 7s-3 7-8 7"/>
      <path d="M14 53h36"/>
      <path d="M12 53c0 2 4 3 20 3s20-1 20-3" opacity="0.7"/>
    </svg>
  ),
  lunch: () => (
    <svg viewBox="0 0 64 64" width="34" height="34" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <path d="M44 6c-1 4 0 8 3 9s4-5 3-9z" opacity="0.85"/>
      <path d="M47 15v9M43 24h8" opacity="0.85"/>
      <circle cx="32" cy="38" r="16"/>
      <circle cx="32" cy="38" r="11" opacity="0.55"/>
      <path d="M14 24v10a4 4 0 0 0 4 4v18"/>
      <path d="M18 24v8M22 24v10a4 4 0 0 1-4 4"/>
      <path d="M50 24c-3 4-4 9-4 14h4z"/>
      <path d="M48 38v18"/>
    </svg>
  ),
  google: () => (
    <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
      <path fill="#4285F4" d="M23.49 12.27c0-.79-.07-1.54-.2-2.27H12v4.51h6.45c-.28 1.45-1.13 2.68-2.4 3.5v2.91h3.88c2.27-2.09 3.56-5.17 3.56-8.65z"/>
      <path fill="#34A853" d="M12 24c3.24 0 5.96-1.07 7.95-2.91l-3.88-2.91c-1.07.72-2.45 1.16-4.07 1.16-3.13 0-5.78-2.11-6.73-4.96H1.27v3.09C3.25 21.31 7.31 24 12 24z"/>
      <path fill="#FBBC04" d="M5.27 14.38a7.21 7.21 0 0 1 0-4.76V6.53H1.27a12 12 0 0 0 0 10.94l4-3.09z"/>
      <path fill="#EA4335" d="M12 4.75c1.77 0 3.35.61 4.6 1.8l3.43-3.43C17.95 1.19 15.24 0 12 0 7.31 0 3.25 2.69 1.27 6.53l4 3.09C6.22 6.86 8.87 4.75 12 4.75z"/>
    </svg>
  ),
  star: () => (
    <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor" stroke="none" aria-hidden="true">
      <path d="M12 2.5l1.7 8.8 8.8 1.7-8.8 1.7L12 21.5l-1.7-8.8L1.5 11l8.8-1.7z"/>
    </svg>
  )
};

// ============== Logo SVG ==============
function Logo({ size = 1, animated = false }) {
  return (
    <svg viewBox="0 0 320 140" style={{ width: 200 * size, height: 'auto', display: 'block' }} className={animated ? 'logo-anim' : ''}>
      <defs>
        <linearGradient id="goldGrad" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="#f0dfb5"/>
          <stop offset="40%" stopColor="#e6c98a"/>
          <stop offset="60%" stopColor="#c9a86a"/>
          <stop offset="100%" stopColor="#9c7d44"/>
        </linearGradient>
      </defs>
      <text x="40" y="62" fontFamily="Cormorant Garamond, serif" fontStyle="italic" fontWeight="500" fontSize="34" fill="url(#goldGrad)">can</text>
      <text x="100" y="78" fontFamily="Cormorant Garamond, serif" fontWeight="600" fontSize="86" fill="url(#goldGrad)" letterSpacing="-2">P</text>
      <text x="146" y="92" fontFamily="Cormorant Garamond, serif" fontStyle="italic" fontWeight="500" fontSize="46" fill="url(#goldGrad)">e</text>
      <text x="172" y="78" fontFamily="Cormorant Garamond, serif" fontWeight="600" fontSize="86" fill="url(#goldGrad)" letterSpacing="-2">T</text>
      <text x="210" y="92" fontFamily="Cormorant Garamond, serif" fontStyle="italic" fontWeight="500" fontSize="46" fill="url(#goldGrad)">it</text>
      <text x="246" y="78" fontFamily="Cormorant Garamond, serif" fontWeight="600" fontSize="86" fill="url(#goldGrad)" letterSpacing="-2">A</text>
      <path d="M 36 100 Q 160 118 290 92" stroke="url(#goldGrad)" strokeWidth="3" fill="none" strokeLinecap="round"/>
    </svg>
  );
}

// ============== Cursor (desktop only) ==============
function Cursor() {
  const haloRef = useRef(null);
  const dotRef = useRef(null);
  useEffect(() => {
    if (window.matchMedia('(hover: none)').matches) return;
    let raf, tx = 0, ty = 0, hx = 0, hy = 0;
    const move = (e) => {
      tx = e.clientX; ty = e.clientY;
      if (dotRef.current) {
        dotRef.current.style.left = tx + 'px';
        dotRef.current.style.top = ty + 'px';
        dotRef.current.classList.add('visible');
        haloRef.current.classList.add('visible');
      }
    };
    const tick = () => {
      hx += (tx - hx) * 0.18;
      hy += (ty - hy) * 0.18;
      if (haloRef.current) {
        haloRef.current.style.left = hx + 'px';
        haloRef.current.style.top = hy + 'px';
      }
      raf = requestAnimationFrame(tick);
    };
    const enter = (e) => {
      if (e.target.closest && e.target.closest('a, button, .menu-tab, .tile, input, select, textarea, label, .nav-logo')) {
        haloRef.current?.classList.add('hover');
      }
    };
    const leave = (e) => {
      if (e.target.closest && e.target.closest('a, button, .menu-tab, .tile, input, select, textarea, label, .nav-logo')) {
        haloRef.current?.classList.remove('hover');
      }
    };
    window.addEventListener('mousemove', move, { passive: true });
    document.addEventListener('mouseover', enter);
    document.addEventListener('mouseout', leave);
    tick();
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('mousemove', move);
      document.removeEventListener('mouseover', enter);
      document.removeEventListener('mouseout', leave);
    };
  }, []);
  return (
    <>
      <div ref={haloRef} className="cursor-halo"/>
      <div ref={dotRef} className="cursor-dot"/>
    </>
  );
}

// ============== Nav (with mobile drawer) ==============
function Nav({ t, lang, setLang }) {
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 60);
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  useEffect(() => {
    document.body.style.overflow = open ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [open]);
  const langs = ['ca', 'es', 'en', 'fr', 'nl'];
  const close = () => setOpen(false);
  return (
    <>
      <nav className={`nav ${scrolled ? 'scrolled' : ''}`}>
        <a href="#top" className="nav-logo" onClick={close}>
          <span style={{ fontStyle: 'italic' }}>can</span><b>Petita</b>
        </a>
        <div className="nav-links">
          <a href="#story">{t.nav.story}</a>
          <a href="#breakfast">{t.nav.breakfast}</a>
          <a href="#lunch">{t.nav.lunch}</a>
          <a href="#gallery">{t.nav.gallery}</a>
          <a href="#visit">{t.nav.visit}</a>
          <button type="button" className="nav-manage" onClick={() => window.dispatchEvent(new CustomEvent('cp:open-manage'))}>
            <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <rect x="3" y="4.5" width="18" height="17" rx="2"/>
              <path d="M16 2.5v4M8 2.5v4M3 10h18" opacity="0.85"/>
              <circle cx="12" cy="15" r="1.4" fill="currentColor"/>
            </svg>
            <span>{t.nav.manage || t.reserve.floaterLabel || 'Mi reserva'}</span>
          </button>
          <div className="lang">
            {langs.map(l => (
              <button key={l} className={lang === l ? 'active' : ''} onClick={() => setLang(l)} aria-label={`Language ${l}`}>{l}</button>
            ))}
          </div>
          <a href="#reserve" className="book-pill">{t.nav.reserve}</a>
          <button className="nav-burger" onClick={() => setOpen(true)} aria-label="Menu">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6"><line x1="4" y1="7" x2="20" y2="7"/><line x1="4" y1="13" x2="20" y2="13"/><line x1="4" y1="19" x2="20" y2="19"/></svg>
          </button>
        </div>
      </nav>

      <div className={`drawer-backdrop ${open ? 'show' : ''}`} onClick={close}/>
      <aside className={`nav-drawer ${open ? 'open' : ''}`} aria-hidden={!open}>
        <button className="drawer-close" onClick={close} aria-label="Close">×</button>
        <a href="#story" onClick={close}>{t.nav.story}</a>
        <a href="#breakfast" onClick={close}>{t.nav.breakfast}</a>
        <a href="#lunch" onClick={close}>{t.nav.lunch}</a>
        <a href="#gallery" onClick={close}>{t.nav.gallery}</a>
        <a href="#visit" onClick={close}>{t.nav.visit}</a>
        <button type="button" className="drawer-manage" onClick={() => { close(); window.dispatchEvent(new CustomEvent('cp:open-manage')); }}>
          <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
            <rect x="3" y="4.5" width="18" height="17" rx="2"/>
            <path d="M16 2.5v4M8 2.5v4M3 10h18" opacity="0.85"/>
            <circle cx="12" cy="15" r="1.4" fill="currentColor"/>
          </svg>
          <span>{t.nav.manage || t.reserve.floaterLabel || 'Mi reserva'}</span>
        </button>
        <div className="lang">
          {langs.map(l => (
            <button key={l} className={lang === l ? 'active' : ''} onClick={() => { setLang(l); close(); }}>{l}</button>
          ))}
        </div>
        <a href="#reserve" className="book-pill" onClick={close}>{t.nav.reserve} →</a>
      </aside>
    </>
  );
}

// ============== Hero language switcher (mobile only) — reactive ==============
function HeroLangSwitcher({ lang, setLang }) {
  const langs = ['ca', 'es', 'en', 'fr', 'nl'];
  return (
    <div className="hero-lang">
      {langs.map(l => (
        <button
          key={l}
          className={lang === l ? 'active' : ''}
          onClick={() => setLang(l)}
          aria-label={`Idioma ${l}`}
        >{l}</button>
      ))}
    </div>
  );
}

// ============== Hero ==============
function Hero({ t, lang, setLang }) {
  const heroRef = useRef(null);
  useEffect(() => {
    if (window.matchMedia('(hover: none)').matches) return;
    const onMove = (e) => {
      if (!heroRef.current) return;
      const r = heroRef.current.getBoundingClientRect();
      const x = (e.clientX - r.left) / r.width - 0.5;
      const y = (e.clientY - r.top) / r.height - 0.5;
      heroRef.current.style.setProperty('--mx', x);
      heroRef.current.style.setProperty('--my', y);
    };
    const el = heroRef.current;
    el?.addEventListener('mousemove', onMove);
    return () => el?.removeEventListener('mousemove', onMove);
  }, []);
  return (
    <section className="hero" id="top" ref={heroRef}>
      <div className="hero-bg-grain"/>
      <div className="hero-orb a" style={{ transform: 'translate(calc(var(--mx, 0) * 30px), calc(var(--my, 0) * 30px))' }}/>
      <div className="hero-orb b" style={{ transform: 'translate(calc(var(--mx, 0) * -20px), calc(var(--my, 0) * -20px))' }}/>
      <div className="hero-inner">
        {t.hero.badge && (
          <div className="hero-badge">{t.hero.badge}</div>
        )}
        <div className="hero-eyebrow">
          <span className="eyebrow">{t.hero.eyebrow}</span>
        </div>
        {/* Mobile-only language switcher (visible only when burger is shown) */}
        <HeroLangSwitcher lang={lang} setLang={setLang}/>
        <h1 className="hero-title">
          <span className="word">{t.hero.title}</span>
          <span className="and">{t.hero.titleAnd}</span>
          <span className="word">{t.hero.title2}</span>
        </h1>
        <p className="hero-sub">{t.hero.sub}</p>
        <div className="hero-ctas">
          <a href="#reserve" className="btn btn-gold">{t.hero.cta} <span className="arrow">→</span></a>
        </div>
        <div className="hero-cta-cards">
          <a href="#breakfast" className="cta-card">
            <span className="cta-card-icon"><CP_ICONS.breakfast/></span>
            <span className="cta-card-text">
              <span className="cta-card-eyebrow">{t.hero.discover || 'descubre'}</span>
              <span className="cta-card-label">{t.hero.ctaBreakfast || t.nav.breakfast}</span>
            </span>
            <span className="cta-card-arrow">→</span>
          </a>
          <a href="#lunch" className="cta-card">
            <span className="cta-card-icon"><CP_ICONS.lunch/></span>
            <span className="cta-card-text">
              <span className="cta-card-eyebrow">{t.hero.discover || 'descubre'}</span>
              <span className="cta-card-label">{t.hero.ctaLunch || t.nav.lunch}</span>
            </span>
            <span className="cta-card-arrow">→</span>
          </a>
        </div>
      </div>
      <div className="hero-scroll">
        <span className="label">{t.hero.scroll}</span>
        <span className="mouse"/>
      </div>
    </section>
  );
}

// ============== Section Divider — coastal/ornamental transitions between sections ==============
function SectionDivider({ variant = 'wave' }) {
  if (variant === 'wave') {
    return (
      <div className="cp-divider cp-divider-wave" aria-hidden="true">
        <svg viewBox="0 0 1440 140" preserveAspectRatio="none">
          <defs>
            <linearGradient id="cpd-wave-a" x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%" stopColor="rgba(15, 51, 41, 1)"/>
              <stop offset="100%" stopColor="rgba(20, 59, 48, 1)"/>
            </linearGradient>
            <linearGradient id="cpd-wave-b" x1="0" y1="0" x2="1" y2="0">
              <stop offset="0%" stopColor="rgba(109, 191, 163, 0.10)"/>
              <stop offset="50%" stopColor="rgba(212, 175, 86, 0.14)"/>
              <stop offset="100%" stopColor="rgba(109, 191, 163, 0.10)"/>
            </linearGradient>
          </defs>
          <path className="cpd-wave-back" d="M0 70 Q120 30 260 55 T540 55 T820 55 T1100 55 T1440 55 L1440 140 L0 140 Z" fill="rgba(109, 191, 163, 0.08)"/>
          <path className="cpd-wave-mid"  d="M0 90 Q140 55 290 80 T580 80 T870 80 T1160 80 T1440 80 L1440 140 L0 140 Z" fill="rgba(212, 175, 86, 0.07)"/>
          <path className="cpd-wave-front" d="M0 110 Q160 80 320 100 T640 100 T960 100 T1280 100 T1440 100 L1440 140 L0 140 Z" fill="url(#cpd-wave-a)"/>
        </svg>
      </div>
    );
  }
  if (variant === 'ridge') {
    return (
      <div className="cp-divider cp-divider-ridge" aria-hidden="true">
        <svg viewBox="0 0 1440 110" preserveAspectRatio="none">
          <path d="M0 110 L0 80 Q60 70 110 60 T220 50 Q280 40 340 55 T450 60 Q520 50 590 35 T720 30 Q800 25 880 45 T1010 55 Q1080 50 1150 30 T1290 25 Q1370 28 1440 45 L1440 110 Z" fill="rgba(109, 191, 163, 0.10)"/>
          <path d="M0 110 L0 95 Q70 88 130 82 T260 75 Q320 70 390 80 T520 85 Q600 78 680 65 T820 60 Q900 58 980 72 T1120 80 Q1200 76 1280 65 T1440 70 L1440 110 Z" fill="rgba(212, 175, 86, 0.06)"/>
        </svg>
      </div>
    );
  }
  if (variant === 'tide') {
    return (
      <div className="cp-divider cp-divider-tide" aria-hidden="true">
        <svg viewBox="0 0 1440 90" preserveAspectRatio="none">
          <path d="M0 60 Q360 20 720 50 T1440 40 L1440 90 L0 90 Z" fill="rgba(109, 191, 163, 0.10)"/>
          <path d="M0 75 Q360 50 720 70 T1440 60 L1440 90 L0 90 Z" fill="rgba(212, 175, 86, 0.05)"/>
        </svg>
        <span className="cpd-tide-spark" style={{ left: '18%' }}/>
        <span className="cpd-tide-spark" style={{ left: '42%' }}/>
        <span className="cpd-tide-spark" style={{ left: '67%' }}/>
        <span className="cpd-tide-spark" style={{ left: '83%' }}/>
      </div>
    );
  }
  // ornament: gold art-deco line + central glyph
  return (
    <div className="cp-divider cp-divider-ornament" aria-hidden="true">
      <span className="cpd-line"/>
      <span className="cpd-glyph">
        <svg viewBox="0 0 60 24" width="64" height="22" fill="none" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M2 12h18" opacity="0.6"/>
          <path d="M40 12h18" opacity="0.6"/>
          <circle cx="30" cy="12" r="3" fill="currentColor" opacity="0.85"/>
          <circle cx="30" cy="12" r="7" opacity="0.5"/>
          <path d="M22 12 Q26 8 30 12 T38 12" opacity="0.4"/>
        </svg>
      </span>
      <span className="cpd-line"/>
    </div>
  );
}

// ============== Story ==============
function Story({ t }) {
  const StatsCounter = window.CP_GAME?.StatsCounter;
  return (
    <section className="story" id="story">
      <div className="section-inner">
        <div className="story-grid">
          <div className="story-text reveal">
            <span className="eyebrow">{t.story.eyebrow}</span>
            <h2 style={{ marginTop: 18 }}>
              {t.story.title.split('\n').map((line, i) => (
                <div key={i}>{i === 1 ? <span className="gold">{line}</span> : line}</div>
              ))}
            </h2>
            <p>{t.story.p1}</p>
            <p>{t.story.p2}</p>
            <div className="story-sign">{t.story.sign}</div>
            <div className="story-stats">
              <div className="stat"><div className="v">{t.story.stat1Value}</div><div className="l">{t.story.stat1Label}</div></div>
              <div className="stat"><div className="v">{t.story.stat2Value}</div><div className="l">{t.story.stat2Label}</div></div>
              <div className="stat"><div className="v">{t.story.stat3Value}</div><div className="l">{t.story.stat3Label}</div></div>
            </div>
          </div>
          <div className="story-photo reveal">
            <img src="assets/photos/paco.jpg" alt={t.story.ownerName} loading="lazy"/>
            <div className="story-card">
              <div className="name">{t.story.ownerName}</div>
              <div className="role">{t.story.ownerRole}</div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ============== Generic Menu Renderer (used for breakfast & lunch) ==============
function MenuItems({ items }) {
  if (!items || !items.length) return null;
  return items.map((it, i) => (
    <div key={i} className={`menu-item ${it.opt ? 'opt' : ''}`} style={{ animation: `fadeUp .5s var(--ease) ${Math.min(i, 12) * 0.03}s both` }}>
      <div className="top">
        <span className="name">{it.n}</span>
        <span className="dots"/>
      </div>
      <span className="price">{it.p}{it.p && !/^[+]/.test(it.p) ? <span className="price-sym"> €</span> : null}</span>
      {it.d && <div className="desc">{it.d}</div>}
    </div>
  ));
}

// ============== Category Pager (arrows + name + dots) ==============
function CategoryPager({ cats, active, onChange }) {
  const idx = Math.max(0, cats.indexOf(active));
  const total = cats.length;
  const go = (i) => onChange(cats[(i + total) % total]);
  const prev = () => go(idx - 1);
  const next = () => go(idx + 1);
  const startX = useRef(0);
  const startY = useRef(0);
  const onTouchStart = (e) => {
    startX.current = e.touches[0].clientX;
    startY.current = e.touches[0].clientY;
  };
  const onTouchEnd = (e) => {
    const dx = e.changedTouches[0].clientX - startX.current;
    const dy = e.changedTouches[0].clientY - startY.current;
    if (Math.abs(dx) > 45 && Math.abs(dx) > Math.abs(dy) * 1.4) {
      if (dx > 0) prev(); else next();
    }
  };
  return (
    <div className="cat-pager reveal" onTouchStart={onTouchStart} onTouchEnd={onTouchEnd}>
      <div className="cat-pager-row">
        <button className="cat-arrow" onClick={prev} aria-label="Categoría anterior" type="button">
          <svg viewBox="0 0 24 24" width="20" height="20" aria-hidden="true">
            <path d="M15 5l-7 7 7 7" stroke="currentColor" strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </button>
        <div className="cat-pager-track">
          <span className="cat-name" key={active}>{active}</span>
          <span className="cat-counter">{idx + 1} / {total}</span>
        </div>
        <button className="cat-arrow" onClick={next} aria-label="Categoría siguiente" type="button">
          <svg viewBox="0 0 24 24" width="20" height="20" aria-hidden="true">
            <path d="M9 5l7 7-7 7" stroke="currentColor" strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </button>
      </div>
      <div className="cat-dots" role="tablist" aria-label="Categorías">
        {cats.map((c, i) => (
          <button
            key={c}
            type="button"
            role="tab"
            aria-selected={i === idx}
            aria-label={c}
            className={`cat-dot ${i === idx ? 'active' : ''}`}
            onClick={() => go(i)}
          />
        ))}
      </div>
    </div>
  );
}

// ============== Breakfast Menu ==============
function BreakfastMenu({ t }) {
  const cats = t.breakfast.cats || [];
  const [active, setActive] = useState(cats[0]);
  useEffect(() => { setActive(cats[0]); }, [cats[0]]);
  const items = t.breakfast.items[active] || [];
  return (
    <section className="menu-section" id="breakfast">
      <div className="section-inner">
        <div className="section-head reveal">
          <span className="eyebrow">{t.breakfast.eyebrow}</span>
          <h2 style={{ marginTop: 14 }}>{t.breakfast.title}</h2>
          <p className="sub">{t.breakfast.sub}</p>
        </div>
        <CategoryPager cats={cats} active={active} onChange={setActive}/>
        <div className="menu-grid" key={active}>
          <MenuItems items={items}/>
        </div>
      </div>
    </section>
  );
}

// ============== Lunch Menu ==============
function LunchMenu({ t }) {
  const cats = t.lunch.cats || [];
  const [active, setActive] = useState(cats[0]);
  useEffect(() => { setActive(cats[0]); }, [cats[0]]);
  const items = t.lunch.items[active] || [];
  return (
    <section className="menu-section dark" id="lunch">
      <div className="section-inner">
        <div className="section-head reveal">
          <span className="eyebrow">{t.lunch.eyebrow}</span>
          <h2 style={{ marginTop: 14 }}><span className="gold">{t.lunch.title}</span></h2>
          <p className="sub">{t.lunch.sub}</p>
        </div>
        <CategoryPager cats={cats} active={active} onChange={setActive}/>
        <div className="menu-grid" key={active}>
          <MenuItems items={items}/>
        </div>
      </div>
    </section>
  );
}

// ============== Gallery (real photos with lightbox) ==============
const GALLERY_PHOTOS = [
  { src: 'assets/photos/exterior.jpg', cls: 't1', key: 0 },
  { src: 'assets/photos/octopus.jpg', cls: 't2', key: 1 },
  { src: 'assets/photos/salmon-toast.jpg', cls: 't3', key: 2 },
  { src: 'assets/photos/table-overhead.jpg', cls: 't4', key: 3 },
  { src: 'assets/photos/charcuterie.jpg', cls: 't5', key: 4 },
  { src: 'assets/photos/bravas.jpg', cls: 't6', key: 5 },
  { src: 'assets/photos/teacups.jpg', cls: 't7', key: 6 },
  { src: 'assets/photos/matcha-cat.jpg', cls: 't8', key: 7 },
  { src: 'assets/photos/canas-fresas.jpg', cls: 't9', key: 8 },
  { src: 'assets/photos/coconut-bowl.jpg', cls: 't10', key: 9 }
];

function Gallery({ t }) {
  const [lbIndex, setLbIndex] = useState(-1);
  const Lightbox = window.CP_GAME?.PhotoLightbox;
  const labels = t.gallery.labels || [];
  const photos = GALLERY_PHOTOS.map((p, i) => ({ ...p, caption: labels[i] || '', alt: labels[i] || 'Can Petita' }));
  return (
    <section className="gallery" id="gallery">
      <div className="section-inner">
        <div className="section-head reveal">
          <span className="eyebrow">{t.gallery.eyebrow}</span>
          <h2 style={{ marginTop: 14 }}>{t.gallery.title}</h2>
          <p className="sub">{t.gallery.sub}</p>
        </div>
        <div className="gallery-grid reveal">
          {photos.map((p, i) => (
            <div key={i} className={`tile ${p.cls}`} onClick={() => setLbIndex(i)} role="button" tabIndex={0}
                 onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') setLbIndex(i); }}>
              <img src={p.src} alt={p.alt} loading="lazy"/>
              <div className="tile-label">{p.caption}</div>
            </div>
          ))}
        </div>
        <div className="ig-cta">
          <a href="https://www.instagram.com/canpetita" target="_blank" rel="noopener" className="btn btn-ghost">
            <span style={{ fontSize: 16 }}>◉</span> {t.gallery.cta}
          </a>
        </div>
      </div>
      {Lightbox && lbIndex >= 0 && (
        <Lightbox photos={photos} index={lbIndex} onClose={() => setLbIndex(-1)}/>
      )}
    </section>
  );
}

// ============== Reviews (real Google reviews) ==============
function Reviews({ t }) {
  return (
    <section className="reviews" id="reviews">
      <div className="section-inner">
        <div className="section-head reveal" style={{ textAlign: 'center' }}>
          <span className="eyebrow" style={{ justifyContent: 'center' }}>{t.reviews.eyebrow}</span>
          <h2 style={{ marginTop: 14 }}><span className="gold">{t.reviews.title}</span></h2>
          {t.reviews.sub && <p className="sub" style={{ marginLeft: 'auto', marginRight: 'auto' }}>{t.reviews.sub}</p>}
        </div>
        <div className="reviews-meta reveal">
          <span className="stars-row">★★★★★</span>
          {t.trust?.rating || '4,9'} / 5 · {t.trust?.reviewsCount || '157'} {t.trust?.reviewsLabel || 'reseñas verificadas'}
        </div>
        <div className="review-track">
          {t.reviews.list.map((r, i) => (
            <div key={i} className="review reveal">
              <span className="quote">"</span>
              <div className="stars">{'★'.repeat(r.s || 5)}</div>
              <h4>{r.t}</h4>
              <p className="body">{r.b}</p>
              <div className="author">{r.a}</div>
              {r.src && <div className="src">{r.src}</div>}
            </div>
          ))}
        </div>
        <div className="reviews-cta reveal">
          <p className="reviews-cta-text">{t.reviews.askText || '¿Te gustó? Déjanos una reseña — nos hace mucha ilusión.'}</p>
          <a href="https://www.google.com/search?q=Can+Petita+Sant+Antoni+de+Calonge#lrd=0x12bafa75836715dd:0x4a8de07a9da8b0aa,3" target="_blank" rel="noopener" className="btn btn-ghost reviews-cta-btn">
            <CP_ICONS.google/> {t.reviews.askCTA || 'Dejar reseña en Google'} <span className="arrow">→</span>
          </a>
        </div>
      </div>
    </section>
  );
}

// ============== Visit (hours + Google Maps) ==============
function Visit({ t }) {
  const now = new Date();
  const jsDay = now.getDay(); // 0=Sun, 1=Mon, ... 6=Sat
  // Our hoursList is Mon-first → index = (Sun=6, Mon=0, Tue=1, ..., Sat=5)
  const todayIdx = jsDay === 0 ? 6 : jsDay - 1;
  const mapsEmbed = "https://maps.google.com/maps?q=Carrer%20de%20Sant%20Antoni%2C%2017252%20Sant%20Antoni%20de%20Calonge%2C%20Girona&t=&z=15&ie=UTF8&iwloc=&output=embed";
  return (
    <section className="visit" id="visit">
      <div className="section-inner">
        <div className="section-head reveal" style={{ textAlign: 'center' }}>
          <span className="eyebrow" style={{ justifyContent: 'center' }}>{t.visit.eyebrow}</span>
          <h2 style={{ marginTop: 14 }}>{t.visit.title}</h2>
        </div>
        <div className="visit-grid">
          <div className="visit-info reveal">
            <dl>
              <div className="row">
                <div className="label">{t.visit.title}</div>
                <div className="value">
                  {t.visit.address}<br/>
                  <span style={{ color: 'rgba(244,237,224,0.65)', fontSize: 14 }}>{t.visit.city || '17252 Sant Antoni de Calonge · Girona'}</span>
                </div>
              </div>
              <div className="row">
                <div className="label">{t.visit.hours}</div>
                <ul className="hours-list">
                  {t.visit.hoursList.map((h, i) => (
                    <li key={i} className={`${i === todayIdx ? 'now' : ''} ${h.closed ? 'closed' : ''}`}>
                      <span className="day">{h.d}</span>
                      <span className="time">{h.h}</span>
                    </li>
                  ))}
                </ul>
              </div>
              <div className="row">
                <div className="label">{t.visit.contact}</div>
                <div className="value">
                  <div><a href={`tel:${t.visit.phone}`}>{t.visit.phoneDisplay || t.visit.phone}</a></div>
                  <div style={{ marginTop: 6 }}><a href={`mailto:${t.visit.email}`}>{t.visit.email}</a></div>
                </div>
              </div>
            </dl>
          </div>
          <div className="map-wrap reveal">
            <iframe src={mapsEmbed} loading="lazy" referrerPolicy="no-referrer-when-downgrade" title="Can Petita map"/>
            <a href={t.visit.mapsUrl || "https://maps.google.com/?q=Can+Petita+Sant+Antoni+de+Calonge"} target="_blank" rel="noopener" className="map-cta">
              {t.visit.directions} →
            </a>
          </div>
        </div>
      </div>
    </section>
  );
}

// ============== Helper: friendly date formatter (i18n aware) ==============
function fmtFriendlyDate(ymd, lang) {
  if (!ymd) return '—';
  try {
    const d = new Date(ymd + 'T00:00:00');
    const localeMap = { ca: 'ca-ES', es: 'es-ES', en: 'en-GB', fr: 'fr-FR', nl: 'nl-NL' };
    return new Intl.DateTimeFormat(localeMap[lang] || 'es-ES', { weekday: 'long', day: 'numeric', month: 'long' }).format(d);
  } catch (_) { return ymd; }
}

// ============== Manage-reservation icons (line-art, brand) ==============
const CP_MANAGE_ICONS = {
  calendar: () => (
    <svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <rect x="3" y="4.5" width="18" height="17" rx="2"/>
      <path d="M16 2.5v4M8 2.5v4M3 10h18" opacity="0.85"/>
      <circle cx="12" cy="15" r="1.4" fill="currentColor"/>
    </svg>
  ),
  arrowRight: () => (
    <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/>
    </svg>
  ),
  close: () => (
    <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
    </svg>
  ),
  warning: () => (
    <svg viewBox="0 0 64 64" width="42" height="42" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <path d="M32 8L4 56h56z"/>
      <line x1="32" y1="26" x2="32" y2="40"/>
      <circle cx="32" cy="48" r="1.5" fill="currentColor"/>
    </svg>
  ),
  info: () => (
    <svg viewBox="0 0 64 64" width="42" height="42" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <circle cx="32" cy="32" r="26"/>
      <line x1="32" y1="28" x2="32" y2="46"/>
      <circle cx="32" cy="20" r="1.6" fill="currentColor"/>
    </svg>
  ),
  check: () => (
    <svg viewBox="0 0 64 64" width="44" height="44" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <circle cx="32" cy="32" r="26"/>
      <path d="M20 32l9 9 16-18"/>
    </svg>
  ),
  search: () => (
    <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <circle cx="11" cy="11" r="7"/><line x1="20" y1="20" x2="16" y2="16"/>
    </svg>
  ),
  whatsapp: () => (
    <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true">
      <path d="M.057 24l1.687-6.163a11.867 11.867 0 0 1-1.587-5.946C.16 5.335 5.495 0 12.05 0a11.817 11.817 0 0 1 8.413 3.488 11.824 11.824 0 0 1 3.48 8.414c-.003 6.557-5.339 11.892-11.893 11.892a11.9 11.9 0 0 1-5.688-1.448L.057 24zm6.597-3.807c1.676.995 3.276 1.591 5.392 1.592 5.448 0 9.886-4.434 9.889-9.885.002-5.462-4.415-9.89-9.881-9.892-5.452 0-9.887 4.434-9.889 9.884a9.86 9.86 0 0 0 1.516 5.26l.241.383-1.005 3.665 3.737-.98z"/>
    </svg>
  )
};

// Embeds /tarjeta inside a fullscreen modal so the user keeps their place on the
// landing. Triggered by the custom event "cp:open-tarjeta".
function TarjetaModal() {
  const [open, setOpen] = useState(false);
  useEffect(() => {
    const onOpen = () => setOpen(true);
    const onClose = () => setOpen(false);
    const onMessage = (e) => {
      if (e.data === 'cp:tarjeta-close') setOpen(false);
      if (e.data && e.data.type === 'cp:tarjeta-install') {
        // Smooth transition: fade the modal out, then take the whole window
        // to /tarjeta so the install hints can fire natively.
        const modal = document.querySelector('.cp-tarjeta-modal');
        if (modal) modal.classList.add('cp-tarjeta-modal-leaving');
        setTimeout(() => {
          const id = e.data.id ? '?id=' + encodeURIComponent(e.data.id) : '';
          window.location.href = '/tarjeta' + id;
        }, 260);
      }
    };
    window.addEventListener('cp:open-tarjeta', onOpen);
    window.addEventListener('cp:close-tarjeta', onClose);
    window.addEventListener('message', onMessage);
    return () => {
      window.removeEventListener('cp:open-tarjeta', onOpen);
      window.removeEventListener('cp:close-tarjeta', onClose);
      window.removeEventListener('message', onMessage);
    };
  }, []);
  useEffect(() => {
    if (!open) return;
    document.body.style.overflow = 'hidden';
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    window.addEventListener('keydown', onKey);
    return () => {
      document.body.style.overflow = '';
      window.removeEventListener('keydown', onKey);
    };
  }, [open]);
  if (!open) return null;
  return (
    <div className="cp-tarjeta-modal" onClick={(e) => { if (e.target.classList.contains('cp-tarjeta-modal')) setOpen(false); }} role="dialog" aria-modal="true">
      <button type="button" className="cp-tarjeta-modal-close" onClick={() => setOpen(false)} aria-label="Cerrar">×</button>
      <iframe className="cp-tarjeta-modal-frame" src="/tarjeta?embed=1" title="Tarjeta Can Petita" allow="clipboard-write"/>
    </div>
  );
}

// Persistent floating pill: when the visitor has a future reservation in localStorage,
// show a small chip on every page so they can open the manage modal in one tap.
function ReservationFloater({ t, lang }) {
  const [last, setLast] = useState(() => {
    try {
      const raw = localStorage.getItem('cp_last_reservation');
      const obj = raw ? JSON.parse(raw) : null;
      if (!obj) return null;
      const today = new Date().toISOString().slice(0, 10);
      return obj.date >= today ? obj : null;
    } catch { return null; }
  });
  const [dismissed, setDismissed] = useState(() => {
    try { return sessionStorage.getItem('cp_floater_dismissed') === '1'; } catch { return false; }
  });

  useEffect(() => {
    const refresh = () => {
      try {
        const raw = localStorage.getItem('cp_last_reservation');
        const obj = raw ? JSON.parse(raw) : null;
        const today = new Date().toISOString().slice(0, 10);
        setLast(obj && obj.date >= today ? obj : null);
      } catch { setLast(null); }
    };
    window.addEventListener('storage', refresh);
    window.addEventListener('cp:reservation-updated', refresh);
    return () => {
      window.removeEventListener('storage', refresh);
      window.removeEventListener('cp:reservation-updated', refresh);
    };
  }, []);

  if (!last || dismissed) return null;
  const open = () => window.dispatchEvent(new CustomEvent('cp:open-manage', { detail: { id: last.id } }));
  const dismiss = (e) => {
    e.stopPropagation();
    try { sessionStorage.setItem('cp_floater_dismissed', '1'); } catch (_) {}
    setDismissed(true);
  };
  const Cal = CP_MANAGE_ICONS.calendar;
  const Arrow = CP_MANAGE_ICONS.arrowRight;
  const X = CP_MANAGE_ICONS.close;
  return (
    <div className="res-floater" onClick={open} role="button" tabIndex={0}
         onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); open(); } }}
         aria-label={t.reserve.floaterLabel || 'Tu reserva'}>
      <span className="res-floater-icon"><Cal/></span>
      <span className="res-floater-text">
        <span className="res-floater-eyebrow">{t.reserve.floaterLabel || 'Tu reserva'}</span>
        <span className="res-floater-info">{fmtFriendlyDate(last.date, lang)} · {last.time}</span>
      </span>
      <span className="res-floater-arrow"><Arrow/></span>
      <button type="button" className="res-floater-close" onClick={dismiss} aria-label="ocultar"><X/></button>
    </div>
  );
}

// ============== Manage Reservation modal (cancel / lookup / reschedule) ==============
function ManageReservation({ t, lang, open, onClose, prefillId }) {
  const [code, setCode] = useState('');
  const [reservation, setReservation] = useState(null);
  const [step, setStep] = useState('lookup'); // lookup, found, alreadyCancelled, justCancelled, confirm
  const [busy, setBusy] = useState(false);
  const [errMsg, setErrMsg] = useState('');

  useEffect(() => {
    if (open && prefillId) { setCode(prefillId); setTimeout(() => doLookup(prefillId), 200); }
    if (!open) { setCode(''); setReservation(null); setStep('lookup'); setErrMsg(''); }
    // ESC handler
    const onKey = (e) => { if (e.key === 'Escape' && open) onClose(); };
    if (open) document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [open, prefillId]);

  const doLookup = async (id) => {
    const clean = (id || code).trim();  // ⚠️ NO toUpperCase — Firestore IDs are case-sensitive
    if (!clean) return;
    setBusy(true); setErrMsg('');
    try {
      const fb = window.CP_FIREBASE;
      const r = fb ? await fb.getReservationById(clean) : null;
      if (!r) {
        setErrMsg(t.reserve.notFound || 'No encontramos ninguna reserva con ese código.');
        setStep('lookup');
      } else {
        setReservation(r);
        setStep(r.status === 'cancelled' ? 'alreadyCancelled' : 'found');
      }
    } catch (e) {
      const msg = (e.message || '').toLowerCase().includes('network')
        ? (t.reserve.networkErr || 'Sin conexión. Revisa tu internet y vuelve a intentar.')
        : 'Error: ' + (e.message || 'algo falló');
      setErrMsg(msg);
    } finally {
      setBusy(false);
    }
  };

  const askCancel = () => setStep('confirm');

  const doCancel = async () => {
    if (!reservation) return;
    setBusy(true); setErrMsg('');
    try {
      await window.CP_FIREBASE.cancelReservationByCustomer(reservation.id);
      setReservation({ ...reservation, status: 'cancelled' });
      setStep('justCancelled');
      // Clear last-reservation pill so "ver mi reserva" doesn't suggest the cancelled one
      try { localStorage.removeItem('cp_last_reservation'); } catch (_) {}
      try { window.dispatchEvent(new CustomEvent('cp:reservation-updated')); } catch (_) {}
    } catch (e) {
      const msg = (e.message || '').toLowerCase().includes('network')
        ? (t.reserve.networkErr || 'Sin conexión. Revisa tu internet y vuelve a intentar.')
        : 'Error: ' + (e.message || 'algo falló');
      setErrMsg(msg);
      setStep('found');
    } finally {
      setBusy(false);
    }
  };

  const whatsappUrl = (action) => {
    if (!reservation) return '#';
    const phone = '+34972077350';
    const dateText = fmtFriendlyDate(reservation.date, lang);
    let msg;
    if (action === 'reschedule') {
      msg = `Hola Paco, soy ${reservation.name}. Necesito cambiar mi reserva del ${dateText} a las ${reservation.time} (${reservation.people} personas). Código: ${reservation.id}`;
    } else {
      msg = `Hola Paco, soy ${reservation.name}. Te escribo por mi reserva del ${dateText} a las ${reservation.time} (${reservation.people} personas). Código: ${reservation.id}`;
    }
    return `https://wa.me/${phone.replace(/\D/g,'')}?text=${encodeURIComponent(msg)}`;
  };

  if (!open) return null;
  return (
    <div className="manage-modal" onClick={(e) => { if (e.target.classList.contains('manage-modal')) onClose(); }} role="dialog" aria-modal="true">
      <div className="manage-card">
        <button className="manage-close" onClick={onClose} aria-label="cerrar">×</button>
        <div className="manage-head">
          <span className="eyebrow">{t.reserve.manageEyebrow || 'Tu reserva'}</span>
          <h2>{t.reserve.manageTitle || 'Gestionar mi reserva'}</h2>
        </div>

        {step === 'lookup' && (
          <div className="manage-body">
            <p className="manage-text">{t.reserve.manageHelp || 'Introduce el código que recibiste al hacer la reserva.'}</p>
            <form onSubmit={(e) => { e.preventDefault(); doLookup(); }} className="manage-form">
              <div className="manage-input-wrap">
                <span className="manage-input-icon">{(() => { const I = CP_MANAGE_ICONS.search; return <I/>; })()}</span>
                <input
                  type="text"
                  value={code}
                  onChange={e => setCode(e.target.value.trim().slice(0, 32))}
                  placeholder={t.reserve.codePlaceholder || 'CÓDIGO DE RESERVA'}
                  autoFocus
                  spellCheck={false}
                  autoComplete="off"
                  autoCapitalize="off"
                  className="manage-input"
                />
              </div>
              <button type="submit" className="btn btn-gold" disabled={busy || code.trim().length < 6}>
                {busy ? '…' : (t.reserve.findRes || 'Buscar')} <span className="arrow">→</span>
              </button>
            </form>
            {errMsg && <div className="manage-error">{errMsg}</div>}
            <a className="manage-fallback" href={`https://wa.me/34972077350?text=${encodeURIComponent('Hola Paco, no encuentro el código de mi reserva. ¿Me ayudas?')}`} target="_blank" rel="noopener">
              {(() => { const W = CP_MANAGE_ICONS.whatsapp; return <W/>; })()}
              <span>{t.reserve.lostCode || '¿Has perdido el código? Escríbenos por WhatsApp'}</span>
            </a>
          </div>
        )}

        {step === 'found' && reservation && (
          <div className="manage-body">
            <div className="res-summary">
              <div className="res-row"><span>{t.reserve.name}</span><strong>{reservation.name}</strong></div>
              <div className="res-row"><span>{t.reserve.date}</span><strong>{fmtFriendlyDate(reservation.date, lang)}</strong></div>
              <div className="res-row"><span>{t.reserve.time}</span><strong>{reservation.time}</strong></div>
              <div className="res-row"><span>{t.reserve.people}</span><strong>{reservation.people}</strong></div>
              {reservation.notes && (<div className="res-row"><span>notas</span><em>{reservation.notes}</em></div>)}
              <div className="res-row"><span>{t.reserve.statusLabel || 'estado'}</span><strong className={`status-pill ${reservation.status || 'pending'}`}>{reservation.status === 'confirmed' ? (t.reserve.statusConfirmed || 'confirmada') : (t.reserve.statusPending || 'recibida · te llamamos')}</strong></div>
            </div>
            <div className="manage-actions-row">
              <a href={whatsappUrl('reschedule')} target="_blank" rel="noopener" className="btn btn-ghost btn-wa">
                <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M.057 24l1.687-6.163a11.867 11.867 0 0 1-1.587-5.946C.16 5.335 5.495 0 12.05 0a11.817 11.817 0 0 1 8.413 3.488 11.824 11.824 0 0 1 3.48 8.414c-.003 6.557-5.339 11.892-11.893 11.892a11.9 11.9 0 0 1-5.688-1.448L.057 24zm6.597-3.807c1.676.995 3.276 1.591 5.392 1.592 5.448 0 9.886-4.434 9.889-9.885.002-5.462-4.415-9.89-9.881-9.892-5.452 0-9.887 4.434-9.889 9.884a9.86 9.86 0 0 0 1.516 5.26l.241.383-1.005 3.665 3.737-.98z"/></svg>
                {t.reserve.reschedule || 'Cambiar fecha por WhatsApp'}
              </a>
            </div>
            <div className="manage-actions">
              <button className="btn btn-ghost" onClick={onClose}>{t.reserve.keepRes || 'Mantener reserva'}</button>
              <button className="btn-danger" onClick={askCancel} disabled={busy}>
                {t.reserve.cancelRes || 'Cancelar reserva'}
              </button>
            </div>
            {errMsg && <div className="manage-error">{errMsg}</div>}
          </div>
        )}

        {step === 'confirm' && reservation && (
          <div className="manage-body">
            <div className="manage-confirm">
              <div className="manage-confirm-icon">{(() => { const W = CP_MANAGE_ICONS.warning; return <W/>; })()}</div>
              <h3>{t.reserve.confirmTitle || '¿Cancelar definitivamente?'}</h3>
              <p>{t.reserve.confirmSub || 'Si quieres cambiar el día o la hora, mejor escríbenos por WhatsApp en lugar de cancelar.'}</p>
              <div className="res-summary res-summary-mini">
                <div className="res-row"><span>{t.reserve.name}</span><strong>{reservation.name}</strong></div>
                <div className="res-row"><span>{t.reserve.date}</span><strong>{fmtFriendlyDate(reservation.date, lang)} · {reservation.time}</strong></div>
              </div>
            </div>
            <div className="manage-actions">
              <button className="btn btn-ghost" onClick={() => setStep('found')} disabled={busy}>{t.reserve.no || 'No, mantener'}</button>
              <button className="btn-danger" onClick={doCancel} disabled={busy}>
                {busy ? '…' : (t.reserve.yesCancel || 'Sí, cancelar')}
              </button>
            </div>
            {errMsg && <div className="manage-error">{errMsg}</div>}
          </div>
        )}

        {step === 'justCancelled' && reservation && (
          <div className="manage-body">
            <div className="manage-success">
              <div className="manage-success-icon">{(() => { const C = CP_MANAGE_ICONS.check; return <C/>; })()}</div>
              <h3>{t.reserve.cancelledTitle || 'Reserva cancelada'}</h3>
              <p>{t.reserve.cancelledSub || 'Hemos avisado a Paco. Esperamos verte pronto.'}</p>
            </div>
            <div className="manage-actions" style={{ justifyContent: 'center' }}>
              <button className="btn btn-gold" onClick={onClose}>{t.reserve.close || 'Cerrar'}</button>
            </div>
          </div>
        )}

        {step === 'alreadyCancelled' && reservation && (
          <div className="manage-body">
            <div className="manage-info">
              <div className="manage-info-icon">{(() => { const I = CP_MANAGE_ICONS.info; return <I/>; })()}</div>
              <h3>{t.reserve.alreadyTitle || 'Esta reserva ya estaba cancelada'}</h3>
              <p>{t.reserve.alreadySub || 'Si quieres venir, haz una nueva reserva — Paco te recibe encantado.'}</p>
            </div>
            <div className="manage-actions" style={{ justifyContent: 'center', gap: 10 }}>
              <button className="btn btn-ghost" onClick={onClose}>{t.reserve.close || 'Cerrar'}</button>
              <a href="#reserve" className="btn btn-gold" onClick={onClose}>{t.reserve.newRes || 'Hacer nueva reserva'} →</a>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

// ============== ICS calendar download (no library) ==============
function downloadICS({ id, name, date, time, people }) {
  const dt = new Date(date + 'T' + time + ':00');
  const end = new Date(dt.getTime() + 90 * 60 * 1000); // 90-minute reservation
  const fmt = (d) => d.toISOString().replace(/[-:]/g, '').split('.')[0] + 'Z';
  const ics = [
    'BEGIN:VCALENDAR',
    'VERSION:2.0',
    'PRODID:-//Can Petita//Reservation//ES',
    'METHOD:PUBLISH',
    'BEGIN:VEVENT',
    `UID:${id}@canpetitacafe.com`,
    `DTSTAMP:${fmt(new Date())}`,
    `DTSTART:${fmt(dt)}`,
    `DTEND:${fmt(end)}`,
    `SUMMARY:Reserva Can Petita · ${people}p`,
    `DESCRIPTION:Reserva a nombre de ${name}\\n\\nCódigo: ${id}\\n\\nGestionar: https://canpetitacafe.com/?reserva=${id}`,
    'LOCATION:Carrer de Sant Antoni\\, 17252 Sant Antoni de Calonge\\, Girona',
    'BEGIN:VALARM',
    'TRIGGER:-PT2H',
    'ACTION:DISPLAY',
    'DESCRIPTION:Recordatorio reserva Can Petita',
    'END:VALARM',
    'END:VEVENT',
    'END:VCALENDAR'
  ].join('\r\n');
  const blob = new Blob([ics], { type: 'text/calendar;charset=utf-8' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `can-petita-${date}.ics`;
  document.body.appendChild(a); a.click();
  setTimeout(() => { URL.revokeObjectURL(url); a.remove(); }, 100);
}

// ============== Reserve (Firebase + localStorage fallback) ==============
function Reserve({ t, lang }) {
  const [people, setPeople] = useState(2);
  const [date, setDate] = useState(() => {
    // pick the next OPEN date (skip Tuesdays / any closed day)
    const fn = window.CP_RESERVE?.getAvailableTimeSlots;
    const d = new Date();
    for (let i = 0; i < 8; i++) {
      const y = d.getFullYear(), m = String(d.getMonth()+1).padStart(2,'0'), day = String(d.getDate()).padStart(2,'0');
      const ymd = `${y}-${m}-${day}`;
      if (!fn || (fn(ymd) || []).length > 0) return ymd;
      d.setDate(d.getDate() + 1);
    }
    return d.toISOString().slice(0, 10);
  });
  const [time, setTime] = useState('13:30');
  const [name, setName] = useState('');
  const [phone, setPhone] = useState('');
  const [notes, setNotes] = useState('');
  const [errors, setErrors] = useState({});
  const [status, setStatus] = useState('idle'); // idle, sending, sent, error
  const [resultId, setResultId] = useState(null);
  const [persisted, setPersisted] = useState(null);
  const [manageOpen, setManageOpen] = useState(false);
  const [managePrefill, setManagePrefill] = useState('');
  const [copied, setCopied] = useState(false);
  const [lastReservation, setLastReservation] = useState(() => {
    try {
      const raw = localStorage.getItem('cp_last_reservation');
      return raw ? JSON.parse(raw) : null;
    } catch { return null; }
  });

  // ?reserva=ID URL handler — auto-opens the manage modal
  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const r = params.get('reserva') || params.get('reservation');
    if (r) { setManagePrefill(r); setManageOpen(true); }
    const onOpen = (e) => {
      setManagePrefill((e.detail && e.detail.id) || '');
      setManageOpen(true);
    };
    window.addEventListener('cp:open-manage', onOpen);
    return () => window.removeEventListener('cp:open-manage', onOpen);
  }, []);

  // Recompute today inside submit for late-night edge case
  const today = new Date().toISOString().slice(0, 10);

  // Detect if selected date is closed
  const isClosed = useMemo(() => {
    const fn = window.CP_RESERVE?.getAvailableTimeSlots;
    return fn ? (fn(date) || []).length === 0 : false;
  }, [date]);

  // Available time slots
  const slots = useMemo(() => {
    const fn = window.CP_RESERVE?.getAvailableTimeSlots;
    if (!fn) return ['09:00','10:00','11:00','12:00','13:00','13:30','14:00','14:30'];
    return fn(date) || [];
  }, [date]);

  useEffect(() => {
    if (slots.length && !slots.includes(time)) setTime(slots[0]);
  }, [slots]);

  // jump to next open day
  const jumpToNextOpen = () => {
    const fn = window.CP_RESERVE?.getAvailableTimeSlots;
    if (!fn) return;
    const d = new Date(date + 'T00:00:00');
    for (let i = 1; i < 8; i++) {
      d.setDate(d.getDate() + 1);
      const ymd = d.getFullYear() + '-' + String(d.getMonth()+1).padStart(2,'0') + '-' + String(d.getDate()).padStart(2,'0');
      if ((fn(ymd) || []).length > 0) { setDate(ymd); break; }
    }
  };

  const submit = async (e) => {
    e.preventDefault();
    const payload = { name: name.trim(), phone: phone.trim(), people, date, time, notes: notes.trim(), language: lang };
    const validate = window.CP_RESERVE?.validateReservation;
    const v = validate ? validate(payload) : { ok: name && phone && date && time, errors: {} };
    if (!v.ok) { setErrors(v.errors || {}); return; }
    setErrors({});
    setStatus('sending');
    try {
      const fb = window.CP_FIREBASE;
      let id;
      if (!fb) {
        const arr = JSON.parse(localStorage.getItem('cp_reservations') || '[]');
        id = 'L' + Date.now().toString(36).toUpperCase();
        arr.push({ ...payload, id, createdAt: new Date().toISOString(), status: 'pending', source: 'web' });
        localStorage.setItem('cp_reservations', JSON.stringify(arr));
        setResultId(id); setPersisted('local'); setStatus('sent');
      } else {
        const res = await fb.addReservation({ ...payload, source: 'web' });
        id = res.id;
        setResultId(id); setPersisted(res.persisted); setStatus('sent');
      }
      // Persist last reservation in localStorage so revisits show "Tu reserva"
      try {
        const last = { id, name: payload.name, date: payload.date, time: payload.time, people: payload.people, savedAt: Date.now() };
        localStorage.setItem('cp_last_reservation', JSON.stringify(last));
        setLastReservation(last);
        try { sessionStorage.removeItem('cp_floater_dismissed'); } catch (_) {}
        window.dispatchEvent(new CustomEvent('cp:reservation-updated'));
      } catch (_) {}
      // NO auto-clear — let user dismiss manually so they have time to copy/save the code
    } catch (err) {
      console.error(err);
      setStatus('error');
      setTimeout(() => setStatus('idle'), 6000);
    }
  };

  const copyCode = async () => {
    if (!resultId) return;
    try {
      await navigator.clipboard.writeText(resultId);
      setCopied(true);
      setTimeout(() => setCopied(false), 2200);
    } catch (_) {
      // Fallback: select the code element so user can long-press
      const el = document.querySelector('.code-pill');
      if (el && window.getSelection) {
        const range = document.createRange();
        range.selectNode(el);
        const sel = window.getSelection();
        sel.removeAllRanges(); sel.addRange(range);
      }
    }
  };

  const newReservation = () => {
    setStatus('idle');
    setName(''); setPhone(''); setNotes('');
    setResultId(null);
  };

  const whatsappConfirmUrl = useMemo(() => {
    if (!resultId) return '#';
    const dateText = fmtFriendlyDate(date, lang);
    const msg = `Hola Paco! Acabo de reservar mesa: ${name || ''} · ${dateText} · ${time} · ${people}p · Código ${resultId}`;
    return `https://wa.me/34972077350?text=${encodeURIComponent(msg)}`;
  }, [resultId, date, time, people, name, lang]);

  const reservationLink = useMemo(() => {
    if (!resultId) return '';
    const origin = (typeof window !== 'undefined' && window.location && window.location.origin) || '';
    return `${origin}/?reserva=${encodeURIComponent(resultId)}`;
  }, [resultId]);

  const [linkShared, setLinkShared] = useState('');
  const shareReservationLink = async () => {
    if (!reservationLink) return;
    const dateText = fmtFriendlyDate(date, lang);
    const text = `Mi reserva en Can Petita · ${dateText} · ${time} · ${people}p`;
    try {
      if (navigator.share) {
        await navigator.share({ title: 'Mi reserva — Can Petita', text, url: reservationLink });
        setLinkShared('shared');
      } else {
        await navigator.clipboard.writeText(reservationLink);
        setLinkShared('copied');
      }
    } catch (_) {
      try { await navigator.clipboard.writeText(reservationLink); setLinkShared('copied'); } catch (__) {}
    }
    setTimeout(() => setLinkShared(''), 2500);
  };
  const whatsappSelfUrl = useMemo(() => {
    if (!reservationLink) return '#';
    const dateText = fmtFriendlyDate(date, lang);
    const msg = `Mi reserva en Can Petita · ${dateText} · ${time} · ${people}p\n${reservationLink}`;
    return `https://wa.me/?text=${encodeURIComponent(msg)}`;
  }, [reservationLink, date, time, people, lang]);

  const peopleSliderStyle = { '--rng': `${((people - 1) / 11) * 100}%` };

  return (
    <section className="reserve" id="reserve">
      <div className="section-inner">
        <div className="reserve-card reveal">
          <div className="section-head">
            <span className="eyebrow">{t.reserve.eyebrow}</span>
            <h2 style={{ marginTop: 14 }}><span className="gold">{t.reserve.title}</span></h2>
            <p className="sub">{t.reserve.sub}</p>
          </div>

          {/* Returning visitor: pill with last reservation */}
          {lastReservation && status !== 'sent' && (
            <div className="last-res-pill" onClick={() => { setManagePrefill(lastReservation.id); setManageOpen(true); }}>
              <div className="last-res-icon">{(() => { const C = CP_MANAGE_ICONS.calendar; return <C/>; })()}</div>
              <div className="last-res-text">
                <div className="last-res-eyebrow">{t.reserve.lastResLabel || 'Tu última reserva'}</div>
                <div className="last-res-info">{lastReservation.name} · {fmtFriendlyDate(lastReservation.date, lang)} · {lastReservation.time}</div>
              </div>
              <div className="last-res-arrow">{(() => { const A = CP_MANAGE_ICONS.arrowRight; return <A/>; })()}</div>
            </div>
          )}

          {/* Closed-day banner */}
          {isClosed && status !== 'sent' && (
            <div className="closed-banner">
              <span>{t.reserve.closedBanner || 'Cerramos los martes — prueba otro día.'}</span>
              <button type="button" onClick={jumpToNextOpen} className="btn-link-gold">{t.reserve.jumpNext || 'Saltar al siguiente día abierto →'}</button>
            </div>
          )}

          {status !== 'sent' && (
          <form onSubmit={submit} className="form-grid" noValidate>
            <div className="field">
              <label>{t.reserve.name}</label>
              <input type="text" required value={name} onChange={e => setName(e.target.value)} placeholder={t.reserve.namePh || 'María García'} className={errors.name ? 'invalid' : ''} autoComplete="name"/>
              {errors.name && <div className="err">{errors.name}</div>}
            </div>
            <div className="field">
              <label>{t.reserve.phone}</label>
              <input type="tel" required value={phone} onChange={e => setPhone(e.target.value)} placeholder="+34 612 34 56 78" className={errors.phone ? 'invalid' : ''} autoComplete="tel"/>
              {errors.phone && <div className="err">{errors.phone}</div>}
            </div>
            <div className="field">
              <label>{t.reserve.date}</label>
              <input type="date" required value={date} onChange={e => setDate(e.target.value)} min={today} className={errors.date ? 'invalid' : ''}/>
              {errors.date && <div className="err">{errors.date}</div>}
            </div>
            <div className="field">
              <label>{t.reserve.time}</label>
              <select value={time} onChange={e => setTime(e.target.value)} className={errors.time ? 'invalid' : ''} disabled={slots.length === 0}>
                {slots.length === 0
                  ? <option>—</option>
                  : slots.map(h => <option key={h} value={h}>{h}</option>)}
              </select>
            </div>
            <div className="field wide">
              <label>{t.reserve.people}: {people} {people === 1 ? t.reserve.person : t.reserve.people_pl}{people >= 8 ? ' · grupo grande' : ''}</label>
              <input type="range" min="1" max="12" value={people} onChange={e => setPeople(+e.target.value)} style={peopleSliderStyle}/>
              {people >= 8 && (
                <div className="big-group-note">
                  {t.reserve.bigGroup || 'Para grupos grandes, llámanos al 972 07 73 50 para asegurar mesa.'}
                </div>
              )}
            </div>
            <div className="field wide">
              <label>{t.reserve.notes}</label>
              <textarea rows="3" value={notes} onChange={e => setNotes(e.target.value)} placeholder={t.reserve.notesPh || 'Mesa interior, terraza, cumpleaños, alergias…'}/>
            </div>
            <div className="form-submit wide">
              <button type="submit" className="btn btn-gold" disabled={status === 'sending' || slots.length === 0}>
                {status === 'sending' ? (t.reserve.sending || '…') : t.reserve.submit} <span className="arrow">→</span>
              </button>
            </div>
            {status === 'error' && (
              <div className="form-error wide">{t.reserve.error}</div>
            )}
            <div className="manage-link wide">
              <button type="button" className="manage-link-btn" onClick={() => { setManagePrefill(''); setManageOpen(true); }}>
                {t.reserve.manageLink || '¿ya tienes reserva? gestiónala con tu código'}
              </button>
            </div>
          </form>
          )}

          {/* Premium success card */}
          {status === 'sent' && (
            <div className="success-card">
              <div className="success-tick">
                <svg viewBox="0 0 64 64" width="56" height="56" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
                  <circle cx="32" cy="32" r="28"/>
                  <path d="M20 32l9 9 16-18"/>
                </svg>
              </div>
              <h3 className="success-title">{t.reserve.sentTitle || '¡Mesa apuntada!'}</h3>
              <p className="success-sub">{t.reserve.sentDescription || 'Paco te llamará pronto para confirmarla.'}</p>

              <div className="success-meta">
                <span><strong>{name}</strong></span>
                <span>·</span>
                <span>{fmtFriendlyDate(date, lang)}</span>
                <span>·</span>
                <span>{time}</span>
                <span>·</span>
                <span>{people}{people === 1 ? ` ${t.reserve.person}` : ` ${t.reserve.people_pl}`}</span>
              </div>

              {resultId && (
                <div className="code-block">
                  <div className="code-label">{t.reserve.codeLabel || 'Guarda este código si necesitas cancelar o gestionar tu reserva'}</div>
                  <button type="button" className="code-pill" onClick={copyCode} title={t.reserve.copyCode || 'Copiar código'}>
                    <span>{resultId}</span>
                    <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                      <rect x="9" y="9" width="13" height="13" rx="2"/>
                      <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
                    </svg>
                  </button>
                  {copied && <div className="code-copied">✓ {t.reserve.copiedMsg || 'copiado al portapapeles'}</div>}
                </div>
              )}

              {resultId && (
                <div className="save-link-block">
                  <div className="save-link-eyebrow">{t.reserve.saveLinkEyebrow || 'Guarda este enlace en tu móvil'}</div>
                  <div className="save-link-help">{t.reserve.saveLinkHelp || 'Te servirá para cambiar o cancelar tu reserva desde cualquier dispositivo, sin necesidad de recordar el código.'}</div>
                  <div className="save-link-actions">
                    <button type="button" className="save-link-btn primary" onClick={shareReservationLink}>
                      <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                        <circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/>
                        <line x1="8.6" y1="10.5" x2="15.4" y2="6.5"/><line x1="8.6" y1="13.5" x2="15.4" y2="17.5"/>
                      </svg>
                      <span>{linkShared === 'copied' ? (t.reserve.linkCopied || '✓ copiado') : linkShared === 'shared' ? (t.reserve.linkSharedMsg || '✓ enviado') : (t.reserve.shareLink || 'Compartir / guardar enlace')}</span>
                    </button>
                    <a href={whatsappSelfUrl} target="_blank" rel="noopener" className="save-link-btn">
                      <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true">
                        <path d="M.057 24l1.687-6.163a11.867 11.867 0 0 1-1.587-5.946C.16 5.335 5.495 0 12.05 0a11.817 11.817 0 0 1 8.413 3.488 11.824 11.824 0 0 1 3.48 8.414c-.003 6.557-5.339 11.892-11.893 11.892a11.9 11.9 0 0 1-5.688-1.448L.057 24zm6.597-3.807c1.676.995 3.276 1.591 5.392 1.592 5.448 0 9.886-4.434 9.889-9.885.002-5.462-4.415-9.89-9.881-9.892-5.452 0-9.887 4.434-9.889 9.884a9.86 9.86 0 0 0 1.516 5.26l.241.383-1.005 3.665 3.737-.98z"/>
                      </svg>
                      <span>{t.reserve.sendToMyself || 'Enviármelo por WhatsApp'}</span>
                    </a>
                  </div>
                  <div className="save-link-url" title={reservationLink}>{reservationLink}</div>
                </div>
              )}

              <div className="success-actions">
                <a href={whatsappConfirmUrl} target="_blank" rel="noopener" className="btn btn-gold success-btn">
                  <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M.057 24l1.687-6.163a11.867 11.867 0 0 1-1.587-5.946C.16 5.335 5.495 0 12.05 0a11.817 11.817 0 0 1 8.413 3.488 11.824 11.824 0 0 1 3.48 8.414c-.003 6.557-5.339 11.892-11.893 11.892a11.9 11.9 0 0 1-5.688-1.448L.057 24zm6.597-3.807c1.676.995 3.276 1.591 5.392 1.592 5.448 0 9.886-4.434 9.889-9.885.002-5.462-4.415-9.89-9.881-9.892-5.452 0-9.887 4.434-9.889 9.884a9.86 9.86 0 0 0 1.516 5.26l.241.383-1.005 3.665 3.737-.98z"/></svg>
                  {t.reserve.confirmByWA || 'Confirmar por WhatsApp'}
                </a>
                <button type="button" className="btn btn-ghost success-btn" onClick={() => downloadICS({ id: resultId, name, date, time, people })}>
                  <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
                  {t.reserve.addCalendar || 'Añadir al calendario'}
                </button>
              </div>

              <div className="success-secondary">
                <button type="button" className="manage-link-btn" onClick={newReservation}>
                  {t.reserve.newRes || 'Hacer otra reserva'}
                </button>
                <span className="success-sep">·</span>
                <button type="button" className="manage-link-btn" onClick={() => { setManagePrefill(resultId); setManageOpen(true); }}>
                  {t.reserve.manageLink || 'gestionar mi reserva'}
                </button>
              </div>

              {persisted === 'local' && (
                <div className="success-warn">
                  Guardada localmente · sin conexión con Firebase
                </div>
              )}
            </div>
          )}
        </div>
      </div>
      <ManageReservation t={t} lang={lang} open={manageOpen} onClose={() => setManageOpen(false)} prefillId={managePrefill}/>
    </section>
  );
}

// ============== Footer ==============
function Footer({ t }) {
  return (
    <footer>
      <div className="footer-script">{t.footer.tag}</div>
      <div className="ornament"><span className="glyph">✦</span></div>
      <div className="footer-socials">
        <a href="https://www.instagram.com/canpetita" target="_blank" rel="noopener" aria-label="Instagram">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="0.8" fill="currentColor"/></svg>
        </a>
        <a href={t.visit?.mapsUrl || "https://maps.google.com/?q=Can+Petita+Sant+Antoni+de+Calonge"} target="_blank" rel="noopener" aria-label="Maps">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M12 21s7-7 7-12a7 7 0 1 0-14 0c0 5 7 12 7 12z"/><circle cx="12" cy="9" r="2.5"/></svg>
        </a>
        <a href={`tel:${t.visit?.phone || '+34972077350'}`} aria-label="Phone">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M5 4h4l2 5-3 2a12 12 0 0 0 5 5l2-3 5 2v4a2 2 0 0 1-2 2A16 16 0 0 1 3 6a2 2 0 0 1 2-2z"/></svg>
        </a>
      </div>
      <div className="footer-rights">{t.footer.rights}</div>
      <div className="footer-meta">
        {t.footer.legal && <a href="#">{t.footer.legal}</a>}
        {t.footer.cookies && <a href="#">{t.footer.cookies}</a>}
      </div>
    </footer>
  );
}

Object.assign(window, {
  Logo, Cursor, Nav, Hero, Story, BreakfastMenu, LunchMenu, Gallery, Reviews, Visit, Reserve, ReservationFloater, Footer, SectionDivider, TarjetaModal
});
