import { createContext, useContext, useEffect, useState, useCallback, type ReactNode } from 'react'
import { api } from './api'
import type { User } from './types'

export type AuthStatus = 'loading' | 'setup' | 'unauthenticated' | 'authenticated'

interface AuthContextValue {
  status: AuthStatus
  user: User | null
  setupNeeded: boolean
  refresh: () => Promise<void>
  onSetupComplete: (user: User) => void
  onLogin: (user: User) => void
  onLogout: () => void
}

const AuthContext = createContext<AuthContextValue | null>(null)

export function AuthProvider({ children }: { children: ReactNode }) {
  const [status, setStatus] = useState<AuthStatus>('loading')
  const [user, setUser] = useState<User | null>(null)
  const [setupNeeded, setSetupNeeded] = useState(false)

  const refresh = useCallback(async () => {
    try {
      const { needed } = await api.setupStatus()
      if (needed) {
        setSetupNeeded(true)
        setStatus('setup')
        return
      }
      setSetupNeeded(false)
      const { user: me } = await api.me()
      setUser(me)
      setStatus('authenticated')
    } catch {
      setStatus('unauthenticated')
    }
  }, [])

  useEffect(() => {
    void refresh()
  }, [refresh])

  const onSetupComplete = useCallback((u: User) => {
    setSetupNeeded(false)
    setUser(u)
    setStatus('authenticated')
  }, [])
  const onLogin = useCallback((u: User) => {
    setUser(u)
    setStatus('authenticated')
  }, [])
  const onLogout = useCallback(() => {
    setUser(null)
    setStatus('unauthenticated')
  }, [])

  return (
    <AuthContext.Provider value={{ status, user, setupNeeded, refresh, onSetupComplete, onLogin, onLogout }}>
      {children}
    </AuthContext.Provider>
  )
}

export function useAuth(): AuthContextValue {
  const ctx = useContext(AuthContext)
  if (!ctx) throw new Error('useAuth outside AuthProvider')
  return ctx
}
