// rsvp.jsx — Confirmación personalizada + seguridad del enlace.
// Exporta: RSVP, AccessGate, useSecurity.

const { T: T3 } = window;

// —————————————————————————— SEGURIDAD DEL ENLACE ——————————————————————————
// Estrategia (la más eficiente sin servidor propio):
//  1) Cada enlace lleva ?id=INVxxx&k=TOKEN. Sin el token correcto, no abre.
//  2) En la 1ª apertura se "vincula" el enlace a este dispositivo (localStorage).
//  3) Se registra cada apertura en la hoja (id + huella de dispositivo + hora).
//     Si el mismo id se abre desde OTRO dispositivo → el Apps Script marca
//     "POSIBLE REENVÍO" y te envía un correo de alerta. Ver la guía incluida.
function getDeviceId() {
  let d = localStorage.getItem('dd_device');
  if (!d) { d = 'dev_' + Math.random().toString(36).slice(2, 10) + Date.now().toString(36); localStorage.setItem('dd_device', d); }
  return d;
}

function post(payload) {
  const url = window.CONFIG.WEBHOOK_URL;
  const body = JSON.stringify({ ...payload, secret: window.CONFIG.formSecret });
  if (!url) { console.log('[RSVP modo demo] payload →', JSON.parse(body)); return Promise.resolve({ demo: true }); }
  return fetch(url, { method: 'POST', mode: 'no-cors', headers: { 'Content-Type': 'text/plain;charset=utf-8' }, body })
    .then(() => ({ ok: true }));
}

function useSecurity(invite) {
  React.useEffect(() => {
    if (!invite || invite.status !== 'ok') return;
    const id = invite.id, dev = getDeviceId();
    const claimKey = 'dd_claim_' + id;
    const firstDevice = localStorage.getItem(claimKey);
    const isNewDeviceForThisLink = firstDevice && firstDevice !== dev; // raro en el mismo equipo
    if (!firstDevice) localStorage.setItem(claimKey, dev);
    // registra la apertura (el servidor decide si es reenvío comparando dispositivos)
    post({
      type: 'apertura', id, nombre: invite.nombre, deviceId: dev,
      nuevoDispositivoLocal: !!isNewDeviceForThisLink,
      ua: navigator.userAgent, referrer: document.referrer || '', ts: new Date().toISOString(),
    }).catch(() => {});
  }, [invite && invite.id, invite && invite.status]);
}

// —————————————————————————— PUERTA DE ACCESO ——————————————————————————
function AccessGate({ invite, children }) {
  if (invite.status === 'ok' || invite.status === 'none') return children;
  // denied / invalid → pantalla de bloqueo
  const denied = invite.status === 'denied';
  return (
    <div style={{ minHeight: '100svh', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 28, textAlign: 'center' }}>
      <div style={{ position: 'absolute', inset: 'clamp(12px,3vw,26px)', border: `1px solid ${T3.ink}`, opacity: 0.25 }} />
      <div style={{ maxWidth: 460, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 18 }}>
        <StepDiamond size={30} color={T3.ink} />
        <Micro size={11} ls=".34em" color={T3.accent}>Invitación personal</Micro>
        <h1 className="serif" style={{ fontSize: 'clamp(30px,7vw,46px)', fontWeight: 600, lineHeight: 1.05 }}>
          {denied ? 'Este enlace no es válido' : 'No encontramos tu invitación'}
        </h1>
        <p className="ital" style={{ fontSize: 'clamp(17px,3vw,20px)', color: T3.soft, lineHeight: 1.6, textWrap: 'pretty' }}>
          Cada invitación de Diana &amp; Daniel es única y personal. Por favor abre el enlace
          completo que recibiste, o escríbenos para reenviártelo.
        </p>
        <Rule width={200} style={{ marginTop: 6 }} />
        <Micro size={10} ls=".2em" color={T3.soft}>Diana &amp; Daniel · 07·11·2026</Micro>
      </div>
    </div>
  );
}

// —————————————————————————— FORMULARIO RSVP ——————————————————————————
function Field({ label, children }) {
  return (
    <label style={{ display: 'block', textAlign: 'left' }}>
      <Micro as="span" size={10} ls=".22em" color={T3.soft} style={{ display: 'block', marginBottom: 9 }}>{label}</Micro>
      {children}
    </label>
  );
}

function RSVP({ invite }) {
  const isOk = invite.status === 'ok';
  const demo = !isOk || invite.demo;
  const nombre = isOk ? invite.nombre : 'Nuestros invitados';
  const maxPases = isOk ? invite.pases : 2;
  const id = isOk ? invite.id : 'DEMO';
  const acomp = isOk && invite.acomp && invite.acomp !== 'TBD' ? invite.acomp : null;

  const storeKey = 'dd_rsvp_' + id;
  const prev = React.useMemo(() => { try { return JSON.parse(localStorage.getItem(storeKey) || 'null'); } catch { return null; } }, [storeKey]);

  const [confirmName, setConfirmName] = React.useState(prev?.nombre || (isOk && !invite.demo ? invite.nombre : ''));
  const [asiste, setAsiste] = React.useState(prev?.asiste ?? null); // true | false | null
  const [pases, setPases] = React.useState(prev?.pases || maxPases);
  const [mensaje, setMensaje] = React.useState(prev?.mensaje || '');
  const [state, setState] = React.useState(prev ? 'done' : 'idle'); // idle | sending | done | error

  const inputStyle = {
    width: '100%', background: T3.bg, border: `1px solid ${T3.line}`, color: T3.ink,
    padding: '14px 16px', fontFamily: T3.micro, fontSize: 16, borderRadius: 2, outline: 'none', transition: 'border-color .3s',
  };

  const submit = async (e) => {
    e.preventDefault();
    if (!confirmName.trim() || asiste === null) return;
    setState('sending');
    const payload = {
      type: 'rsvp', id, nombreConfirmacion: confirmName.trim(),
      estatus: asiste ? 'Asiste' : 'No asiste',
      pasesConfirmados: asiste ? pases : 0,
      mensaje: mensaje.trim(), deviceId: getDeviceId(), ts: new Date().toISOString(),
    };
    try {
      await post(payload);
      localStorage.setItem(storeKey, JSON.stringify({ nombre: confirmName.trim(), asiste, pases, mensaje }));
      setState('done');
    } catch { setState('error'); }
  };

  // — estado de agradecimiento —
  if (state === 'done') {
    const yes = (prev?.asiste ?? asiste) === true;
    return (
      <section id="rsvp" style={{ padding: 'clamp(64px,10vh,120px) 22px', background: T3.deep, color: T3.bg }}>
        <div style={{ maxWidth: 560, margin: '0 auto', textAlign: 'center', display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
          <StepDiamond size={32} color={T3.bg} />
          <Micro size={11} ls=".34em" color={T3.accent} style={{ marginTop: 18 }}>{yes ? 'Confirmación recibida' : 'Gracias por avisarnos'}</Micro>
          <h2 className="serif" style={{ fontSize: 'clamp(34px,7vw,56px)', fontWeight: 600, marginTop: 10, lineHeight: 1.05 }}>
            {yes ? '¡Nos vemos en Oaxaca!' : 'Te vamos a extrañar'}
          </h2>
          <p className="ital" style={{ fontSize: 'clamp(18px,3vw,22px)', color: 'rgba(236,227,207,.85)', marginTop: 16, lineHeight: 1.6, textWrap: 'pretty' }}>
            {yes
              ? `Gracias, ${(prev?.nombre || confirmName).split(' ')[0]}. Guardamos tu lugar con mucho cariño y contamos los días para celebrar contigo.`
              : 'Lamentamos que no puedas acompañarnos. Gracias por tomarte un momento para avisarnos; estarás en nuestros pensamientos ese día.'}
          </p>
          <Rule width={200} diamond={T3.accent} color="rgba(236,227,207,.3)" style={{ margin: '26px 0' }} />
          <button onClick={() => setState('idle')} style={{ cursor: 'pointer', background: 'transparent', border: `1px solid rgba(236,227,207,.5)`, color: T3.bg,
            padding: '11px 20px', fontFamily: T3.micro, fontSize: 11, letterSpacing: '.16em', textTransform: 'uppercase', fontWeight: 600, borderRadius: 2 }}>
            Editar mi respuesta
          </button>
        </div>
      </section>
    );
  }

  return (
    <section id="rsvp" style={{ padding: 'clamp(64px,10vh,120px) 22px', background: T3.deep, color: T3.bg }}>
      <div style={{ maxWidth: 560, margin: '0 auto', textAlign: 'center' }}>
        <Reveal><div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14, marginBottom: 8 }}>
          <Micro size={11} ls=".34em" color={T3.accent}>Confirma tu asistencia</Micro>
          <div style={{ width: 64 }}><Greca color={T3.bg} step={5} ups={3} strokeWidth={1.3} /></div>
        </div></Reveal>
        <Reveal delay={60}><h2 className="serif" style={{ fontSize: 'clamp(34px,7vw,56px)', fontWeight: 600, marginTop: 6, lineHeight: 1.02 }}>
          ¡Hola, {nombre}!
        </h2></Reveal>
        <Reveal delay={120}><p className="ital" style={{ fontSize: 'clamp(17px,2.8vw,21px)', color: 'rgba(236,227,207,.85)', marginTop: 14, lineHeight: 1.6 }}>
          {isOk
            ? (acomp
                ? <>Reservamos un lugar para <strong style={{ color: T3.bg, fontWeight: 600 }}>ti y {acomp}</strong>. Confírmanos antes del 15 de septiembre.</>
                : maxPases === 1
                  ? <>Reservamos <strong style={{ color: T3.bg, fontWeight: 600 }}>un lugar</strong> a tu nombre. Confírmanos antes del 15 de septiembre.</>
                  : <>Tenemos <strong style={{ color: T3.bg, fontWeight: 600 }}>{maxPases} lugares reservados</strong> a tu nombre. Confírmanos antes del 15 de septiembre.</>)
            : 'Vista previa del formulario. Comparte un enlace personal (con ?id=…) para activar el saludo y los pases de cada invitado.'}
        </p></Reveal>

        <Reveal delay={160}>
          <form onSubmit={submit} style={{ marginTop: 36, display: 'flex', flexDirection: 'column', gap: 22, textAlign: 'left' }}>
            <Field label="Nombre de quien confirma">
              <input style={inputStyle} value={confirmName} onChange={(e) => setConfirmName(e.target.value)}
                placeholder="Tu nombre completo" required
                onFocus={(e) => e.target.style.borderColor = T3.accent} onBlur={(e) => e.target.style.borderColor = T3.line} />
            </Field>

            <Field label="¿Podrás acompañarnos?">
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                {[[true, 'Sí, asistiré'], [false, 'No podré asistir']].map(([val, txt]) => {
                  const active = asiste === val;
                  return (
                    <button type="button" key={String(val)} onClick={() => setAsiste(val)}
                      style={{ cursor: 'pointer', padding: '15px 12px', borderRadius: 2, fontFamily: T3.micro, fontSize: 13, letterSpacing: '.08em', fontWeight: 600,
                        textTransform: 'uppercase', transition: 'all .3s', border: `1px solid ${active ? T3.accent : 'rgba(236,227,207,.4)'}`,
                        background: active ? T3.accent : 'transparent', color: active ? '#fff' : 'rgba(236,227,207,.85)' }}>
                      {txt}
                    </button>
                  );
                })}
              </div>
            </Field>

            <div style={{ display: 'grid', gridTemplateRows: asiste === true ? '1fr' : '0fr', transition: 'grid-template-rows .45s ease', overflow: 'hidden' }}>
              <div style={{ minHeight: 0 }}>
                {maxPases === 1 ? (
                  /* invitación individual: sin dropdown, confirmación fija */
                  <Field label="¿Quiénes asistirán?">
                    <div style={{ display: 'flex', alignItems: 'center', gap: 12, background: T3.bg, border: `1px solid ${T3.line}`, padding: '14px 16px', borderRadius: 2 }}>
                      <StepDiamond size={14} color={T3.accent} />
                      <span style={{ fontFamily: T3.micro, fontSize: 16, color: T3.ink, fontWeight: 600 }}>
                        {isOk ? `${nombre} · 1 persona` : '1 persona'}
                      </span>
                    </div>
                    <Micro as="span" size={9} ls=".14em" color="rgba(236,227,207,.5)" style={{ display: 'block', marginTop: 8 }}>
                      Esta invitación es individual
                    </Micro>
                  </Field>
                ) : (
                  /* invitación para dos: opciones con nombres reales */
                  <Field label="¿Quiénes asistirán?">
                    <div style={{ position: 'relative' }}>
                      <select style={{ ...inputStyle, appearance: 'none', cursor: 'pointer' }} value={pases} onChange={(e) => setPases(Number(e.target.value))}>
                        <option value={1}>{acomp ? `Solo ${nombre.split(' ')[0]} · 1 persona` : 'Solo yo · 1 persona'}</option>
                        <option value={2}>{acomp ? `${nombre.split(' ')[0]} y ${acomp} · 2 personas` : 'Con mi acompañante · 2 personas'}</option>
                      </select>
                      <span style={{ position: 'absolute', right: 16, top: '50%', transform: 'translateY(-50%)', pointerEvents: 'none', color: T3.accent }}>▾</span>
                    </div>
                    <Micro as="span" size={9} ls=".14em" color="rgba(236,227,207,.5)" style={{ display: 'block', marginTop: 8 }}>
                      {acomp ? `Tu invitación incluye un lugar para ${acomp}` : 'Tu invitación incluye un lugar para tu acompañante'}
                    </Micro>
                  </Field>
                )}
              </div>
            </div>

            <Field label="Un mensaje para los novios (opcional)">
              <textarea style={{ ...inputStyle, resize: 'vertical', minHeight: 96, lineHeight: 1.5 }} value={mensaje}
                onChange={(e) => setMensaje(e.target.value)} placeholder="Déjanos unas palabras…"
                onFocus={(e) => e.target.style.borderColor = T3.accent} onBlur={(e) => e.target.style.borderColor = T3.line} />
            </Field>

            <button type="submit" disabled={state === 'sending' || !confirmName.trim() || asiste === null}
              style={{ marginTop: 6, cursor: state === 'sending' ? 'wait' : 'pointer', background: T3.accent, color: '#fff', border: 'none',
                padding: '17px 24px', fontFamily: T3.micro, fontSize: 13, letterSpacing: '.2em', textTransform: 'uppercase', fontWeight: 600,
                borderRadius: 2, transition: 'opacity .3s, transform .2s', opacity: (!confirmName.trim() || asiste === null) ? 0.45 : 1 }}>
              {state === 'sending' ? 'Enviando…' : 'Enviar confirmación'}
            </button>

            {state === 'error' && <Micro size={10} ls=".1em" color="#f0b8a0" style={{ textAlign: 'center' }}>Hubo un problema. Intenta de nuevo o escríbenos directamente.</Micro>}

            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, marginTop: 4, opacity: 0.6 }}>
              <span style={{ color: T3.accent }}>⬩</span>
              <Micro size={9} ls=".16em" color="rgba(236,227,207,.7)">Enlace personal e intransferible{demo ? ' · modo demo' : ''}</Micro>
            </div>
          </form>
        </Reveal>
      </div>
    </section>
  );
}

Object.assign(window, { RSVP, AccessGate, useSecurity, getDeviceId });
