import { create } from 'zustand'; import { setAccessToken, clearTokens, restoreCustomerSession } from '@/services/api/client'; export interface CustomerAuthUser { customer_id: string; email: string; first_name?: string; last_name?: string; [key: string]: unknown; } interface AuthState { accessToken: string | null; customer: CustomerAuthUser | null; isAuthenticated: boolean; /** False until bootstrap has tried refresh/sessionStorage restore */ authReady: boolean; setAuth: (accessToken: string, customer: CustomerAuthUser | null) => void; clearAuth: () => void; setAuthReady: (ready: boolean) => void; bootstrapAuth: () => Promise; } const SESSION_KEY = 'ifixkart_customer_auth'; let bootstrapPromise: Promise | null = null; function persistSession(accessToken: string, customer: CustomerAuthUser | null) { try { sessionStorage.setItem( SESSION_KEY, JSON.stringify({ accessToken, customer }) ); } catch { /* ignore quota / private mode */ } } function readPersistedSession(): { accessToken: string; customer: CustomerAuthUser | null } | null { try { const raw = sessionStorage.getItem(SESSION_KEY); if (!raw) return null; const parsed = JSON.parse(raw); if (!parsed?.accessToken) return null; return parsed; } catch { return null; } } function clearPersistedSession() { try { sessionStorage.removeItem(SESSION_KEY); } catch { /* ignore */ } } export const useAuthStore = create((set, get) => ({ accessToken: null, customer: null, isAuthenticated: false, authReady: false, setAuth: (accessToken, customer) => { setAccessToken(accessToken); persistSession(accessToken, customer); set({ accessToken, customer, isAuthenticated: true, authReady: true, }); }, clearAuth: () => { clearTokens(); clearPersistedSession(); set({ accessToken: null, customer: null, isAuthenticated: false, authReady: true, }); }, setAuthReady: (ready) => set({ authReady: ready }), bootstrapAuth: async () => { if (get().authReady) return; if (bootstrapPromise) return bootstrapPromise; bootstrapPromise = (async () => { try { // 1) Restore from tab sessionStorage (survives soft navigations / reloads in same tab) const persisted = readPersistedSession(); if (persisted?.accessToken) { setAccessToken(persisted.accessToken); set({ accessToken: persisted.accessToken, customer: persisted.customer, isAuthenticated: true, authReady: true, }); return; } // 2) Try HttpOnly refresh cookie → new access token const restored = await restoreCustomerSession(); if (restored) { const customer = { customer_id: restored.customer_id, email: restored.email, first_name: restored.first_name, }; set({ accessToken: restored.access_token, customer, isAuthenticated: true, authReady: true, }); persistSession(restored.access_token, customer); return; } set({ authReady: true, isAuthenticated: false }); } finally { bootstrapPromise = null; } })(); return bootstrapPromise; }, }));