// App.jsx — Marcela & Manuel · v2 with envelope, gallery, RSVP form, music, advanced personalization
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ─── Palettes ─────────────────────────────────────────────────
const PALETTES = {
  olivo: { '--cream':'#F5F1E8','--cream-deep':'#ECE5D3','--paper':'#FBF8F0','--olive':'#6B7D4F','--olive-light':'#9CA77A','--olive-pale':'#C4CCA9','--olive-soft':'#D9DEC4','--gold':'#B0904F','--gold-soft':'#D4B97A','--ink':'#3F4A2E','--ink-soft':'#6E6A55' },
  rosa:  { '--cream':'#FBEEE8','--cream-deep':'#F4DDD2','--paper':'#FFF7F2','--olive':'#A35D5A','--olive-light':'#C48986','--olive-pale':'#E8C5BF','--olive-soft':'#F1D9D4','--gold':'#B0904F','--gold-soft':'#D4B97A','--ink':'#5C2E2C','--ink-soft':'#8a605d' },
  azul:  { '--cream':'#EAEEF2','--cream-deep':'#D7DFE8','--paper':'#F4F7FA','--olive':'#3F5A78','--olive-light':'#6F88A3','--olive-pale':'#B7C6D6','--olive-soft':'#D4DCE5','--gold':'#B89766','--gold-soft':'#D4B97A','--ink':'#1F324A','--ink-soft':'#506378' },
  borgona:{ '--cream':'#F2EAE6','--cream-deep':'#E2D2CC','--paper':'#FAF4F0','--olive':'#7A2E33','--olive-light':'#A35F62','--olive-pale':'#D4B0B2','--olive-soft':'#E5CFD0','--gold':'#B0904F','--gold-soft':'#D4B97A','--ink':'#3D1518','--ink-soft':'#73464a' },
  dorado:{ '--cream':'#F5EFE3','--cream-deep':'#E8DCC2','--paper':'#FBF7EC','--olive':'#8A6E2F','--olive-light':'#B89766','--olive-pale':'#DCC79B','--olive-soft':'#EADBB7','--gold':'#9C6B30','--gold-soft':'#C99A55','--ink':'#3E2E12','--ink-soft':'#7a6440' },
  noche: { '--cream':'#1E2418','--cream-deep':'#2A3122','--paper':'#252B1E','--olive':'#C4CCA9','--olive-light':'#9CA77A','--olive-pale':'#6B7D4F','--olive-soft':'#3F4A2E','--gold':'#D4B97A','--gold-soft':'#B0904F','--ink':'#F5F1E8','--ink-soft':'#C4CCA9' },
};

function applyPalette(name) {
  const p = PALETTES[name] || PALETTES.olivo;
  Object.entries(p).forEach(([k,v]) => document.documentElement.style.setProperty(k, v));
}

// ─── URL params ───────────────────────────────────────────────
function getParams() {
  const p = new URLSearchParams(window.location.search);
  const nombre = (p.get('nombre') || p.get('invitado') || '').trim();
  const pases = parseInt(p.get('pases') || p.get('espacios') || '0', 10);
  const mesa = (p.get('mesa') || '').trim();
  const tipo = (p.get('tipo') || '').trim().toLowerCase();
  const mensaje = (p.get('mensaje') || '').trim();
  const tema = (p.get('tema') || p.get('palette') || 'olivo').trim().toLowerCase();
  const token = (p.get('t') || p.get('token') || '').trim();
  return {
    nombre,
    pases: Number.isFinite(pases) && pases > 0 ? pases : 0,
    mesa,
    tipo,
    mensaje,
    tema: PALETTES[tema] ? tema : 'olivo',
    token,
  };
}

// ─── Reveal hook ──────────────────────────────────────────────
function useReveal() {
  useEffect(() => {
    const io = new IntersectionObserver(es => es.forEach(e => e.isIntersecting && e.target.classList.add('in')), { threshold: 0.18, rootMargin: '0px 0px -40px 0px' });
    const observeAll = () => document.querySelectorAll('.reveal:not(.in)').forEach(el => io.observe(el));
    observeAll();
    // La galería agrega elementos .reveal después del primer render
    const mo = new MutationObserver(observeAll);
    mo.observe(document.getElementById('root'), { childList: true, subtree: true });
    return () => { io.disconnect(); mo.disconnect(); };
  }, []);
}

// ─── Countdown ────────────────────────────────────────────────
const TARGET = new Date('2026-07-18T14:30:00-06:00');
function useCountdown() {
  const [now, setNow] = useState(() => new Date());
  useEffect(() => { const id = setInterval(() => setNow(new Date()), 1000); return () => clearInterval(id); }, []);
  const diff = Math.max(0, TARGET - now);
  return {
    d: Math.floor(diff / 86400000),
    h: Math.floor((diff / 3600000) % 24),
    m: Math.floor((diff / 60000) % 60),
    s: Math.floor((diff / 1000) % 60),
  };
}

// ─── Petals ───────────────────────────────────────────────────
function PetalLayer() {
  const petals = useMemo(() => Array.from({ length: 14 }).map((_, i) => ({
    id: i, left: Math.random() * 100, delay: Math.random() * 18,
    duration: 14 + Math.random() * 12, size: 8 + Math.random() * 8, type: i % 3,
  })), []);
  return (
    <div className="petal-layer">
      {petals.map(p => (
        <div key={p.id} className="petal" style={{ left: `${p.left}%`, animationDelay: `${p.delay}s`, animationDuration: `${p.duration}s` }}>
          {p.type === 0 ? (
            <svg width={p.size} height={p.size} viewBox="0 0 14 14"><circle cx="7" cy="7" r="5" fill="#FBF8F0" stroke="#D4B97A" strokeWidth="0.5" opacity="0.85" /></svg>
          ) : p.type === 1 ? (
            <svg width={p.size * 1.6} height={p.size * 0.7} viewBox="0 0 20 9"><ellipse cx="10" cy="4.5" rx="9" ry="3" fill="#9CA77A" opacity="0.55" /></svg>
          ) : (
            <svg width={p.size * 0.8} height={p.size * 0.8} viewBox="0 0 10 10"><circle cx="5" cy="5" r="3" fill="#C4CCA9" opacity="0.7" /></svg>
          )}
        </div>
      ))}
    </div>
  );
}

// ─── Botanical corner ─────────────────────────────────────────
function BotanicalCorner({ size = 220 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 220 220">
      <defs><linearGradient id={`lg${size}`} x1="0" y1="0" x2="1" y2="1"><stop offset="0%" stopColor="#9CA77A" /><stop offset="100%" stopColor="#6B7D4F" /></linearGradient></defs>
      <g stroke="#6B7D4F" strokeWidth="1.2" fill="none" strokeLinecap="round" opacity="0.6">
        <path d="M -5 -5 Q 50 35, 80 95 T 130 200" />
        <path d="M 12 -5 Q 60 28, 70 70" />
      </g>
      <g fill={`url(#lg${size})`} opacity="0.85">
        <ellipse cx="22" cy="14" rx="12" ry="4.5" transform="rotate(-30 22 14)" />
        <ellipse cx="38" cy="34" rx="14" ry="5" transform="rotate(-15 38 34)" />
        <ellipse cx="54" cy="54" rx="15" ry="5.5" transform="rotate(20 54 54)" />
        <ellipse cx="58" cy="78" rx="13" ry="4.5" transform="rotate(60 58 78)" />
        <ellipse cx="78" cy="92" rx="15" ry="5" transform="rotate(-10 78 92)" />
        <ellipse cx="86" cy="120" rx="14" ry="5" transform="rotate(45 86 120)" />
        <ellipse cx="105" cy="142" rx="15" ry="5" transform="rotate(-20 105 142)" />
        <ellipse cx="112" cy="170" rx="13" ry="4.5" transform="rotate(50 112 170)" />
        <ellipse cx="128" cy="196" rx="14" ry="5" transform="rotate(-15 128 196)" />
      </g>
      <g fill="#C4CCA9" opacity="0.7">
        <ellipse cx="14" cy="48" rx="11" ry="4" transform="rotate(40 14 48)" />
        <ellipse cx="32" cy="72" rx="10" ry="3.5" transform="rotate(70 32 72)" />
        <ellipse cx="46" cy="108" rx="12" ry="4" transform="rotate(60 46 108)" />
        <ellipse cx="64" cy="148" rx="11" ry="4" transform="rotate(75 64 148)" />
        <ellipse cx="86" cy="180" rx="10" ry="3.5" transform="rotate(50 86 180)" />
      </g>
      <g fill="#FBF8F0" stroke="#D4B97A" strokeWidth="0.5">
        <circle cx="20" cy="24" r="3.2" /><circle cx="27" cy="30" r="2.5" /><circle cx="14" cy="30" r="2" />
        <circle cx="72" cy="42" r="3.2" /><circle cx="80" cy="48" r="2.5" />
        <circle cx="92" cy="68" r="3" /><circle cx="100" cy="74" r="2.5" />
        <circle cx="116" cy="108" r="3.2" /><circle cx="124" cy="114" r="2.5" />
        <circle cx="140" cy="160" r="3" /><circle cx="148" cy="166" r="2.5" />
        <circle cx="160" cy="200" r="3" />
      </g>
      <g fill="#B0904F" opacity="0.6">
        <circle cx="22" cy="20" r="1.2" /><circle cx="76" cy="40" r="1.2" />
        <circle cx="96" cy="72" r="1.2" /><circle cx="144" cy="162" r="1.2" />
      </g>
    </svg>
  );
}

function MiniLeaf() {
  return (
    <svg width="64" height="20" viewBox="0 0 64 20" className="mini-leaf">
      <path d="M 4 10 H 60" stroke="#9CA77A" strokeWidth="0.8" />
      <g fill="#9CA77A" opacity="0.8">
        <ellipse cx="14" cy="7" rx="6" ry="2" transform="rotate(-25 14 7)" />
        <ellipse cx="14" cy="13" rx="6" ry="2" transform="rotate(25 14 13)" />
        <ellipse cx="50" cy="7" rx="6" ry="2" transform="rotate(25 50 7)" />
        <ellipse cx="50" cy="13" rx="6" ry="2" transform="rotate(-25 50 13)" />
      </g>
      <circle cx="32" cy="10" r="2.5" fill="#B0904F" />
    </svg>
  );
}

// ─── Icons ────────────────────────────────────────────────────
const ChurchIcon = () => (<svg width="26" height="26" viewBox="0 0 32 32" fill="none" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round"><path d="M16 4 V 12" /><path d="M13 7 H 19" /><path d="M8 14 L 16 10 L 24 14" /><path d="M9 14 V 26 H 23 V 14" /><path d="M14 26 V 19 H 18 V 26" /></svg>);
const GlassIcon = () => (<svg width="26" height="26" viewBox="0 0 32 32" fill="none" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round"><path d="M10 6 H 22 L 20 16 A 4 4 0 0 1 12 16 Z" /><path d="M16 20 V 26" /><path d="M12 26 H 20" /></svg>);
const PinIcon = () => (<svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"><path d="M8 14 C 4 9, 3 7, 3 6 a 5 5 0 0 1 10 0 c 0 1 -1 3 -5 8 z" /><circle cx="8" cy="6" r="1.6" /></svg>);
const SeatIcon = ({ size = 14 }) => (<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M5 11 V 7 a 2 2 0 0 1 2 -2 h 10 a 2 2 0 0 1 2 2 V 11" /><path d="M3 11 h 18 v 5 a 2 2 0 0 1 -2 2 h -1 v 2 M 6 18 v 2 M 6 18 h 12" /></svg>);
const CheckIcon = () => (<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12.5 L10 17.5 L 19 7" /></svg>);
const BookIcon = () => (<svg width="26" height="26" viewBox="0 0 32 32" fill="none" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round"><path d="M16 7 C 13 5, 8 5, 5 6 V 25 c 3 -1 8 -1 11 1" /><path d="M16 7 c 3 -2 8 -2 11 -1 V 25 c -3 -1 -8 -1 -11 1" /><path d="M16 7 V 27" /><path d="M16 11 V 14" /><path d="M14.5 12.5 H 17.5" /></svg>);
const MusicOnIcon = () => (<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"><path d="M9 17 V 5 L 19 3 V 15" /><circle cx="7" cy="17" r="2" /><circle cx="17" cy="15" r="2" /></svg>);
const MusicOffIcon = () => (<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"><path d="M9 17 V 5 L 19 3 V 15" /><circle cx="7" cy="17" r="2" /><circle cx="17" cy="15" r="2" /><path d="M3 3 L 21 21" /></svg>);

// ─── Envelope opening overlay ─────────────────────────────────
function EnvelopeOverlay({ guestName, onOpen }) {
  const [opened, setOpened] = useState(() => sessionStorage.getItem('mm_opened') === '1');
  const [opening, setOpening] = useState(false);

  const handleOpen = () => {
    if (opening) return;
    setOpening(true);
    setTimeout(() => {
      setOpened(true);
      sessionStorage.setItem('mm_opened', '1');
      onOpen && onOpen();
    }, 1600);
  };

  if (opened) return null;

  return (
    <div className={`envelope-overlay${opening ? ' opening' : ''}`} onClick={handleOpen}>
      <div style={{ textAlign: 'center' }}>
        <div className="env-guest-name">{guestName}</div>
        <div className="env-title">Marcela<span className="amp">&amp;</span>Manuel</div>
      </div>
      <div className="envelope-stage">
        <div className="env-back"></div>
        <div className="env-letter">
          <div className="env-letter-eye">— Te invitamos a —</div>
          <div>Nuestra Boda</div>
        </div>
        <div className="env-front"></div>
        <div className="env-flap"></div>
        <div className="env-seal">M&amp;M</div>
      </div>
      <div className="env-instruction">Toca para abrir</div>
    </div>
  );
}

// ─── Music toggle ─────────────────────────────────────────────
function MusicToggle() {
  const [playing, setPlaying] = useState(false);
  const [hasAudio, setHasAudio] = useState(true);
  const audioRef = useRef(null);

  useEffect(() => {
    const a = new Audio('fotos/audio.mp3');
    a.loop = true; a.volume = 0.45;
    a.addEventListener('error', () => setHasAudio(false));
    audioRef.current = a;
    return () => { a.pause(); audioRef.current = null; };
  }, []);

  const toggle = () => {
    const a = audioRef.current; if (!a) return;
    if (playing) { a.pause(); setPlaying(false); }
    else { a.play().then(() => setPlaying(true)).catch(() => setHasAudio(false)); }
  };

  if (!hasAudio) return null;
  return (
    <button className={`music-toggle${playing ? ' playing' : ''}`} onClick={toggle} aria-label={playing ? 'Pausar música' : 'Reproducir música'}>
      {playing ? <MusicOnIcon /> : <MusicOffIcon />}
    </button>
  );
}

// ─── Gallery ──────────────────────────────────────────────────
function Gallery() {
  const [photos, setPhotos] = useState(null);
  const [active, setActive] = useState(0);
  const railRef = useRef(null);

  useEffect(() => {
    // Primero las fotos subidas desde el panel (base de datos); si no hay,
    // se usa el manifest estático (fotos/manifest.json) como respaldo.
    fetch('api/photos', { cache: 'no-store' })
      .then(r => r.ok ? r.json() : [])
      .then(data => {
        if (Array.isArray(data) && data.length) { setPhotos(data); return; }
        return fetch('fotos/manifest.json', { cache: 'no-store' })
          .then(r => r.ok ? r.json() : [])
          .then(m => setPhotos(Array.isArray(m) ? m : []));
      })
      .catch(() => setPhotos([]));
  }, []);

  useEffect(() => {
    const rail = railRef.current; if (!rail) return;
    const onScroll = () => {
      const w = rail.children[0]?.offsetWidth || 1;
      const gap = 14;
      const idx = Math.round(rail.scrollLeft / (w + gap));
      setActive(idx);
    };
    rail.addEventListener('scroll', onScroll, { passive: true });
    return () => rail.removeEventListener('scroll', onScroll);
  }, [photos]);

  if (photos === null) return null;

  // If no photos, show 4 placeholders
  const items = photos.length ? photos : Array.from({ length: 4 }).map((_, i) => ({ placeholder: i + 1 }));

  return (
    <section className="gallery-section">
      <div className="gallery-head reveal">
        <div className="eyebrow">Nuestra historia</div>
        <MiniLeaf />
        <div className="script-title">Galería</div>
        <p className="body">
          Algunos momentos que nos trajeron hasta aquí.
        </p>
      </div>
      <div className="gallery-rail reveal delay-1" ref={railRef}>
        {items.map((p, i) => (
          <div className="gallery-card" key={i}>
            {p.placeholder ? (
              <div className="gallery-placeholder">
                <div className="gallery-placeholder-num">{String(p.placeholder).padStart(2, '0')}</div>
                <MiniLeaf />
                <div className="gallery-placeholder-text">Foto · {p.placeholder}</div>
                <div style={{ fontFamily: "'Cormorant Garamond', serif", fontStyle: 'italic', fontSize: 13, color: 'var(--ink-soft)', marginTop: 4 }}>
                  agrega tus fotos<br/>en /fotos/
                </div>
              </div>
            ) : (
              <img src={p.src} alt={p.caption || ''} loading="lazy" onError={(e) => { e.currentTarget.style.display = 'none'; }} />
            )}
          </div>
        ))}
      </div>
      <div className="gallery-dots reveal delay-2">
        {items.map((_, i) => (<div key={i} className={`gallery-dot${i === active ? ' active' : ''}`}></div>))}
      </div>
    </section>
  );
}

// ─── RSVP Form ────────────────────────────────────────────────
function RsvpForm({ defaultName, defaultPases, mesaText, guestToken, waNumber, onSubmitted }) {
  // La confirmación se cachea por invitado (token o nombre del titular) para que
  // una respuesta previa NO se muestre al abrir otra invitación en el mismo navegador.
  const storageKey = `mm_rsvp_${guestToken || defaultName || 'anon'}`;
  const [submitted, setSubmitted] = useState(() => {
    try { return JSON.parse(localStorage.getItem(storageKey) || 'null'); } catch { return null; }
  });

  // Limpia la clave global antigua que dejaba el saludo "fijado" entre invitaciones.
  useEffect(() => { try { localStorage.removeItem('mm_rsvp'); } catch {} }, []);
  const [attending, setAttending] = useState('si');
  const [name, setName] = useState(defaultName || '');
  const [pases, setPases] = useState(defaultPases || 1);
  const [notes, setNotes] = useState('');
  const [busy, setBusy] = useState(false);

  const submit = (e) => {
    e.preventDefault();
    if (busy) return;
    setBusy(true);
    const payload = {
      attending, name: name.trim(), pases: attending === 'si' ? pases : 0,
      notes: notes.trim(),
      mesa: mesaText || '',
      timestamp: new Date().toISOString(),
    };
    localStorage.setItem(storageKey, JSON.stringify(payload));

    // Save to backend DB (best-effort — WhatsApp still works if the API is down)
    const dbSave = fetch('api/rsvp', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        nombre: payload.name,
        attending: payload.attending,
        pases: payload.pases,
        mesa: payload.mesa,
        notes: payload.notes,
        guest_token: guestToken || '',
      }),
    }).catch(() => {});

    // Build WhatsApp message
    const lines = [
      `*RSVP — Boda Marcela & Manuel*`,
      ``,
      `Nombre: ${payload.name || '(sin nombre)'}`,
      attending === 'si' ? `✅ Confirmo mi asistencia` : `❌ No podré asistir`,
    ];
    if (attending === 'si') {
      lines.push(`Personas: ${payload.pases}`);
      if (payload.mesa) lines.push(`Mesa: ${payload.mesa}`);
    }
    if (payload.notes) lines.push(``, `Mensaje: ${payload.notes}`);
    const text = encodeURIComponent(lines.join('\n'));
    const num = (waNumber || '50372470414').replace(/[^0-9]/g, '');
    const wa = `https://wa.me/${num}?text=${text}`;

    dbSave.finally(() => {
      window.open(wa, '_blank');
      setSubmitted(payload);
      setBusy(false);
      onSubmitted && onSubmitted(payload);
    });
  };

  const reset = () => { localStorage.removeItem(storageKey); setSubmitted(null); };

  if (submitted) {
    return (
      <div className="confirm-state reveal in">
        <div className="confirm-check"><CheckIcon /></div>
        <div className="confirm-title">¡Gracias, {defaultName || submitted.name || 'invitado'}!</div>
        <div className="confirm-msg">
          {submitted.attending === 'si'
            ? `Tu asistencia para ${submitted.pases} ${submitted.pases === 1 ? 'persona' : 'personas'} ha sido registrada. Nos vemos el 18 de julio.`
            : 'Lamentamos que no puedas acompañarnos. Gracias por avisarnos.'}
        </div>
        <button type="button" className="reset-link" onClick={reset}>Editar respuesta</button>
      </div>
    );
  }

  return (
    <form className="rsvp-form reveal delay-1" onSubmit={submit}>
      <div className="field">
        <label>¿Podrás acompañarnos?</label>
        <div className="attend-toggle">
          <button type="button" className={`attend-btn${attending === 'si' ? ' active' : ''}`} onClick={() => setAttending('si')}>Sí, asistiré</button>
          <button type="button" className={`attend-btn no${attending === 'no' ? ' active' : ''}`} onClick={() => setAttending('no')}>No podré</button>
        </div>
      </div>

      <div className="field">
        <label>Tu nombre</label>
        <input type="text" value={name} onChange={e => setName(e.target.value)} placeholder="Nombre completo" required />
      </div>

      {attending === 'si' && (
        <>
          <div className="field-row">
            <div className="field">
              <label>Personas</label>
              <select value={pases} onChange={e => setPases(parseInt(e.target.value, 10))}>
                {Array.from({ length: Math.max(defaultPases || 4, 6) }).map((_, i) => (
                  <option key={i + 1} value={i + 1}>{i + 1}</option>
                ))}
              </select>
            </div>
            {mesaText && (
              <div className="field">
                <label>Tu mesa</label>
                <input type="text" value={mesaText} disabled style={{ fontStyle: 'italic', color: 'var(--olive)' }} />
              </div>
            )}
          </div>
        </>
      )}

      <div className="field">
        <label>Mensaje a los novios</label>
        <textarea value={notes} onChange={e => setNotes(e.target.value)} placeholder="Déjanos un mensaje (opcional)" rows="3"></textarea>
      </div>

      <button type="submit" className="submit-btn" disabled={busy}>
        {busy ? 'Enviando...' : 'Confirmar por WhatsApp →'}
      </button>
    </form>
  );
}

// ─── Main App ─────────────────────────────────────────────────
function App() {
  useReveal();
  const cd = useCountdown();
  const urlParams = useMemo(() => getParams(), []);
  const [guest, setGuest] = useState(null);
  const [settings, setSettings] = useState(null);

  // If the link carries a token (?t=abc123), pull the guest's data from the DB.
  useEffect(() => {
    if (!urlParams.token) return;
    fetch(`api/guest-by-token/${encodeURIComponent(urlParams.token)}`)
      .then(r => (r.ok ? r.json() : null))
      .then(g => g && setGuest(g))
      .catch(() => {});
  }, [urlParams.token]);

  // Configuración editable desde el panel (teléfonos, misal).
  useEffect(() => {
    fetch('api/settings')
      .then(r => (r.ok ? r.json() : null))
      .then(s => s && setSettings(s))
      .catch(() => {});
  }, []);

  const telMarce = settings?.tel_marce || '+50372470414';
  const telManuel = settings?.tel_manuel || '+50300000000';
  const waRsvp = settings?.wa_rsvp || '50372470414';
  const hasMisal = !!settings?.misal;

  // DB values (via token) take precedence; URL params are the fallback.
  const nombre = guest?.nombre || urlParams.nombre;
  const pases = guest?.pases || urlParams.pases;
  const mesa = guest?.mesa || urlParams.mesa;
  const tipo = (guest?.tipo || urlParams.tipo || '').toLowerCase();
  const mensaje = guest?.mensaje || urlParams.mensaje;

  const guestName = nombre || 'Querido invitado';
  const tipoLabel = tipo ? `Lado ${tipo}` : null;

  return (
    <div className="app">
      <EnvelopeOverlay guestName={guestName} />
      <MusicToggle />
      <PetalLayer />

      {/* HERO */}
      <section className="hero">
        <div className="botanical bot-tl sway-slow"><BotanicalCorner size={220} /></div>
        <div className="botanical bot-tr sway-rev"><BotanicalCorner size={220} /></div>
        <div className="botanical bot-bl sway-rev"><BotanicalCorner size={180} /></div>
        <div className="botanical bot-br sway-slow"><BotanicalCorner size={180} /></div>

        <div className="hero-content">
          <div className="hero-anim-1">
            {tipoLabel && <div className="guest-tag">{tipoLabel}</div>}
            <div className="guest-greeting">— Para —</div>
            <div className="guest-name">{guestName}</div>
          </div>

          <div className="hero-anim-2">
            <div className="couple-eyebrow">Boda · Guzmán · Ponce</div>
          </div>

          <div className="hero-anim-3">
            <div className="couple-names">Marcela<span className="amp">&amp;</span>Manuel</div>
          </div>

          <div className="hero-anim-4">
            <MiniLeaf />
            <div className="hero-tagline">¡Nos casamos!</div>
          </div>

          <div className="hero-anim-5">
            <div className="hero-date">Sábado · 18 Julio 2026</div>
            {pases > 0 && (
              <div className="seat-badge">
                <SeatIcon /> {pases} {pases === 1 ? 'pase reservado' : 'pases reservados'}
              </div>
            )}
            {mesa && <div className="table-badge">Mesa {mesa}</div>}
            {mensaje && <div className="personal-msg">"{mensaje}"</div>}
          </div>
        </div>

        <div className="scroll-cue">
          <span>Desliza</span>
          <svg width="10" height="14" viewBox="0 0 10 14" fill="none" stroke="currentColor" strokeWidth="1.2"><path d="M5 1 V 12 M 1 8 L 5 12 L 9 8" strokeLinecap="round" strokeLinejoin="round" /></svg>
        </div>
      </section>

      {/* QUOTE */}
      <section className="quote-section">
        <div className="reveal">
          <div className="eyebrow">Te invitamos a nuestra boda</div>
          <p className="quote">Dios ha llenado nuestros corazones con su inmenso amor y sabemos que con Él construiremos un hogar lleno de paz.</p>
          <div className="reveal delay-1" style={{ marginTop: 28, fontFamily: "'Cormorant Garamond', serif", fontStyle: 'italic', fontSize: 18, color: 'var(--ink-soft)' }}>
            Acompáñanos a sellar nuestro amor.
          </div>
        </div>
      </section>

      {/* GALLERY */}
      <Gallery />

      {/* SAVE THE DATE */}
      <section className="date-section">
        <div className="reveal">
          <div className="eyebrow">Save the date</div>
          <MiniLeaf />
        </div>
        <div className="reveal delay-1">
          <div className="date-card">
            <div style={{ fontFamily: "'Inter', sans-serif", fontSize: 10, letterSpacing: '0.4em', color: 'var(--olive)', textTransform: 'uppercase', marginBottom: 8 }}>Sábado</div>
            <div className="date-day">18</div>
            <div className="date-month">Julio</div>
            <div className="date-year">2026</div>
          </div>
        </div>
        <div className="countdown reveal delay-2">
          <div className="cd-cell"><div className="cd-num">{cd.d}</div><div className="cd-lab">Días</div></div>
          <div className="cd-cell"><div className="cd-num">{String(cd.h).padStart(2,'0')}</div><div className="cd-lab">Horas</div></div>
          <div className="cd-cell"><div className="cd-num">{String(cd.m).padStart(2,'0')}</div><div className="cd-lab">Min</div></div>
          <div className="cd-cell"><div className="cd-num">{String(cd.s).padStart(2,'0')}</div><div className="cd-lab">Seg</div></div>
        </div>
      </section>

      {/* CEREMONY */}
      <section className="event-section ceremony">
        <div className="botanical bot-tl" style={{opacity: 0.4}}><BotanicalCorner size={140} /></div>
        <div className="botanical bot-br" style={{opacity: 0.4}}><BotanicalCorner size={140} /></div>
        <div className="reveal">
          <div className="event-icon"><ChurchIcon /></div>
          <div className="event-title">Ceremonia</div>
          <div style={{ fontFamily: "'Inter', sans-serif", fontSize: 10, letterSpacing: '0.32em', color: 'var(--gold)', textTransform: 'uppercase', marginBottom: 18 }}>Religiosa</div>
          <div className="event-place">Parroquia El Calvario</div>
          <div className="event-time"><span className="tdot"></span>2:30 pm<span className="tdot"></span></div>
          <div className="event-address">Carretera Panamericana 5-3<br/>Santa Tecla</div>
          <a className="map-btn" href="https://www.google.com/maps/search/?api=1&query=Parroquia+El+Calvario+Santa+Tecla" target="_blank" rel="noreferrer"><PinIcon /> Ver mapa</a>
        </div>
      </section>

      {/* RECEPTION */}
      <section className="event-section reception">
        <div className="botanical bot-tr" style={{opacity: 0.4}}><BotanicalCorner size={140} /></div>
        <div className="botanical bot-bl" style={{opacity: 0.4}}><BotanicalCorner size={140} /></div>
        <div className="reveal">
          <div className="event-icon"><GlassIcon /></div>
          <div className="event-title">Recepción</div>
          <div style={{ fontFamily: "'Inter', sans-serif", fontSize: 10, letterSpacing: '0.32em', color: 'var(--gold)', textTransform: 'uppercase', marginBottom: 18 }}>Cena & celebración</div>
          <div className="event-place">Quinta Las Tumbergias</div>
          <div className="event-time"><span className="tdot"></span>5:00 pm — 10:00 pm<span className="tdot"></span></div>
          <div className="event-address">Volcán de San Salvador<br/>Cantón Álvarez, Finca Florencia<br/>Calle principal, casa #2<br/>Santa Tecla 1502</div>
          <div className="event-ref">Referencia: arriba de Volcatenango</div>
          <a className="map-btn" href="https://www.google.com/maps/search/?api=1&query=Quinta+Las+Tumbergias+Volcan+San+Salvador" target="_blank" rel="noreferrer"><PinIcon /> Ver mapa</a>
        </div>
      </section>

      {/* MISAL */}
      {hasMisal && (
        <section className="event-section ceremony">
          <div className="reveal">
            <div className="event-icon"><BookIcon /></div>
            <div className="event-title">Misal</div>
            <div style={{ fontFamily: "'Inter', sans-serif", fontSize: 10, letterSpacing: '0.32em', color: 'var(--gold)', textTransform: 'uppercase', marginBottom: 18 }}>Orden de la ceremonia</div>
            <p className="body" style={{ marginBottom: 24 }}>Sigue la celebración religiosa con nuestro misal. Puedes verlo o descargarlo aquí.</p>
            <a className="map-btn" href="misal.pdf" target="_blank" rel="noreferrer"><BookIcon /> Ver misal</a>
          </div>
        </section>
      )}

      {/* DRESS CODE */}
      <section className="dress-section">
        <div className="reveal">
          <div className="eyebrow">Código de vestimenta</div>
          <MiniLeaf />
          <div className="script-title">Vestimenta formal</div>
        </div>
        <div className="reveal delay-1">
          <div style={{ fontFamily: "'Inter', sans-serif", fontSize: 10, letterSpacing: '0.28em', color: 'var(--ink-soft)', textTransform: 'uppercase', marginTop: 18 }}>Mujeres — favor evitar</div>
          <div className="swatch-row">
            <div className="swatch"><div className="swatch-circle no" style={{ background: '#FBF8F0' }}></div><div className="swatch-label">Blanco</div></div>
            <div className="swatch"><div className="swatch-circle no" style={{ background: '#C4CCA9' }}></div><div className="swatch-label">Verde olivo</div></div>
          </div>
          <div className="dress-note">Estos son los colores de la novia y de la decoración.</div>
        </div>
      </section>

      {/* GIFT */}
      <section className="gift-section">
        <div className="reveal">
          <div className="envelope-wrap">
            <svg width="100" height="70" viewBox="0 0 100 70">
              <rect x="1" y="1" width="98" height="68" fill="#FBF8F0" stroke="#B0904F" strokeWidth="1.2" />
              <path d="M 1 1 L 50 38 L 99 1" fill="none" stroke="#B0904F" strokeWidth="1.2" />
              <path d="M 18 28 q 6 -10 16 0 q 10 -10 16 0 q -8 8 -16 14 q -8 -6 -16 -14 z" fill="#D4B97A" opacity="0.6" />
            </svg>
          </div>
          <div className="eyebrow">Mesa de regalos</div>
          <MiniLeaf />
          <div className="script-title" style={{ marginBottom: 18 }}>Lluvia de sobres</div>
          <p className="body">Agradecemos tus muestras de cariño en regalo de sobre. Tu presencia es nuestro mejor regalo.</p>
        </div>
      </section>

      {/* RSVP */}
      <section className="rsvp-section">
        <div className="botanical bot-tl" style={{opacity: 0.35}}><BotanicalCorner size={120} /></div>
        <div className="botanical bot-tr" style={{opacity: 0.35}}><BotanicalCorner size={120} /></div>
        <div className="reveal">
          <div className="eyebrow">Confirma tu asistencia</div>
          <MiniLeaf />
          <p className="body" style={{ marginBottom: 8 }}>Para reservar tu espacio es indispensable confirmar tu asistencia.</p>
          <div className="rsvp-deadline">Antes del 30 de junio 2026</div>
        </div>
        <RsvpForm defaultName={nombre} defaultPases={pases || 1} mesaText={mesa} guestToken={urlParams.token} waNumber={waRsvp} />
        <div className="alt-contact reveal delay-2">
          ¿Prefieres llamar?
          <a href={`tel:${telMarce}`}>Marce</a>·
          <a href={`tel:${telManuel}`}>Manuel</a>
        </div>
      </section>

      {/* FOOTER */}
      <div className="footer">
        <div className="footer-mono">M &amp; M</div>
        <div className="footer-text">18 · 07 · 2026</div>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
