import { computed, ref } from 'vue' import { defineStore } from 'pinia' import { AUTH_EXPIRED_EVENT, AUTH_UPDATED_EVENT, apiRequest, clearAccessToken, refreshSession, setAccessToken, } from '@/lib/api' import type { AuthResponse, AuthUser } from '@/types/api' import type { Profile } from '@/types/database' export const useAuthStore = defineStore('auth', () => { const user = ref(null) const profile = ref(null) const loading = ref(true) let listenersAttached = false const isLoggedIn = computed(() => !!user.value) const isAdmin = computed(() => profile.value?.role === 'admin') function applyAuth(auth: AuthResponse) { setAccessToken(auth.access_token) user.value = auth.user profile.value = auth.profile } function clearAuth() { clearAccessToken() user.value = null profile.value = null } async function login(email: string, password: string) { const auth = await apiRequest('/auth/login', { method: 'POST', auth: false, body: { email, password }, }) applyAuth(auth) } async function register(email: string, password: string, username: string) { await apiRequest('/auth/register', { method: 'POST', auth: false, body: { email, password, username }, }) } async function logout() { try { await apiRequest('/auth/logout', { method: 'POST', retry: false }) } finally { clearAuth() } } async function updateUsername(username: string) { const updatedProfile = await apiRequest('/profiles/me', { method: 'PATCH', body: { username }, }) profile.value = updatedProfile } async function updatePassword(password: string) { const auth = await apiRequest('/auth/password', { method: 'PATCH', body: { password }, }) applyAuth(auth) } async function sendPasswordReset(email: string) { await apiRequest('/auth/forgot-password', { method: 'POST', auth: false, body: { email }, }) } async function initialize() { if (!listenersAttached) { window.addEventListener(AUTH_UPDATED_EVENT, event => { applyAuth((event as CustomEvent).detail) }) window.addEventListener(AUTH_EXPIRED_EVENT, clearAuth) listenersAttached = true } try { applyAuth(await refreshSession()) } catch { clearAuth() } finally { loading.value = false } } return { user, profile, loading, isLoggedIn, isAdmin, login, register, logout, updateUsername, updatePassword, sendPasswordReset, initialize, } })