// ============================================================
// Supabase auth — sign in / sign up controls and modal
// ============================================================
//
// PASTE YOUR SUPABASE PROJECT URL + ANON KEY BELOW.
// Both come from Supabase Dashboard → Project Settings → API.
//
// The anon key is *designed to be public* — it's safe to commit
// to a public repo and ship in client-side JS. Row Level Security
// (which we enable on the profiles table) is what actually
// protects user data from being read across accounts.
// ============================================================

const SUPABASE_URL      = 'https://xlbfyphfuhepteszepyt.supabase.co';
const SUPABASE_ANON_KEY = 'sb_publishable_KZcpyaTxOy6gDoyzWXZyuQ_joVOuVlQ';

// Skip init if the dev hasn't pasted real values yet — keeps the
// page from white-screening with a confusing error.
const SUPABASE_CONFIGURED =
  SUPABASE_URL.startsWith('http') &&
  SUPABASE_ANON_KEY.length > 30 &&
  !SUPABASE_URL.includes('YOUR_') &&
  !SUPABASE_ANON_KEY.includes('YOUR_');

const supabaseClient = SUPABASE_CONFIGURED
  ? window.supabase.createClient(SUPABASE_URL, SUPABASE_ANON_KEY)
  : null;
window.supabaseClient = supabaseClient;
window.JUMP_AUTH_READY = SUPABASE_CONFIGURED;

// ============================================================
// useAuth — single hook that subscribes to auth state changes
// ============================================================
const { useState: useAuthState, useEffect: useAuthEffect, useRef: useAuthRef } = React;

function useAuth() {
  const [user, setUser]       = useAuthState(null);
  const [loading, setLoading] = useAuthState(true);

  useAuthEffect(() => {
    if (!supabaseClient) { setLoading(false); return; }
    let mounted = true;

    supabaseClient.auth.getSession().then(({ data }) => {
      if (!mounted) return;
      setUser(data?.session?.user ?? null);
      setLoading(false);
    });

    const { data: sub } = supabaseClient.auth.onAuthStateChange((_event, session) => {
      if (!mounted) return;
      setUser(session?.user ?? null);
      setLoading(false);
    });

    return () => {
      mounted = false;
      sub?.subscription?.unsubscribe?.();
    };
  }, []);

  const signOut = async () => {
    if (!supabaseClient) return;
    await supabaseClient.auth.signOut();
    // onAuthStateChange will fire and clear user
  };

  return { user, loading, signOut };
}

// ============================================================
// AuthControls — the header bit (Sign in button | avatar menu)
// ============================================================
function AuthControls() {
  const { user, loading, signOut } = useAuth();
  const [open, setOpen]       = useAuthState(false); // dropdown
  const [modalOpen, setModal] = useAuthState(false); // modal
  const menuRef = useAuthRef(null);

  // Close dropdown on outside click
  useAuthEffect(() => {
    if (!open) return;
    const onDocClick = (e) => {
      if (menuRef.current && !menuRef.current.contains(e.target)) setOpen(false);
    };
    document.addEventListener('mousedown', onDocClick);
    return () => document.removeEventListener('mousedown', onDocClick);
  }, [open]);

  // Bridge so other components (e.g. SignupPromptModal in
  // image-converter.jsx) can open the auth modal without a state hoist.
  useAuthEffect(() => {
    window.__jumpOpenAuth = () => setModal(true);
    return () => { if (window.__jumpOpenAuth) delete window.__jumpOpenAuth; };
  }, []);

  if (!SUPABASE_CONFIGURED) {
    // Surface a quiet hint to the developer rather than crashing
    return (
      <button
        className="btn"
        title="Add SUPABASE_URL and SUPABASE_ANON_KEY in auth.jsx"
        disabled
        style={{opacity:0.55, cursor:'not-allowed'}}
      >
        <IconUser /> Sign in
      </button>
    );
  }

  if (loading) {
    return <div className="auth-skeleton" aria-hidden />;
  }

  if (!user) {
    return (
      <>
        <button className="btn" onClick={() => setModal(true)}>
          <IconUser /> Sign in
        </button>
        {modalOpen && <AuthModal onClose={() => setModal(false)} />}
      </>
    );
  }

  // Signed in — avatar + dropdown
  const initials = (user.email || '?').slice(0, 2).toUpperCase();
  return (
    <div className="user-menu-wrap" ref={menuRef}>
      <button className="user-trigger" onClick={() => setOpen(o => !o)} title={user.email}>
        <span className="avatar avatar-sm">{initials}</span>
        <span className="email-pill">{user.email}</span>
      </button>
      {open && (
        <div className="user-menu menu">
          <div className="user-menu-header">
            <div className="user-menu-email">{user.email}</div>
            <div className="user-menu-sub">Signed in</div>
          </div>
          <div className="user-menu-divider" />
          <button className="menu-item" onClick={() => { setOpen(false); signOut(); }}>
            <IconLogout /> Sign out
          </button>
        </div>
      )}
    </div>
  );
}

// ============================================================
// AuthModal — magic link primary, password fallback
// ============================================================
function AuthModal({ onClose }) {
  const [mode, setMode]       = useAuthState('magic');   // 'magic' | 'password'
  const [pwIntent, setIntent] = useAuthState('signin');  // 'signin' | 'signup'
  const [email, setEmail]     = useAuthState('');
  const [password, setPwd]    = useAuthState('');
  const [fullName, setFullName] = useAuthState('');     // Name or organisation
  const [busy, setBusy]       = useAuthState(false);
  const [err, setErr]         = useAuthState('');
  const [sentTo, setSentTo]   = useAuthState(null);     // email address we sent link / confirmation to

  // Whether the current sub-form will create a new user. The name field
  // is only relevant on a creation path; existing-user sign-in skips it.
  const isSignUpPath = mode === 'magic' || (mode === 'password' && pwIntent === 'signup');

  const signInWithGoogle = async () => {
    setErr('');
    setBusy(true);
    try {
      const { error } = await supabaseClient.auth.signInWithOAuth({
        provider: 'google',
        options: { redirectTo: window.location.origin },
      });
      if (error) throw error;
      // Browser redirects to Google immediately; nothing more to do here.
    } catch (e2) {
      setErr(e2.message || String(e2));
      setBusy(false);
    }
  };

  const submit = async (e) => {
    e?.preventDefault();
    setErr('');
    if (!email) { setErr('Enter your email'); return; }
    if (isSignUpPath && !fullName.trim()) { setErr('Enter a name or organisation'); return; }
    setBusy(true);
    try {
      // user_metadata payload — picked up by the public.handle_new_user
      // trigger which writes it to profiles.full_name. Same field name
      // as Google OAuth (Supabase normalises Google's name into the
      // user_metadata bag) so one trigger handles both flows.
      const userMeta = isSignUpPath ? { full_name: fullName.trim() } : undefined;

      if (mode === 'magic') {
        const { error } = await supabaseClient.auth.signInWithOtp({
          email,
          options: {
            data: userMeta,
            emailRedirectTo: window.location.origin,
          },
        });
        if (error) throw error;
        setSentTo(email);
      } else if (pwIntent === 'signin') {
        const { error } = await supabaseClient.auth.signInWithPassword({ email, password });
        if (error) throw error;
        onClose();
      } else {
        const { data, error } = await supabaseClient.auth.signUp({
          email, password,
          options: {
            data: userMeta,
            emailRedirectTo: window.location.origin,
          },
        });
        if (error) throw error;
        if (!data.session) setSentTo(email);
        else onClose();
      }
    } catch (e2) {
      setErr(e2.message || String(e2));
    } finally {
      setBusy(false);
    }
  };

  // "Check your inbox" confirmation screen
  if (sentTo) {
    return ReactDOM.createPortal(
      <div className="modal-backdrop" onClick={onClose}>
        <div className="modal" onClick={(e) => e.stopPropagation()} style={{maxWidth: 440}}>
          <h2>Check your inbox</h2>
          <p className="modal-sub">
            We sent a {mode === 'magic' ? 'sign-in link' : 'confirmation link'} to{' '}
            <strong style={{color:'var(--text)'}}>{sentTo}</strong>. Click the link in the email
            to {mode === 'magic' ? 'sign in' : 'finish creating your account'}.
          </p>
          <div className="modal-actions">
            <button className="btn" onClick={onClose}>Close</button>
            <button className="btn btn-ghost" onClick={() => { setSentTo(null); }}>
              Use a different email
            </button>
          </div>
        </div>
      </div>,
      document.body
    );
  }

  return ReactDOM.createPortal(
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()} style={{maxWidth: 440}}>
        <h2>Sign in</h2>
        <p className="modal-sub">
          We'll send you a one-tap magic link, or use a password if you prefer.
        </p>

        <button type="button" className="btn-google" onClick={signInWithGoogle} disabled={busy}>
          <GoogleLogo /> Continue with Google
        </button>

        <div className="auth-or"><span>or</span></div>

        <div className="auth-tabs">
          <div className="seg">
            <button
              type="button"
              className={mode === 'magic' ? 'active' : ''}
              onClick={() => { setMode('magic'); setErr(''); }}
            >
              Magic link
            </button>
            <button
              type="button"
              className={mode === 'password' ? 'active' : ''}
              onClick={() => { setMode('password'); setErr(''); }}
            >
              Password
            </button>
          </div>
        </div>

        <form onSubmit={submit}>
          {isSignUpPath && (
            <div className="field">
              <label>Name or organisation</label>
              <input
                type="text"
                autoComplete="name"
                value={fullName}
                onChange={(e) => setFullName(e.target.value)}
                placeholder="e.g. Jane Doe or Acme Studio"
                required
                autoFocus
              />
            </div>
          )}
          <div className="field">
            <label>Email</label>
            <input
              type="email"
              autoComplete="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              placeholder="you@example.com"
              required
              autoFocus={!isSignUpPath}
            />
          </div>

          {mode === 'password' && (
            <>
              <div className="field">
                <label>Password</label>
                <input
                  type="password"
                  autoComplete={pwIntent === 'signup' ? 'new-password' : 'current-password'}
                  value={password}
                  onChange={(e) => setPwd(e.target.value)}
                  placeholder={pwIntent === 'signup' ? 'At least 6 characters' : ''}
                  minLength={6}
                  required
                />
              </div>
              <div className="auth-pw-switch">
                {pwIntent === 'signin' ? (
                  <span>
                    New here?{' '}
                    <button type="button" className="link-btn" onClick={() => { setIntent('signup'); setErr(''); }}>
                      Create an account
                    </button>
                  </span>
                ) : (
                  <span>
                    Already have one?{' '}
                    <button type="button" className="link-btn" onClick={() => { setIntent('signin'); setErr(''); }}>
                      Sign in
                    </button>
                  </span>
                )}
              </div>
            </>
          )}

          {err && <div className="error-text">{err}</div>}

          <div className="modal-actions">
            <button type="button" className="btn" onClick={onClose}>Cancel</button>
            <button type="submit" className="btn btn-primary" disabled={busy}>
              {busy
                ? 'Working…'
                : mode === 'magic'
                  ? 'Send magic link'
                  : pwIntent === 'signin' ? 'Sign in' : 'Create account'}
            </button>
          </div>
        </form>
      </div>
    </div>,
    document.body
  );
}

// ============================================================
// SignupPromptModal — fires both as a soft nudge after the first
// export and as a hard gate before a 2nd export attempt. Same
// headline; only the "Maybe later" escape hatch differs.
//   mode='nudge' → "Maybe later" + "Sign up free"
//   mode='block' → only "Sign up free" (sign-up is essential to continue)
// ============================================================
function SignupPromptModal({ isOpen, onClose, onSignUp, mode = 'nudge' }) {
  if (!isOpen) return null;
  const isBlock = mode === 'block';
  return ReactDOM.createPortal(
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()} style={{maxWidth: 460, textAlign: 'center'}}>
        <div className="signup-prompt-art" aria-hidden>
          <span className="dot" />
        </div>
        <h2 style={{marginTop: 14}}>Get unlimited free conversions with a quick sign up!</h2>
        <p className="modal-sub" style={{marginBottom: 22}}>
          Free, takes 10 seconds — magic link to your inbox.
        </p>
        <div className="modal-actions" style={{justifyContent: 'center', borderTop: 'none', marginTop: 0, paddingTop: 0}}>
          {!isBlock && <button className="btn btn-ghost" onClick={onClose}>Maybe later</button>}
          <button className="btn btn-primary" onClick={onSignUp}>
            <IconUser /> Sign up free
          </button>
        </div>
      </div>
    </div>,
    document.body
  );
}

// ============================================================
// Tiny auth-only icons (kept here to avoid touching icons.jsx)
// ============================================================
const _AUTH_ICON_PROPS = {
  viewBox: "0 0 24 24",
  fill: "none",
  stroke: "currentColor",
  strokeWidth: 1.7,
  strokeLinecap: "round",
  strokeLinejoin: "round",
};
const IconUser = (props) => (
  <svg {..._AUTH_ICON_PROPS} {...props}>
    <circle cx="12" cy="8" r="4" />
    <path d="M4 21c0-4.4 3.6-8 8-8s8 3.6 8 8" />
  </svg>
);
const IconLogout = (props) => (
  <svg {..._AUTH_ICON_PROPS} {...props}>
    <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
    <path d="M16 17l5-5-5-5" />
    <path d="M21 12H9" />
  </svg>
);

// Google "G" — official multi-color, used per their brand guidelines
const GoogleLogo = (props) => (
  <svg viewBox="0 0 48 48" width="18" height="18" {...props}>
    <path fill="#FFC107" d="M43.611 20.083H42V20H24v8h11.303c-1.649 4.657-6.08 8-11.303 8-6.627 0-12-5.373-12-12s5.373-12 12-12c3.059 0 5.842 1.154 7.961 3.039l5.657-5.657C34.046 6.053 29.268 4 24 4 12.955 4 4 12.955 4 24s8.955 20 20 20 20-8.955 20-20c0-1.341-.138-2.65-.389-3.917z"/>
    <path fill="#FF3D00" d="M6.306 14.691l6.571 4.819C14.655 15.108 18.961 12 24 12c3.059 0 5.842 1.154 7.961 3.039l5.657-5.657C34.046 6.053 29.268 4 24 4 16.318 4 9.656 8.337 6.306 14.691z"/>
    <path fill="#4CAF50" d="M24 44c5.166 0 9.86-1.977 13.409-5.192l-6.19-5.238C29.211 35.091 26.715 36 24 36c-5.202 0-9.619-3.317-11.283-7.946l-6.522 5.025C9.505 39.556 16.227 44 24 44z"/>
    <path fill="#1976D2" d="M43.611 20.083H42V20H24v8h11.303c-.792 2.237-2.231 4.166-4.087 5.571.001-.001.002-.001.003-.002l6.19 5.238C36.971 39.205 44 34 44 24c0-1.341-.138-2.65-.389-3.917z"/>
  </svg>
);

window.useAuth            = useAuth;
window.AuthControls       = AuthControls;
window.AuthModal          = AuthModal;
window.SignupPromptModal  = SignupPromptModal;
window.IconUser           = IconUser;
window.IconLogout         = IconLogout;
