import { useCallback, useEffect, useState } from 'react'
import App from './App'
import { api, setUnauthorizedHandler } from './api'
import { Login } from './Login'
import type { Me } from './types'

/**
 * AuthGate decides, on load and after every 401, whether to show the setup
 * screen, a login form, or the app itself. It owns the one GET /api/me call
 * the app needs before it can render anything real.
 */
export function AuthGate() {
  const [me, setMe] = useState<Me | null>(null)
  const [error, setError] = useState('')

  const load = useCallback(async () => {
    try {
      setMe(await api.me())
      setError('')
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e))
    }
  }, [])

  useEffect(() => {
    load()
  }, [load])

  // A 401 elsewhere in the app (an expired or revoked session) means the
  // server no longer considers us logged in; drop straight to the login form
  // instead of waiting for the next unrelated re-render to notice.
  useEffect(() => {
    setUnauthorizedHandler(() => setMe((prev) => (prev ? { ...prev, authenticated: false } : prev)))
    return () => setUnauthorizedHandler(null)
  }, [])

  const logout = useCallback(async () => {
    await api.logout().catch(() => undefined)
    await load()
  }, [load])

  if (!me) {
    return <div className="empty">{error || 'loading…'}</div>
  }
  if (!me.authenticated) {
    return <Login needsSetup={!!me.needsSetup} onDone={load} />
  }
  return <App me={me} logout={logout} />
}
