import { createContext, useContext, useEffect, useState } from 'react'
import { useDispatch } from 'react-redux'
import { setCredentials, clearCredentials } from '../store/slices/authSlice'
import { api } from '../services/api'

const AuthContext = createContext()

export const useAuth = () => {
  const context = useContext(AuthContext)
  if (!context) {
    throw new Error('useAuth must be used within an AuthProvider')
  }
  return context
}

export const AuthProvider = ({ children }) => {
  const [isLoading, setIsLoading] = useState(true)
  const dispatch = useDispatch()

  useEffect(() => {
    const initAuth = async () => {
      try {
        const token = localStorage.getItem('accessToken')
        const refreshToken = localStorage.getItem('refreshToken')
        
        if (token) {
          // First, immediately set the token in Redux to prevent redirect
          dispatch(setCredentials({
            user: { email: 'Loading...' }, // Temporary user
            token
          }))

          try {
            // Verify token with backend
            const response = await api.get('/auth/user/')
            if (response) {
              dispatch(setCredentials({
                user: response,
                token
              }))
            } else {
              // Invalid response, clear tokens
              localStorage.removeItem('accessToken')
              localStorage.removeItem('refreshToken')
              dispatch(clearCredentials())
            }
          } catch (error) {
            console.warn('Token verification failed:', error)
            
            // If it's a network error or server error, keep the token temporarily
            if (error.code === 'ERR_NETWORK' || error.response?.status >= 500) {
              console.warn('Backend unavailable, using cached token')
              dispatch(setCredentials({
                user: { 
                  email: 'admin@dubai-analytics.com',
                  first_name: 'Admin',
                  last_name: 'User'
                },
                token
              }))
            } else if (error.response?.status === 401) {
              // Token is invalid, try to refresh
              if (refreshToken) {
                try {
                  const refreshResponse = await api.post('/auth/refresh/', { refresh: refreshToken })
                  const newToken = refreshResponse.access
                  localStorage.setItem('accessToken', newToken)
                  
                  // Get user data with new token
                  const userResponse = await api.get('/auth/user/')
                  dispatch(setCredentials({
                    user: userResponse,
                    token: newToken
                  }))
                } catch (refreshError) {
                  // Refresh failed, clear everything
                  localStorage.removeItem('accessToken')
                  localStorage.removeItem('refreshToken')
                  dispatch(clearCredentials())
                }
              } else {
                // No refresh token, clear everything
                localStorage.removeItem('accessToken')
                localStorage.removeItem('refreshToken')
                dispatch(clearCredentials())
              }
            } else {
              // Other errors, clear tokens
              localStorage.removeItem('accessToken')
              localStorage.removeItem('refreshToken')
              dispatch(clearCredentials())
            }
          }
        }
      } catch (error) {
        console.error('Auth initialization error:', error)
        localStorage.removeItem('accessToken')
        localStorage.removeItem('refreshToken')
        dispatch(clearCredentials())
      } finally {
        setIsLoading(false)
      }
    }

    initAuth()
  }, [dispatch])

  const login = async (email, password) => {
    try {
      const response = await api.post('/auth/login/', { email, password })
      const { user, tokens } = response
      
      localStorage.setItem('accessToken', tokens.access)
      localStorage.setItem('refreshToken', tokens.refresh)
      
      dispatch(setCredentials({ user, token: tokens.access }))
      
      return { success: true }
    } catch (error) {
      return { 
        success: false, 
        error: error.response?.data?.message || error.message || 'Login failed' 
      }
    }
  }

  const logout = () => {
    localStorage.removeItem('accessToken')
    localStorage.removeItem('refreshToken')
    dispatch(clearCredentials())
  }

  const value = {
    isLoading,
    login,
    logout
  }

  if (isLoading) {
    return (
      <div className="min-h-screen flex items-center justify-center">
        <div className="animate-spin rounded-full h-32 w-32 border-b-2 border-primary-600"></div>
      </div>
    )
  }

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

