import { API_ENDPOINTS } from '@/config/api-config'
import { api } from '@/services/api'
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import router from '@/router'

export interface AuthState {
  accessToken: string | null
  refreshToken: string | null
  user: {
    email: string
    name: string
    id?: string | number
  } | null
}

export const useAuthStore = defineStore('auth', () => {
  // State
  const accessToken = ref<string | null>(localStorage.getItem('token'))
  const refreshToken = ref<string | null>(localStorage.getItem('refreshToken'))
  const user = ref<AuthState['user']>(null)

  // Getters
  const isAuthenticated = computed(() => !!accessToken.value)
  const getUser = computed(() => user.value)

  // Actions
  const setTokens = (tokens: { access_token: string; refresh_token?: string }) => {
    try {
      accessToken.value = tokens.access_token
      localStorage.setItem('token', tokens.access_token)
      if (tokens.refresh_token) {
        refreshToken.value = tokens.refresh_token
        localStorage.setItem('refreshToken', tokens.refresh_token)
      }
    } catch (error) {
      console.error('Error setting tokens:', error)
      clearTokens()
    }
  }

  const clearTokens = () => {
    try {
      accessToken.value = null
      refreshToken.value = null
      user.value = null
      localStorage.removeItem('token')
      localStorage.removeItem('refreshToken')
    } catch (error) {
      console.error('Error clearing tokens:', error)
    }
  }

  const setUser = (userData: AuthState['user']) => {
    user.value = userData
  }

  const fetchCurrentUser = async () => {
    if (!accessToken.value) {
      // No token, so definitely clear any residual state and return.
      clearTokens()
      return null
    }
    try {
      const response = await api.get(API_ENDPOINTS.USERS.PROFILE)
      setUser(response.data)
      return response.data
    } catch (error: any) {
      // Check if the error is from an Axios request and has a response status
      if (error.isAxiosError && error.response) {
        const status = error.response.status
        if (status === 401 || status === 403) {
          // Authentication error from the server, clear tokens.
          console.error('Authentication error fetching user, clearing tokens:', error)
          clearTokens()
        } else {
          // Other HTTP error, log it but don't clear tokens.
          // The user might be null, but the token remains for other cached calls.
          console.error('HTTP error fetching user, token preserved:', error)
        }
      } else {
        // Network error (offline) or other non-HTTP error.
        // Log the error but preserve tokens.
        // This allows the app to function with cached data if available.
        console.error('Network or other error fetching user, token preserved:', error)
      }
      // In all error cases where tokens are not cleared, return null for the user object.
      // The existing user object (if any) will remain until explicitly cleared or overwritten.
      // If the intention is to clear the user object on any fetch error, uncomment the next line:
      // setUser(null);
      return null
    }
  }

  const login = async (email: string, password: string) => {
    const formData = new FormData()
    formData.append('username', email)
    formData.append('password', password)

    const response = await api.post(API_ENDPOINTS.AUTH.LOGIN, formData, {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
    })

    const { access_token, refresh_token } = response.data
    setTokens({ access_token, refresh_token })
    await fetchCurrentUser()
    return response.data
  }

  const signup = async (userData: { name: string; email: string; password: string }) => {
    const response = await api.post(API_ENDPOINTS.AUTH.SIGNUP, userData)
    return response.data
  }

  const logout = async () => {
    clearTokens()
    await router.push('/auth/login')
  }

  return {
    accessToken,
    user,
    refreshToken,
    isAuthenticated,
    getUser,
    setTokens,
    clearTokens,
    setUser,
    fetchCurrentUser,
    login,
    signup,
    logout,
  }
})
