'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)) {
      console.log('Token expired in refreshUser, clearing auth state')
      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 {
        // Token is invalid or expired, get error details
        try {
          const errorData = await response.json()
          console.log('Server returned 401 error:', errorData)
        } catch (e) {
          console.log('Server returned 401 without JSON body, status:', response.status)
        }
        console.log('Token expired or invalid, clearing auth state')
        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)
    }
  }

  // Debug database schema
  const debugSchema = async () => {
    try {
      const response = await fetch('/api/debug/schema')
      const debug = await response.json()
      console.log('Database schema info:', debug)
    } catch (e) {
      console.log('Schema debug failed:', e)
    }
  }

  // Debug user lookup
  const debugUser = async (userId: string) => {
    try {
      const response = await fetch('/api/debug/user', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ userId })
      })
      const debug = await response.json()
      console.log('User debug info:', debug)
    } catch (e) {
      console.log('User debug failed:', e)
    }
  }

  // Debug token validation
  const debugToken = async (token: string) => {
    try {
      const response = await fetch('/api/debug/token', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ token })
      })
      const debug = await response.json()
      console.log('Token debug info:', debug)

      // Log more details about the token payload
      if (debug.payload) {
        console.log('Token payload:', debug.payload)

        // Debug user lookup
        if (debug.payload.userId) {
          debugUser(debug.payload.userId)
        }
      }
      if (debug.verificationResult) {
        console.log('Verification result:', debug.verificationResult)
      }
    } catch (e) {
      console.log('Token debug failed:', e)
    }
  }

  // Clear expired tokens and sync state immediately on mount
  useEffect(() => {
    if (typeof window !== 'undefined') {
      const token = localStorage.getItem('authToken')
      console.log('Auth mount check - token exists:', !!token)
      if (token) {
        console.log('Token preview:', token.substring(0, 50) + '...')

        // Debug the database schema and token on server side
        debugSchema()
        debugToken(token)

        const expired = isTokenExpired(token)
        console.log('Token expired:', expired)
        if (expired) {
          console.log('Clearing expired token and user state on mount')
          localStorage.removeItem('authToken')
          setUser(null)
        }
      } else if (user) {
        console.log('No token but user exists in store, clearing user state')
        setUser(null)
      }
      clearExpiredToken()
    }
  }, [])

  // Initialize auth state only once on mount
  useEffect(() => {
    if (!initialized && typeof window !== 'undefined') {
      const token = localStorage.getItem('authToken')
      console.log('Initialization flow - token exists:', !!token)

      if (token) {
        // Check if token is expired before making request
        if (isTokenExpired(token)) {
          console.log('Token expired during initialization, clearing auth state')
          localStorage.removeItem('authToken')
          setUser(null)
          setIsLoading(false)
        } else {
          console.log('Token is valid, calling refreshUser()')
          // Token appears valid, try to refresh user data
          // refreshUser will handle server-side validation failures
          refreshUser()
        }
      } else {
        console.log('No token found, clearing user state')
        // 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
}
