import { create } from "zustand"; import api from "@/lib/api"; import type { User, Organization } from "@/lib/types"; export type { Organization }; interface AuthState { user: User | null; isLoading: boolean; isAuthenticated: boolean; _hasFetched: boolean; fetchUser: () => Promise; login: (email: string, password: string, orgId?: string) => Promise; logout: () => Promise; setAuth: (user: User) => void; switchOrg: (orgId: string) => Promise; } export const useAuthStore = create((set, get) => ({ user: null, isLoading: true, isAuthenticated: false, _hasFetched: false, fetchUser: async () => { if (get()._hasFetched) return; set({ _hasFetched: true }); const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 5000); try { const user = await api.get("/api/v1/auth/me", { signal: controller.signal }); set({ user, isAuthenticated: true, isLoading: false }); } catch { set({ user: null, isAuthenticated: false, isLoading: false }); } finally { clearTimeout(timeout); } }, login: async (email: string, password: string, orgId?: string) => { const data = await api.post<{ user: User }>("/api/v1/auth/login", { email, password, org_id: orgId, }); set({ user: data.user, isAuthenticated: true, isLoading: false }); }, setAuth: (user: User) => { set({ user, isAuthenticated: true, isLoading: false }); }, logout: async () => { try { await api.post("/api/v1/auth/logout"); } catch { // ignore } finally { set({ user: null, isAuthenticated: false, _hasFetched: false }); } }, switchOrg: async (orgId: string) => { const data = await api.post<{ message: string; org: Organization; user?: User; }>("/api/v1/auth/switch-org", { org_id: orgId }); if (data.user && data.org) { set({ user: { ...data.user, org_id: orgId, org: data.org }, isAuthenticated: true }); } else { const user = get().user; if (user && data.org) { set({ user: { ...user, org_id: orgId, org: data.org } }); } } }, }));