import {useLocalSearchParams, useRouter} from 'expo-router'
import {useEffect, useRef} from 'react'
import {ActivityIndicator} from 'react-native'

import {Layout} from '@/components/ui/layout'
import {rpc} from '@/lib/rpc'
import {useAuth} from '@/stores/auth'

type Params = {code?: string; error?: string}

export default function AuthCallback() {
  const params = useLocalSearchParams<Params>()
  const router = useRouter()
  const user = useAuth((s) => s.user)
  const setSession = useAuth((s) => s.setSession)
  // the exchange code is single use — never run the effect twice
  const handled = useRef(false)

  useEffect(() => {
    if (user === undefined || handled.current) return
    handled.current = true
    if (user) {
      // already signed in — ignore the link to prevent session fixation
      router.replace('/')
      return
    }
    const code = params.code
    if (params.error || !code) {
      router.replace('/sign-in')
      return
    }
    void (async () => {
      const res = await rpc.auth.exchange.$post({json: {code}})
      if (!res.ok) {
        router.replace('/sign-in')
        return
      }
      const {token} = await res.json()
      const ok = await setSession(token)
      router.replace(ok ? '/' : '/sign-in')
    })()
  }, [user, params.code, params.error, setSession, router])

  return (
    <Layout.Screen>
      <Layout.Center>
        <ActivityIndicator />
      </Layout.Center>
    </Layout.Screen>
  )
}
