import { useMemo, useState } from 'react'
import type { PropsWithChildren } from 'react'
import { clearAuthSession, getAuthSession, isAccessTokenStale, setAuthSession } from '../lib/auth-storage'
import type { AuthSession } from '../lib/auth-storage'
import { loginCenter, logoutCenter, refreshCenter } from '../lib/center-auth-client'
import { AuthContext } from './auth-context'
import type { AuthContextValue } from './auth-context'

export function AuthProvider({ children }: PropsWithChildren) {
  const [session, setSession] = useState<AuthSession | null>(getAuthSession())

  const value = useMemo<AuthContextValue>(
    () => ({
      session,
      isAuthed: !!session,
      login: async (email: string, password: string) => {
        const next = await loginCenter({ email, password })
        setAuthSession(next)
        setSession(next)
      },
      logout: async () => {
        if (session?.refreshToken) {
          try {
            await logoutCenter(session.refreshToken)
          } catch {
            // noop
          }
        }
        clearAuthSession()
        setSession(null)
      },
      ensureFreshToken: async () => {
        if (!session) return null
        if (!isAccessTokenStale(session.accessToken)) return session.accessToken

        const refreshed = await refreshCenter(session.refreshToken)
        const next: AuthSession = {
          ...session,
          accessToken: refreshed.accessToken,
          refreshToken: refreshed.refreshToken,
          tokenType: refreshed.tokenType,
        }
        setAuthSession(next)
        setSession(next)
        return next.accessToken
      },
    }),
    [session],
  )

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>
}
