import { create } from 'zustand'; import { apiClient } from './api-client'; interface User { id: string; email: string; fullName: string; phone?: string; role: string; passengerId?: string; dateOfBirth?: string; gender?: string; nationality?: string; nationalityCode?: string; nationalId?: string; passportNumber?: string; passportCountry?: string; passportIssueDate?: string; passportExpiryDate?: string; passportIssuingAuthority?: string; faydaVerified?: boolean; faydaSub?: string; faydaVerifiedAt?: string; lastLoginAt?: string; createdAt?: string; } interface AuthState { user: User | null; token: string | null; isAuthenticated: boolean; isInitialized: boolean; login: (email: string, password: string) => Promise; register: (data: RegisterData) => Promise; logout: () => Promise; setUser: (user: User, token: string) => void; updateUser: (userData: Partial) => void; initialize: () => Promise; fetchProfile: () => Promise; } interface RegisterData { fullName: string; email: string; phone: string; } interface RegisterResult { iamUserId: string; email: string; phoneNumber: string; } export const useAuthStore = create((set, get) => ({ user: null, token: null, isAuthenticated: false, isInitialized: false, initialize: async () => { if (typeof window === 'undefined') return; const token = localStorage.getItem('auth_token'); const userStr = localStorage.getItem('auth_user'); if (token && userStr) { try { const user = JSON.parse(userStr); set({ user, token, isAuthenticated: true, isInitialized: true }); // Fetch fresh profile data in background get().fetchProfile().catch(() => { // If profile fetch fails, token might be expired console.warn('Failed to fetch profile, token might be expired'); }); } catch (e) { localStorage.removeItem('auth_token'); localStorage.removeItem('auth_user'); set({ isInitialized: true }); } } else { set({ isInitialized: true }); } }, fetchProfile: async () => { if (typeof window === 'undefined') return; const token = localStorage.getItem('auth_token'); if (!token) return; try { const response: any = await apiClient.get('/auth/profile', { headers: { 'Authorization': `Bearer ${token}` } }); const userData = response.data || response; if (typeof window !== 'undefined') { localStorage.setItem('auth_user', JSON.stringify(userData)); } set({ user: userData }); } catch (error: any) { // If 401, token is invalid - logout if (error.response?.status === 401) { if (typeof window !== 'undefined') { localStorage.removeItem('auth_token'); localStorage.removeItem('auth_user'); } set({ user: null, token: null, isAuthenticated: false }); } throw error; } }, login: async (email: string, password: string) => { const response: any = await apiClient.post('/auth/login', { email, password }); const { token, user } = response.data || response; if (typeof window !== 'undefined') { localStorage.setItem('auth_token', token); localStorage.setItem('auth_user', JSON.stringify(user)); } set({ user, token, isAuthenticated: true }); }, register: async (data: RegisterData): Promise => { // Shape required by the passenger-api RegisterDto; username = email by convention. // Registration no longer takes a password — the account is created as pending and // an SMS verification code is sent. The user completes signup on the verify-account // page (set-password). No token is issued here; the user is NOT logged in yet. const payload = { email: data.email, username: data.email, phoneNumber: data.phone, name: { en: data.fullName, am: data.fullName }, }; const response: any = await apiClient.post('/auth/register', payload); const result = response.data || response; return { iamUserId: result.iamUserId, email: result.email, phoneNumber: result.phoneNumber, }; }, logout: async () => { try { const token = typeof window !== 'undefined' ? localStorage.getItem('auth_token') : null; if (token) { // Call logout endpoint to invalidate session on backend await apiClient.post('/auth/logout', {}, { headers: { 'Authorization': `Bearer ${token}` } }); } } catch (error) { console.error('Logout API call failed:', error); // Continue with logout even if API call fails } // Clear local storage and state if (typeof window !== 'undefined') { localStorage.removeItem('auth_token'); localStorage.removeItem('auth_user'); } set({ user: null, token: null, isAuthenticated: false }); // Redirect to home page after state is updated if (typeof window !== 'undefined') { setTimeout(() => { window.location.href = '/'; }, 100); } }, setUser: (user: User, token: string) => { if (typeof window !== 'undefined') { localStorage.setItem('auth_token', token); localStorage.setItem('auth_user', JSON.stringify(user)); } set({ user, token, isAuthenticated: true }); }, updateUser: (userData: Partial) => { if (typeof window !== 'undefined') { const currentUser = JSON.parse(localStorage.getItem('auth_user') || '{}'); const updatedUser = { ...currentUser, ...userData }; localStorage.setItem('auth_user', JSON.stringify(updatedUser)); set({ user: updatedUser }); } }, }) );