// ============================================================================
// lib-auth.jsx — AuthScreen + AuthGate component
// ============================================================================
// AuthScreen: the login UI. Three providers (Google, GitHub, email magic link).
// AuthGate: wraps the app — shows AuthScreen if no session, else children.
//
// Both are exposed on window so index.html can wrap App with <AuthGate>.
// ============================================================================

const { useState, useEffect } = React;

// ────────────────────────────────────────────────────────────────────────────
// AUTH SCREEN
// ────────────────────────────────────────────────────────────────────────────

function AuthScreen() {
  const [email, setEmail] = useState('');
  const [sending, setSending] = useState(false);
  const [sentTo, setSentTo] = useState(null);   // email we sent magic link to
  const [error, setError] = useState(null);

  const sendMagicLink = async () => {
    const trimmed = email.trim();
    if (!trimmed || !trimmed.includes('@')) {
      setError("That doesn't look like an email.");
      return;
    }
    setError(null);
    setSending(true);
    try {
      const { error: e } = await window.sbAuth.signInWithEmail(trimmed);
      if (e) throw e;
      setSentTo(trimmed);
    } catch (e) {
      setError(e.message || String(e));
    } finally {
      setSending(false);
    }
  };

  const oauthSignIn = async (provider) => {
    setError(null);
    try {
      const { error: e } = await window.sbAuth.signInWithProvider(provider);
      if (e) throw e;
      // Browser will redirect away to the provider — nothing more to do here
    } catch (e) {
      setError(e.message || String(e));
    }
  };

  return (
    <div style={{
      position: 'fixed', inset: 0,
      background: 'radial-gradient(ellipse at center, #0a0a0a 0%, #000 70%)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      zIndex: 9000, padding: 24, overflowY: 'auto',
    }}>
      <div style={{
        width: 'min(440px, 100%)',
        background: '#070707',
        border: '1px solid #1a1a1a',
        borderRadius: 14,
        padding: '36px 32px',
        boxShadow: '0 30px 80px rgba(0,0,0,0.7)',
        display: 'flex', flexDirection: 'column', gap: 18,
      }}>
        {/* Branding */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 8 }}>
          <div style={{
            width: 38, height: 38, borderRadius: 9,
            background: 'var(--accent, #3B82F6)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontWeight: 800, fontSize: 17, color: '#fff', letterSpacing: -1,
            boxShadow: '0 0 18px rgba(59,130,246,0.35)',
          }}>L</div>
          <div>
            <div style={{ fontSize: 18, fontWeight: 700, color: '#e8e8e8', letterSpacing: -0.4 }}>
              Laminar Flow
            </div>
            <div style={{ fontSize: 11, color: '#555', letterSpacing: '0.1em', textTransform: 'uppercase', fontWeight: 600 }}>
              External cortex
            </div>
          </div>
        </div>

        {sentTo ? (
          // ─── Magic-link-sent confirmation ───
          <div style={{
            padding: '18px 16px',
            background: 'rgba(34,197,94,0.06)',
            border: '1px solid rgba(34,197,94,0.25)',
            borderRadius: 10,
            display: 'flex', flexDirection: 'column', gap: 8,
          }}>
            <div style={{ fontSize: 14, fontWeight: 700, color: '#22C55E' }}>
              ✓ Check your email
            </div>
            <div style={{ fontSize: 13, color: '#aaa', lineHeight: 1.55 }}>
              We sent a magic link to <span style={{ color: '#e8e8e8', fontWeight: 600 }}>{sentTo}</span>.
              Click it to sign in. Link expires in an hour.
            </div>
            <button onClick={() => { setSentTo(null); setEmail(''); }}
              style={{ background: 'transparent', border: 'none', color: '#666', fontSize: 11, fontFamily: 'inherit', cursor: 'pointer', textAlign: 'left', padding: 0, marginTop: 4 }}>
              ← Use a different email
            </button>
          </div>
        ) : (
          <>
            {/* OAuth buttons — primary path for most users */}
            <button onClick={() => oauthSignIn('google')}
              style={{
                background: '#fff', color: '#111', border: 'none',
                borderRadius: 9, padding: '12px 14px',
                fontSize: 14, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit',
                display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
                transition: 'transform 0.1s',
              }}
              onMouseDown={(e) => { e.currentTarget.style.transform = 'scale(0.98)'; }}
              onMouseUp={(e) => { e.currentTarget.style.transform = 'scale(1)'; }}
              onMouseLeave={(e) => { e.currentTarget.style.transform = 'scale(1)'; }}>
              <svg width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
                <path d="M17.64 9.205c0-.639-.057-1.252-.164-1.841H9v3.481h4.844a4.14 4.14 0 01-1.796 2.716v2.259h2.908c1.702-1.567 2.684-3.875 2.684-6.615z" fill="#4285F4"/>
                <path d="M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 009 18z" fill="#34A853"/>
                <path d="M3.964 10.71A5.41 5.41 0 013.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 000 9c0 1.452.348 2.827.957 4.042l3.007-2.332z" fill="#FBBC05"/>
                <path d="M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 00.957 4.958L3.964 7.29C4.672 5.163 6.656 3.58 9 3.58z" fill="#EA4335"/>
              </svg>
              Continue with Google
            </button>

            <button onClick={() => oauthSignIn('github')}
              style={{
                background: '#181818', color: '#fff', border: '1px solid #2a2a2a',
                borderRadius: 9, padding: '12px 14px',
                fontSize: 14, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit',
                display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
                transition: 'transform 0.1s',
              }}
              onMouseDown={(e) => { e.currentTarget.style.transform = 'scale(0.98)'; }}
              onMouseUp={(e) => { e.currentTarget.style.transform = 'scale(1)'; }}
              onMouseLeave={(e) => { e.currentTarget.style.transform = 'scale(1)'; }}>
              <svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor">
                <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/>
              </svg>
              Continue with GitHub
            </button>

            {/* Divider */}
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, margin: '4px 0' }}>
              <div style={{ flex: 1, height: 1, background: '#1a1a1a' }} />
              <span style={{ fontSize: 10, color: '#444', letterSpacing: '0.1em', textTransform: 'uppercase', fontWeight: 700 }}>or</span>
              <div style={{ flex: 1, height: 1, background: '#1a1a1a' }} />
            </div>

            {/* Magic link */}
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              <input
                type="email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                onKeyDown={(e) => { if (e.key === 'Enter') sendMagicLink(); }}
                placeholder="you@email.com"
                autoComplete="email"
                disabled={sending}
                style={{
                  background: '#0a0a0a', border: '1px solid #1c1c1c',
                  borderRadius: 8, padding: '11px 14px',
                  color: '#e8e8e8', fontFamily: 'inherit', fontSize: 14,
                  outline: 'none', boxSizing: 'border-box',
                }}
              />
              <button onClick={sendMagicLink} disabled={sending || !email.trim()}
                style={{
                  background: 'var(--accent, #3B82F6)', color: '#fff', border: 'none',
                  borderRadius: 8, padding: '11px 14px',
                  fontSize: 13, fontWeight: 700, cursor: sending ? 'default' : 'pointer',
                  fontFamily: 'inherit', opacity: (sending || !email.trim()) ? 0.5 : 1,
                }}>
                {sending ? 'Sending…' : 'Email me a magic link'}
              </button>
            </div>
          </>
        )}

        {error && (
          <div style={{
            padding: '10px 12px',
            background: 'rgba(239,68,68,0.08)',
            border: '1px solid rgba(239,68,68,0.25)',
            borderRadius: 8,
            fontSize: 12, color: '#EF4444', lineHeight: 1.5,
          }}>
            {error}
          </div>
        )}

        {/* Footer */}
        <div style={{ fontSize: 10, color: '#3a3a3a', textAlign: 'center', marginTop: 4, lineHeight: 1.6 }}>
          By signing in you agree to the <a href="https://laminarflow.tech/terms" target="_blank" style={{ color: '#666' }}>Terms</a> and <a href="https://laminarflow.tech/privacy" target="_blank" style={{ color: '#666' }}>Privacy Policy</a>.
        </div>
      </div>
    </div>
  );
}
window.AuthScreen = AuthScreen;

// ────────────────────────────────────────────────────────────────────────────
// AUTH GATE
// Wraps children. Renders AuthScreen if no session, else children.
// Also handles session-loaded → app-hydration handoff (sets a flag the rest
// of the app reads to know "data is ready").
// ────────────────────────────────────────────────────────────────────────────

function AuthGate({ children }) {
  // null = loading, false = no session, object = signed-in session
  const [session, setSession] = useState(null);
  const [hydrated, setHydrated] = useState(false);

  useEffect(() => {
    // 1. Read existing session from storage
    window.sbAuth.getSession().then((s) => {
      setSession(s || false);
    });

    // 2. Subscribe to auth changes (login/logout in another tab, token refresh)
    const unsub = window.sbAuth.onAuthChange((event, newSession) => {
      setSession(newSession || false);
      // On fresh sign-in, force re-hydration of the LF state
      if (event === 'SIGNED_IN' && window.LFHydrate) {
        setHydrated(false);
        window.LFHydrate(newSession.user).then(() => setHydrated(true));
      }
      if (event === 'SIGNED_OUT') {
        setHydrated(false);
      }
    });
    return unsub;
  }, []);

  // Hydrate on initial mount once we have a session.
  // Wait up to 5s for window.LFHydrate to be installed by lib-sync.js (it
  // self-installs once window.LF + window.sb are both ready). Skipping
  // hydration when LFHydrate is briefly undefined was bypassing the
  // seed-from-local step on first sign-in — left Supabase empty.
  useEffect(() => {
    if (!session) return;
    let cancelled = false;
    const start = Date.now();
    const waitForHydrate = async () => {
      while (!window.LFHydrate && Date.now() - start < 5000) {
        await new Promise((r) => setTimeout(r, 30));
      }
      if (cancelled) return;
      if (!window.LFHydrate) {
        console.warn('[auth] LFHydrate never appeared — rendering without hydration');
        setHydrated(true);
        return;
      }
      try {
        await window.LFHydrate(session.user);
      } catch (e) {
        console.error('[auth] LFHydrate failed', e);
      }
      if (!cancelled) setHydrated(true);
    };
    waitForHydrate();
    return () => { cancelled = true; };
  }, [session?.user?.id]);

  // Loading state — brief, just a black screen while we check the session
  if (session === null) {
    return (
      <div style={{
        position: 'fixed', inset: 0, background: '#000',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        zIndex: 9000,
      }}>
        <div style={{
          width: 6, height: 6, borderRadius: '50%',
          background: '#3B82F6', boxShadow: '0 0 12px #3B82F6',
          animation: 'pulse 1.4s ease-in-out infinite',
        }} />
      </div>
    );
  }

  // No session → login
  if (!session) {
    return <AuthScreen />;
  }

  // Signed in but not hydrated yet — keep the dot
  if (!hydrated) {
    return (
      <div style={{
        position: 'fixed', inset: 0, background: '#000',
        display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
        zIndex: 9000, gap: 14,
      }}>
        <div style={{
          width: 6, height: 6, borderRadius: '50%',
          background: '#22C55E', boxShadow: '0 0 12px #22C55E',
          animation: 'pulse 1.4s ease-in-out infinite',
        }} />
        <div style={{ fontSize: 10, color: '#444', letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 700 }}>
          Loading your workspace…
        </div>
      </div>
    );
  }

  // Signed in + hydrated → show the app
  return children;
}
window.AuthGate = AuthGate;
