import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { authService } from '@/services/auth'
import type { User, LoginCredentials, RegisterData, LoginResponse } from '@/types/auth'

export const useAuthStore = defineStore('auth', () => {
  // State
  const user = ref<User | null>(null)
  const accessToken = ref<string | null>(localStorage.getItem('access_token'))
  const refreshToken = ref<string | null>(localStorage.getItem('refresh_token'))
  const isLoading = ref(false)
  const error = ref<string | null>(null)

  // Getters
  const isAuthenticated = computed(() => !!accessToken.value && !!user.value)
  const userRole = computed(() => user.value?.role || null)
  const isAdmin = computed(() => user.value?.is_admin || false)

  // Actions
  const login = async (credentials: LoginCredentials): Promise<LoginResponse> => {
    try {
      isLoading.value = true
      error.value = null
      
      const response = await authService.login(credentials)
      
      // Store tokens
      accessToken.value = response.access_token
      refreshToken.value = response.refresh_token
      localStorage.setItem('access_token', response.access_token)
      localStorage.setItem('refresh_token', response.refresh_token)
      
      // Get user profile
      await getCurrentUser()
      
      return response
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Login failed'
      throw err
    } finally {
      isLoading.value = false
    }
  }

  const register = async (data: RegisterData) => {
    try {
      isLoading.value = true
      error.value = null
      
      const response = await authService.register(data)
      return response
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Registration failed'
      throw err
    } finally {
      isLoading.value = false
    }
  }

  const logout = async () => {
    try {
      if (refreshToken.value) {
        await authService.logout(refreshToken.value)
      }
    } catch (err) {
      // Ignore logout errors
      console.warn('Logout error:', err)
    } finally {
      // Clear local state regardless of API call success
      user.value = null
      accessToken.value = null
      refreshToken.value = null
      localStorage.removeItem('access_token')
      localStorage.removeItem('refresh_token')
    }
  }

  const getCurrentUser = async () => {
    try {
      if (!accessToken.value) return null
      
      const userData = await authService.getCurrentUser()
      user.value = userData
      return userData
    } catch (err: any) {
      // If getting user fails, clear tokens
      if (err.response?.status === 401) {
        await logout()
      }
      throw err
    }
  }

  const refreshAccessToken = async () => {
    try {
      if (!refreshToken.value) {
        throw new Error('No refresh token available')
      }
      
      const response = await authService.refreshToken(refreshToken.value)
      
      accessToken.value = response.access_token
      localStorage.setItem('access_token', response.access_token)
      
      return response.access_token
    } catch (err: any) {
      // If refresh fails due to expired token, clear everything
      console.warn('Token refresh failed:', err.response?.data?.detail || err.message)
      await logout()
      throw err
    }
  }

  const clearError = () => {
    error.value = null
  }

  // Initialize auth state on store creation
  const initializeAuth = async () => {
    if (accessToken.value) {
      try {
        await getCurrentUser()
      } catch (err: any) {
        // If initialization fails due to expired token, clear everything
        console.warn('Auth initialization failed:', err.response?.data?.detail || err.message)
        await logout()
      }
    }
  }

  // Check if tokens are expired and clear them
  const validateTokens = () => {
    const token = accessToken.value
    if (token) {
      try {
        // Decode JWT to check expiration (basic check)
        const payload = JSON.parse(atob(token.split('.')[1]))
        const exp = payload.exp * 1000 // Convert to milliseconds
        const now = Date.now()
        
        // If token expired more than 7 days ago, clear everything
        if (now - exp > 7 * 24 * 60 * 60 * 1000) {
          console.warn('Tokens are too old, clearing...')
          logout()
        }
      } catch (err) {
        console.warn('Token validation failed:', err)
        // If we can't decode the token, it's invalid
        logout()
      }
    }
  }

  return {
    // State
    user,
    accessToken,
    refreshToken,
    isLoading,
    error,
    
    // Getters
    isAuthenticated,
    userRole,
    isAdmin,
    
    // Actions
    login,
    register,
    logout,
    getCurrentUser,
    refreshAccessToken,
    clearError,
    initializeAuth,
    validateTokens
  }
})