'use client'

import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react'
import { useLocale } from 'next-intl'
import { useStore } from '@/lib/store'
import { isTokenExpired, clearExpiredToken } from '@/lib/auth/client'
import type { User } from '@/types'

interface AuthContextType {
  user: User | null
  isAuthenticated: boolean
  isLoading: boolean
  login: (email: string, password: string) => Promise<{ success: boolean; error?: string }>
  register: (email: string, password: string, name?: string) => Promise<{ success: boolean; error?: string }>
  logout: () => Promise<void>
  refreshUser: () => Promise<void>
}

const AuthContext = createContext<AuthContextType | undefined>(undefined)

interface AuthProviderProps {
  children: ReactNode
}

export function AuthProvider({ children }: AuthProviderProps) {
  const [isLoading, setIsLoading] = useState(true)
  const [initialized, setInitialized] = useState(false)
  const locale = useLocale()
  const { user, setUser } = useStore()

  const refreshUser = async (forceRefresh = false) => {
    const token = localStorage.getItem('authToken')
    if (!token) {
      setUser(null)
      setIsLoading(false)
      return
    }

    // Check if token is expired before making request
    if (isTokenExpired(token)) {
      localStorage.removeItem('authToken')
      setUser(null)
      setIsLoading(false)
      return
    }

    // If we already have a user and this isn't a forced refresh, don't re-fetch
    if (user && !forceRefresh) {
      setIsLoading(false)
      return
    }

    try {
      const response = await fetch(`/api/auth/me?locale=${locale}`, {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      })

      if (response.ok) {
        const data = await response.json()
        setUser(data.user)
      } else {
        localStorage.removeItem('authToken')
        setUser(null)
      }
    } catch (error) {
      console.error('Auth check failed:', error)
      // Network error or other issues, clean up auth state
      localStorage.removeItem('authToken')
      setUser(null)
    } finally {
      setIsLoading(false)
    }
  }


  // Clear expired tokens and sync state immediately on mount
  useEffect(() => {
    if (typeof window !== 'undefined') {
      const token = localStorage.getItem('authToken')
      if (token) {
        const expired = isTokenExpired(token)
        if (expired) {
          localStorage.removeItem('authToken')
          setUser(null)
        }
      } else if (user) {
        setUser(null)
      }
      clearExpiredToken()
    }
  }, [])

  // Initialize auth state only once on mount
  useEffect(() => {
    if (!initialized && typeof window !== 'undefined') {
      const token = localStorage.getItem('authToken')

      if (token) {
        // Check if token is expired before making request
        if (isTokenExpired(token)) {
          localStorage.removeItem('authToken')
          setUser(null)
          setIsLoading(false)
        } else {
          // Token appears valid, try to refresh user data
          // refreshUser will handle server-side validation failures
          refreshUser()
        }
      } else {
        // No token, clear any stale user data
        setUser(null)
        setIsLoading(false)
      }

      setInitialized(true)
    }
  }, [initialized])

  // Handle hydration issues - ensure we stop loading once initialized
  useEffect(() => {
    if (initialized && isLoading) {
      const token = localStorage.getItem('authToken')
      if (!token) {
        setIsLoading(false)
      }
    }
  }, [initialized, isLoading])

  const login = async (email: string, password: string): Promise<{ success: boolean; error?: string }> => {
    try {
      const response = await fetch(`/api/auth/login?locale=${locale}`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ email, password }),
      })

      const data = await response.json()

      if (response.ok) {
        localStorage.setItem('authToken', data.token)
        setUser(data.user)
        return { success: true }
      } else {
        return { success: false, error: data.error }
      }
    } catch (error) {
      console.error('Login error:', error)
      return {
        success: false,
        error: locale === 'en' ? 'Login failed' : 'Autentificare eșuată'
      }
    }
  }

  const register = async (email: string, password: string, name?: string): Promise<{ success: boolean; error?: string }> => {
    try {
      const response = await fetch(`/api/auth/register?locale=${locale}`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ email, password, name }),
      })

      const data = await response.json()

      if (response.ok) {
        localStorage.setItem('authToken', data.token)
        setUser(data.user)
        return { success: true }
      } else {
        return { success: false, error: data.error }
      }
    } catch (error) {
      console.error('Registration error:', error)
      return {
        success: false,
        error: locale === 'en' ? 'Registration failed' : 'Înregistrare eșuată'
      }
    }
  }

  const logout = async () => {
    try {
      const token = localStorage.getItem('authToken')
      if (token) {
        await fetch('/api/auth/logout', {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${token}`
          }
        })
      }
    } catch (error) {
      console.error('Logout error:', error)
    } finally {
      localStorage.removeItem('authToken')
      setUser(null)
    }
  }

  const value: AuthContextType = {
    user,
    isAuthenticated: !!user,
    isLoading,
    login,
    register,
    logout,
    refreshUser: () => refreshUser(true)
  }

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

export function useAuth(): AuthContextType {
  const context = useContext(AuthContext)
  if (context === undefined) {
    throw new Error('useAuth must be used within an AuthProvider')
  }
  return context
}
