import { useEffect, useRef, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { getPKCE, clearPKCE, storeToken, getState, clearState } from '../auth/oidc'
import { api } from '../api/client'
import { useAuthStore } from '../stores/auth'

const CLIENT_ID = import.meta.env.VITE_OIDC_CLIENT_ID
const REDIRECT_URI = import.meta.env.VITE_OIDC_REDIRECT_URI

export default function CallbackPage() {
  const navigate = useNavigate()
  const { setUser, setError } = useAuthStore()
  const [status, setStatus] = useState('Processing authentication...')
  const isMounted = useRef(true)

  useEffect(() => {
    return () => {
      isMounted.current = false
    }
  }, [])

  useEffect(() => {
    const handleCallback = async () => {
      try {
        const urlParams = new URLSearchParams(window.location.search)
        const code = urlParams.get('code')
        const error = urlParams.get('error')
        const state = urlParams.get('state')
        const storedState = getState()

        if (error) {
          throw new Error(`Authentication error: ${error}`)
        }

        if (!code) {
          throw new Error('No authorization code received')
        }

        if (!state || state !== storedState) {
          throw new Error('Invalid or missing state parameter')
        }

        const verifier = getPKCE()
        if (!verifier) {
          throw new Error('PKCE verifier not found')
        }

        if (isMounted.current) {
          setStatus('Exchanging code for token...')
        }

        const tokenEndpoint = 'https://auth.commumedia.org/application/o/token/'
        const tokenResponse = await fetch(tokenEndpoint, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
          },
          body: new URLSearchParams({
            grant_type: 'authorization_code',
            client_id: CLIENT_ID,
            code,
            redirect_uri: REDIRECT_URI,
            code_verifier: verifier,
          }),
        })

        if (!tokenResponse.ok) {
          const errorData = await tokenResponse.json().catch(() => ({}))
          throw new Error(errorData.error_description || errorData.error || 'Token exchange failed')
        }

        const tokenData = await tokenResponse.json()
        storeToken(tokenData.access_token)
        clearPKCE()
        clearState()

        if (isMounted.current) {
          setStatus('Fetching user information...')
        }

        const user = await api.getCurrentUser()

        if (isMounted.current) {
          setUser(user)
          navigate('/')
        }
      } catch (error) {
        console.error('Callback error:', error)
        clearPKCE()
        clearState()

        if (isMounted.current) {
          setError(error instanceof Error ? error : new Error('Authentication failed'))
          setStatus('Authentication failed')
          setTimeout(() => navigate('/login'), 3000)
        }
      }
    }

    handleCallback()
  }, [navigate, setUser, setError])

  return (
    <div className="flex min-h-screen items-center justify-center">
      <div className="text-center">
        <h1 className="text-2xl font-bold mb-4">{status}</h1>
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-accent mx-auto"></div>
      </div>
    </div>
  )
}
