const API_URL = import.meta.env.VITE_API_URL ?? 'http://localhost:4100'; class AuthError extends Error { constructor(message = 'Authentication required') { super(message); this.name = 'AuthError'; } } const getStoredToken = (): string | null => localStorage.getItem('helix_access_token'); const getRefreshToken = (): string | null => localStorage.getItem('helix_refresh_token'); const storeTokens = (accessToken: string, refreshToken: string) => { localStorage.setItem('helix_access_token', accessToken); localStorage.setItem('helix_refresh_token', refreshToken); }; const clearTokens = () => { localStorage.removeItem('helix_access_token'); localStorage.removeItem('helix_refresh_token'); }; export const apiClient = { async login(email: string, password: string): Promise<{ accessToken: string; refreshToken: string; user?: { id?: string; email?: string; firstName?: string; lastName?: string; avatarUrl?: string; role?: string; platformRoles?: string[]; }; }> { const response = await fetch(`${API_URL}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }), }); if (!response.ok) { const data = await response.json().catch(() => ({})); throw new Error(data.message ?? 'Login failed'); } const data = await response.json(); storeTokens(data.accessToken, data.refreshToken); return data; }, async graphql(query: string, variables?: Record): Promise { const token = getStoredToken(); if (!token) throw new AuthError(); const response = await fetch(`${API_URL}/graphql`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, body: JSON.stringify({ query, variables }), }); if (response.status === 401) { clearTokens(); throw new AuthError(); } const json = await response.json(); if (json.errors) { console.error('GraphQL errors:', json.errors); throw new Error(json.errors[0]?.message ?? 'GraphQL error'); } return json.data; }, async healthCheck(): Promise<{ status: string; platform: { reachable: boolean } }> { try { const response = await fetch(`${API_URL}/api/health`, { signal: AbortSignal.timeout(3000) }); if (!response.ok) return { status: 'down', platform: { reachable: false } }; return response.json(); } catch { return { status: 'down', platform: { reachable: false } }; } }, getStoredToken, getRefreshToken, storeTokens, clearTokens, isAuthenticated: () => !!getStoredToken(), };