// Auth layer — login, forgot, reset, invite panels + AuthGate wrapper
const { useState, useEffect, createContext, useContext } = React;

const _AuthCtx = createContext(null);

// ── Styles ────────────────────────────────────────────────────────────────────
const S = {
  screen: {
    position: 'fixed', inset: 0, background: 'var(--canvas)',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    zIndex: 1000,
  },
  card: {
    width: '100%', maxWidth: '400px', padding: '40px 36px',
    background: '#1a1a1a', border: '1px solid #2a2a2a', borderRadius: '16px',
    display: 'flex', flexDirection: 'column', gap: '8px',
  },
  wordmark: {
    fontFamily: 'var(--f-mono)', fontSize: '22px', fontWeight: 700,
    color: 'var(--mint)', letterSpacing: '-0.5px', marginBottom: '8px',
    textAlign: 'center',
  },
  title: {
    fontFamily: 'var(--f-sans)', fontSize: '14px', fontWeight: 500,
    color: 'var(--text-meta)', textAlign: 'center', marginBottom: '16px',
  },
  input: {
    width: '100%', padding: '10px 14px', background: '#111', border: '1px solid #333',
    borderRadius: '8px', color: 'var(--text)', fontFamily: 'var(--f-sans)', fontSize: '14px',
    outline: 'none', boxSizing: 'border-box', transition: 'border-color .15s',
  },
  btn: {
    width: '100%', padding: '11px', background: 'var(--mint)', border: 'none',
    borderRadius: '8px', color: '#131313', fontFamily: 'var(--f-sans)', fontSize: '14px',
    fontWeight: 700, cursor: 'pointer', transition: 'opacity .15s',
  },
  ghost: {
    width: '100%', padding: '10px', background: 'transparent',
    border: '1px solid #333', borderRadius: '8px', color: 'var(--text-muted)',
    fontFamily: 'var(--f-sans)', fontSize: '14px', cursor: 'pointer',
  },
  link: {
    background: 'none', border: 'none', color: 'var(--text-meta)', fontSize: '13px',
    cursor: 'pointer', textDecoration: 'underline', padding: '4px 0', fontFamily: 'var(--f-sans)',
  },
  msg: (ok) => ({
    padding: '10px 14px', borderRadius: '8px', fontSize: '13px',
    background: ok ? 'rgba(60,255,208,.12)' : 'rgba(255,76,76,.12)',
    color: ok ? 'var(--mint)' : '#ff4c4c',
  }),
  privacyRow: {
    display: 'flex', alignItems: 'flex-start', gap: '8px', fontSize: '13px',
    color: 'var(--text-meta)',
  },
  gap16: { display: 'flex', flexDirection: 'column', gap: '12px' },
};

function Msg({ text, ok }) {
  if (!text) return null;
  return <div style={S.msg(ok)}>{text}</div>;
}

// ── Login panel ───────────────────────────────────────────────────────────────
function LoginPanel({ onAuth, switchTo, appendMsg }) {
  const [email, setEmail] = useState('');
  const [pw, setPw] = useState('');
  const [busy, setBusy] = useState(false);
  const [msg, setMsg] = useState(null);
  const [needsVerify, setNeedsVerify] = useState(false);

  async function submit() {
    if (!email || !pw) { setMsg({ text: 'Rellena email y contraseña', ok: false }); return; }
    setBusy(true);
    try {
      const r = await fetch('/api/auth/login', {
        method: 'POST', credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email: email.trim().toLowerCase(), password: pw }),
      });
      if (!r.ok) { const e = await r.json().catch(() => ({})); throw new Error(e.detail || 'Error al iniciar sesión'); }
      const me = await fetch('/api/auth/me', { cache: 'no-store', credentials: 'include' });
      const user = await me.json();
      onAuth(user);
    } catch (e) {
      setMsg({ text: e.message, ok: false });
      setNeedsVerify(/verific/i.test(e.message || ''));
    } finally { setBusy(false); }
  }

  async function resendVerification() {
    if (!email) { setMsg({ text: 'Introduce tu email primero', ok: false }); return; }
    setBusy(true);
    try {
      await fetch('/api/auth/resend-verification', {
        method: 'POST', credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email: email.trim().toLowerCase() }),
      });
      setMsg({ text: 'Si tu cuenta existe y no está verificada, te hemos reenviado el email.', ok: true });
      setNeedsVerify(false);
    } catch { setMsg({ text: 'Error de red. Inténtalo de nuevo.', ok: false }); }
    finally { setBusy(false); }
  }

  return (
    <div style={S.gap16}>
      {appendMsg && <div style={S.msg(appendMsg.ok)}>{appendMsg.text}</div>}
      <Msg {...(msg || { text: null })} />
      <input style={S.input} type="email" placeholder="Email" autoComplete="email"
        value={email} onChange={e => setEmail(e.target.value)}
        onKeyDown={e => e.key === 'Enter' && submit()} />
      <input style={S.input} type="password" placeholder="Contraseña" autoComplete="current-password"
        value={pw} onChange={e => setPw(e.target.value)}
        onKeyDown={e => e.key === 'Enter' && submit()} />
      <button style={{ ...S.btn, opacity: busy ? 0.5 : 1 }} disabled={busy} onClick={submit}>
        {busy ? 'Entrando…' : 'Entrar'}
      </button>
      {needsVerify && (
        <button style={S.link} disabled={busy} onClick={resendVerification}>Reenviar email de verificación</button>
      )}
      <button style={S.link} onClick={() => switchTo('forgot')}>Olvidé mi contraseña</button>
    </div>
  );
}

// ── Forgot password panel ─────────────────────────────────────────────────────
function ForgotPanel({ switchTo }) {
  const [email, setEmail] = useState('');
  const [busy, setBusy] = useState(false);
  const [msg, setMsg] = useState(null);

  async function submit() {
    if (!email) { setMsg({ text: 'Introduce tu email', ok: false }); return; }
    setBusy(true);
    try {
      const r = await fetch('/api/auth/request-reset', {
        method: 'POST', credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email: email.trim().toLowerCase() }),
      });
      if (r.ok) setMsg({ text: 'Si el email existe, recibirás un enlace en unos minutos.', ok: true });
      else { const e = await r.json().catch(() => ({})); setMsg({ text: e.detail || 'Error al enviar.', ok: false }); }
    } catch { setMsg({ text: 'Error de red. Inténtalo de nuevo.', ok: false }); }
    finally { setBusy(false); }
  }

  return (
    <div style={S.gap16}>
      <Msg {...(msg || { text: null })} />
      <input style={S.input} type="email" placeholder="Tu email" autoComplete="email"
        value={email} onChange={e => setEmail(e.target.value)}
        onKeyDown={e => e.key === 'Enter' && submit()} />
      <button style={{ ...S.btn, opacity: busy ? 0.5 : 1 }} disabled={busy} onClick={submit}>
        {busy ? 'Enviando…' : 'Enviar enlace'}
      </button>
      <button style={S.ghost} onClick={() => switchTo('login')}>Volver</button>
    </div>
  );
}

// ── Reset password panel ──────────────────────────────────────────────────────
function ResetPanel({ resetToken, switchTo }) {
  const [pw, setPw] = useState('');
  const [pw2, setPw2] = useState('');
  const [busy, setBusy] = useState(false);
  const [msg, setMsg] = useState(null);

  async function submit() {
    if (pw.length < 8) { setMsg({ text: 'La contraseña debe tener al menos 8 caracteres.', ok: false }); return; }
    if (pw !== pw2) { setMsg({ text: 'Las contraseñas no coinciden.', ok: false }); return; }
    setBusy(true);
    try {
      const r = await fetch('/api/auth/reset', {
        method: 'POST', credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ token: resetToken, password: pw }),
      });
      if (!r.ok) { const e = await r.json().catch(() => ({})); throw new Error(e.detail || 'Token inválido o caducado'); }
      setMsg({ text: 'Contraseña actualizada. Ya puedes iniciar sesión.', ok: true });
      history.replaceState({}, '', '/');
      setTimeout(() => switchTo('login'), 1800);
    } catch (e) { setMsg({ text: e.message, ok: false }); }
    finally { setBusy(false); }
  }

  return (
    <div style={S.gap16}>
      <Msg {...(msg || { text: null })} />
      <input style={S.input} type="password" placeholder="Nueva contraseña (mín. 8 caracteres)"
        autoComplete="new-password" value={pw} onChange={e => setPw(e.target.value)}
        onKeyDown={e => e.key === 'Enter' && submit()} />
      <input style={S.input} type="password" placeholder="Repetir contraseña"
        autoComplete="new-password" value={pw2} onChange={e => setPw2(e.target.value)}
        onKeyDown={e => e.key === 'Enter' && submit()} />
      <button style={{ ...S.btn, opacity: busy ? 0.5 : 1 }} disabled={busy} onClick={submit}>
        {busy ? 'Guardando…' : 'Guardar contraseña'}
      </button>
    </div>
  );
}

// ── Invite redemption panel ───────────────────────────────────────────────────
function InvitePanel({ inviteCode, switchTo }) {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [pw, setPw] = useState('');
  const [privacy, setPrivacy] = useState(false);
  const [busy, setBusy] = useState(false);
  const [msg, setMsg] = useState(null);

  async function submit() {
    if (!email || !pw) { setMsg({ text: 'Rellena email y contraseña', ok: false }); return; }
    if (!privacy) { setMsg({ text: 'Debes aceptar la política de privacidad', ok: false }); return; }
    setBusy(true);
    try {
      const r = await fetch('/api/auth/redeem-invite', {
        method: 'POST', credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ code: inviteCode, email: email.trim().toLowerCase(), password: pw, name, accepted_privacy: true }),
      });
      const data = await r.json().catch(() => ({}));
      if (!r.ok) throw new Error(data.detail || 'Error al crear la cuenta');
      setMsg({ text: 'Cuenta creada. Revisa tu email para verificarla antes de iniciar sesión.', ok: true });
      history.replaceState({}, '', '/');
      setTimeout(() => switchTo('login'), 2200);
    } catch (e) { setMsg({ text: e.message, ok: false }); }
    finally { setBusy(false); }
  }

  return (
    <div style={S.gap16}>
      <Msg {...(msg || { text: null })} />
      <input style={S.input} type="text" placeholder="Tu nombre (opcional)"
        value={name} onChange={e => setName(e.target.value)} />
      <input style={S.input} type="email" placeholder="Email" autoComplete="email"
        value={email} onChange={e => setEmail(e.target.value)} />
      <input style={S.input} type="password" placeholder="Contraseña (mín. 8 caracteres)"
        autoComplete="new-password" value={pw} onChange={e => setPw(e.target.value)}
        onKeyDown={e => e.key === 'Enter' && submit()} />
      <label style={S.privacyRow}>
        <input type="checkbox" checked={privacy} onChange={e => setPrivacy(e.target.checked)}
          style={{ marginTop: 2, accentColor: 'var(--mint)', flexShrink: 0 }} />
        <span>Acepto la <a href="/privacidad" target="_blank" style={{ color: 'var(--mint)' }}>política de privacidad</a></span>
      </label>
      <button style={{ ...S.btn, opacity: busy ? 0.5 : 1 }} disabled={busy} onClick={submit}>
        {busy ? 'Creando cuenta…' : 'Crear cuenta'}
      </button>
    </div>
  );
}

// ── Auth screen ───────────────────────────────────────────────────────────────
const TITLES = {
  login: 'Iniciar sesión',
  forgot: 'Recuperar contraseña',
  reset: 'Nueva contraseña',
  invite: 'Crear cuenta',
};

function AuthScreen({ onAuth, initialPanel, resetToken, inviteCode }) {
  const [panel, setPanel] = useState(initialPanel || 'login');
  const [verifyMsg, setVerifyMsg] = useState(null);

  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const ver = params.get('verify_token');
    if (ver) {
      setVerifyMsg({ text: 'Verificando email…', ok: true });
      fetch(`/api/auth/verify-email?token=${encodeURIComponent(ver)}`, { credentials: 'include' })
        .then(r => r.json())
        .then(d => {
          setVerifyMsg({ text: d.message || 'Email verificado. Ya puedes iniciar sesión.', ok: true });
          history.replaceState({}, '', '/');
          setTimeout(() => setVerifyMsg(null), 3000);
        })
        .catch(() => setVerifyMsg({ text: 'Error al verificar. El enlace puede haber caducado.', ok: false }));
    }
  }, []);

  return (
    <div style={S.screen}>
      <div style={S.card}>
        <div style={S.wordmark}>Ruticomidas</div>
        <div style={S.title}>{TITLES[panel] || ''}</div>
        {panel === 'login'  && <LoginPanel onAuth={onAuth} switchTo={setPanel} appendMsg={verifyMsg} />}
        {panel === 'forgot' && <ForgotPanel switchTo={setPanel} />}
        {panel === 'reset'  && <ResetPanel resetToken={resetToken} switchTo={setPanel} />}
        {panel === 'invite' && <InvitePanel inviteCode={inviteCode} switchTo={setPanel} />}
      </div>
    </div>
  );
}

// ── Loading screen ─────────────────────────────────────────────────────────────
function LoadingScreen() {
  return (
    <div style={{ ...S.screen, flexDirection: 'column', gap: 16 }}>
      <div style={{ fontFamily: 'var(--f-mono)', color: 'var(--mint)', fontSize: 20 }}>Ruticomidas</div>
      <div style={{ color: 'var(--text-meta)', fontSize: 13 }}>Cargando…</div>
    </div>
  );
}

// ── AuthGate ──────────────────────────────────────────────────────────────────
function AuthGate({ children }) {
  const [user, setUser] = useState(undefined); // undefined=loading, null=unauthed, obj=authed
  const [initialPanel, setInitialPanel] = useState('login');
  const [resetToken, setResetToken] = useState(null);
  const [inviteCode, setInviteCode] = useState(null);

  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const inv = params.get('invite');
    const rst = params.get('reset_token');
    const ver = params.get('verify_token');

    if (inv) { setInviteCode(inv); setInitialPanel('invite'); setUser(null); return; }
    if (rst) { setResetToken(rst); setInitialPanel('reset'); setUser(null); return; }
    if (ver) { setInitialPanel('login'); }

    fetch('/api/auth/me', { cache: 'no-store', credentials: 'include' })
      .then(r => r.ok ? r.json() : null)
      .then(u => { if (u) { window.RC_Auth.currentUser = u; setUser(u); } else setUser(null); })
      .catch(() => setUser(null));
  }, []);

  function handleAuth(u) {
    window.RC_Auth.currentUser = u;
    setUser(u);
  }

  function logout() {
    fetch('/api/auth/logout', { method: 'POST', credentials: 'include' }).catch(() => {});
    window.RC_Auth.currentUser = null;
    setUser(null);
  }

  if (user === undefined) return <LoadingScreen />;
  if (user === null) return (
    <AuthScreen onAuth={handleAuth} initialPanel={initialPanel}
      resetToken={resetToken} inviteCode={inviteCode} />
  );

  return (
    <_AuthCtx.Provider value={{ user, logout }}>
      {children}
    </_AuthCtx.Provider>
  );
}

function useAuth() { return useContext(_AuthCtx); }

window.RC_Auth = { currentUser: null, AuthGate, useAuth };

// Reload on 401 from api.jsx wrapper
window.RC_API.setOn401(() => {
  window.RC_Auth.currentUser = null;
  window.location.reload();
});
