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
    is_guest?: boolean
    avatarUrl?: string
  } | 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)
  const isRefreshing = ref(false)
  const fetchingUser = ref(false)

  // Getters
  const isAuthenticated = computed(() => !!accessToken.value)
  const getUser = computed(() => user.value)
  const isGuest = computed(() => user.value?.is_guest ?? false)

  // 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')
      isRefreshing.value = false
      fetchingUser.value = false
    } 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
    }

    // Prevent multiple simultaneous user fetch calls
    if (fetchingUser.value) {
      return user.value
    }

    fetchingUser.value = true
    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) {
          // Only clear tokens if we're not currently refreshing
          // The API interceptor will handle the refresh
          if (!isRefreshing.value) {
            console.error('Authentication error fetching user, tokens will be handled by interceptor:', error)
            // Don't clear tokens here - let the API interceptor handle it
            // This prevents race conditions where tokens get cleared while refresh is happening
          }
        } else {
          // Other HTTP error, log it but don't clear tokens.
          console.error('HTTP error fetching user, token preserved:', error)
        }
      } else {
        // Network error (offline) or other non-HTTP error.
        // Log the error but preserve tokens.
        console.error('Network or other error fetching user, token preserved:', error)
      }
      return null
    } finally {
      fetchingUser.value = false
    }
  }

  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 loginAsGuest = async () => {
    const response = await api.post(API_ENDPOINTS.AUTH.GUEST)
    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')
  }

  const requestMagicLink = async (email: string) => {
    const response = await api.post(API_ENDPOINTS.AUTH.MAGIC_LINK, { email })
    return response.data as { detail: string; token: string }
  }

  const verifyMagicLink = async (token: string) => {
    const response = await api.get(API_ENDPOINTS.AUTH.MAGIC_LINK_VERIFY, { params: { token } })
    const { access_token, refresh_token } = response.data
    setTokens({ access_token, refresh_token })
    await fetchCurrentUser()
    return response.data
  }

  return {
    accessToken,
    user,
    refreshToken,
    isAuthenticated,
    getUser,
    isGuest,
    isRefreshing,
    fetchingUser,
    setTokens,
    clearTokens,
    setUser,
    fetchCurrentUser,
    login,
    loginAsGuest,
    signup,
    logout,
    requestMagicLink,
    verifyMagicLink,
  }
})
