import { useAuthStore } from '../stores/auth.ts' import { mockPurchases, mockProducts, mockCoupons, mockAlerts, getMockPriceHistory, } from './mock-data.ts' const API_BASE = import.meta.env.VITE_API_URL ?? '/api/v1' const USE_MOCK = import.meta.env.VITE_MOCK_API === 'true' // Mock response lookup table const mockRoutes: Record unknown> = { '/purchases': () => mockPurchases, '/products': () => mockProducts, '/coupons': () => mockCoupons, '/price-alerts': () => mockAlerts, } function matchMockRoute(path: string): T | null { // Exact match if (mockRoutes[path]) return mockRoutes[path](path) as T // /purchases/:id const purchaseMatch = path.match(/^\/purchases\/(.+)$/) if (purchaseMatch) { const purchase = mockPurchases.find((p) => p.id === purchaseMatch[1]) return (purchase ?? null) as T } // /products/:id/price-history const priceHistoryMatch = path.match(/^\/products\/(.+)\/price-history$/) if (priceHistoryMatch) { return getMockPriceHistory(priceHistoryMatch[1]) as T } // /products?q=search or /products/:id const productMatch = path.match(/^\/products\/(.+)$/) if (productMatch) { const product = mockProducts.find((p) => p.id === productMatch[1]) return (product ?? null) as T } const productsSearch = path.match(/^\/products\?q=(.+)$/) if (productsSearch) { const q = decodeURIComponent(productsSearch[1]).toLowerCase() return mockProducts.filter( (p) => p.name.toLowerCase().includes(q) || p.brand.toLowerCase().includes(q) || p.category.toLowerCase().includes(q), ) as T } return null } async function apiFetch(path: string, options?: RequestInit): Promise { // Mock interceptor: return mock data without hitting the network if (USE_MOCK && (!options?.method || options.method === 'GET')) { const mockResult = matchMockRoute(path) if (mockResult !== null) { // Simulate network delay for realistic loading states await new Promise((r) => setTimeout(r, 300)) return mockResult } } const token = useAuthStore.getState().token const res = await fetch(`${API_BASE}${path}`, { ...options, headers: { 'Content-Type': 'application/json', ...(token ? { Authorization: `Bearer ${token}` } : {}), ...options?.headers, }, }) if (res.status === 401) { useAuthStore.getState().logout() throw new Error('Unauthorized') } if (!res.ok) { throw new Error(`API error: ${res.status}`) } return res.json() as Promise } export const api = { get: (path: string) => apiFetch(path), post: (path: string, body: unknown) => apiFetch(path, { method: 'POST', body: JSON.stringify(body) }), put: (path: string, body: unknown) => apiFetch(path, { method: 'PUT', body: JSON.stringify(body) }), delete: (path: string) => apiFetch(path, { method: 'DELETE' }), }