import axios, { AxiosError } from 'axios'; // Use proxy in development (vite will forward to backend) // In production, use VITE_API_URL const API_BASE = import.meta.env.VITE_API_URL || ''; const API_PREFIX = import.meta.env.VITE_API_PREFIX || '/api/v1'; export const api = axios.create({ baseURL: `${API_BASE}${API_PREFIX}`, headers: { 'Content-Type': 'application/json', }, }); // Add auth interceptor - attach token to requests api.interceptors.request.use((config) => { const token = localStorage.getItem('accessToken'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); // Response interceptor - handle 401 errors api.interceptors.response.use( (response) => response, async (error: AxiosError) => { if (error.response?.status === 401) { // Try refresh token const refreshToken = localStorage.getItem('refreshToken'); if (refreshToken) { try { const response = await axios.post(`${API_BASE}${API_PREFIX}/auth/refresh`, { refreshToken, }); const { accessToken, refreshToken: newRefresh } = response.data; localStorage.setItem('accessToken', accessToken); localStorage.setItem('refreshToken', newRefresh); // Retry original request if (error.config) { error.config.headers.Authorization = `Bearer ${accessToken}`; return axios(error.config); } } catch { // Refresh failed, clear tokens and redirect to login localStorage.removeItem('accessToken'); localStorage.removeItem('refreshToken'); localStorage.removeItem('user'); localStorage.removeItem('tenant'); window.location.href = '/login'; } } else { // No refresh token, redirect to login localStorage.removeItem('accessToken'); localStorage.removeItem('user'); localStorage.removeItem('tenant'); window.location.href = '/login'; } } return Promise.reject(error); } ); // Auth API export const authApi = { register: (data: { name: string; ownerName: string; businessType: string; phone: string; pin: string; email?: string; whatsapp?: string; }) => api.post('/auth/register', data), login: (data: { phone: string; pin: string }) => api.post('/auth/login', data), refresh: (refreshToken: string) => api.post('/auth/refresh', { refreshToken }), changePin: (data: { currentPin: string; newPin: string }) => api.post('/auth/change-pin', data), }; // Products API export const productsApi = { getAll: (params?: { category?: string; search?: string }) => api.get('/products', { params }), getById: (id: string) => api.get(`/products/${id}`), create: (data: any) => api.post('/products', data), update: (id: string, data: any) => api.patch(`/products/${id}`, data), delete: (id: string) => api.delete(`/products/${id}`), }; // Orders API export const ordersApi = { getAll: (params?: { status?: string; date?: string }) => api.get('/orders', { params }), getById: (id: string) => api.get(`/orders/${id}`), create: (data: any) => api.post('/orders', data), updateStatus: (id: string, status: string) => api.patch(`/orders/${id}/status`, { status }), }; // Customers API export const customersApi = { getAll: (params?: { search?: string }) => api.get('/customers', { params }), getById: (id: string) => api.get(`/customers/${id}`), create: (data: any) => api.post('/customers', data), update: (id: string, data: any) => api.patch(`/customers/${id}`, data), getFiado: (id: string) => api.get(`/customers/${id}/fiado`), }; // Inventory API export const inventoryApi = { getMovements: (params?: { productId?: string; type?: string }) => api.get('/inventory/movements', { params }), createMovement: (data: any) => api.post('/inventory/movements', data), getLowStock: () => api.get('/inventory/low-stock'), getAlerts: () => api.get('/inventory/alerts'), }; // Dashboard API export const dashboardApi = { getStats: () => api.get('/dashboard/stats'), getSalesChart: (period: string) => api.get('/dashboard/sales', { params: { period } }), getTopProducts: () => api.get('/dashboard/top-products'), }; // Referrals API export const referralsApi = { getMyCode: () => api.get('/referrals/my-code'), generateCode: () => api.post('/referrals/generate-code'), validateCode: (code: string) => api.get(`/referrals/validate/${code}`), applyCode: (code: string) => api.post('/referrals/apply-code', { code }), getMyReferrals: () => api.get('/referrals/list'), getStats: () => api.get('/referrals/stats'), getRewards: () => api.get('/referrals/rewards'), getAvailableMonths: () => api.get('/referrals/rewards/available-months'), getDiscount: () => api.get('/referrals/discount'), }; // CoDi/SPEI API export const codiSpeiApi = { // CoDi generateQr: (data: { amount: number; description?: string; saleId?: string }) => api.post('/codi/generate-qr', data), getCodiStatus: (id: string) => api.get(`/codi/status/${id}`), getCodiTransactions: (limit?: number) => api.get('/codi/transactions', { params: { limit } }), // SPEI getClabe: () => api.get('/spei/clabe'), createClabe: (beneficiaryName: string) => api.post('/spei/create-clabe', { beneficiaryName }), getSpeiTransactions: (limit?: number) => api.get('/spei/transactions', { params: { limit } }), // Summary getSummary: (date?: string) => api.get('/payments/summary', { params: { date } }), }; // Invoices API (SAT/CFDI) export const invoicesApi = { // Tax Config getTaxConfig: () => api.get('/invoices/tax-config'), saveTaxConfig: (data: any) => api.post('/invoices/tax-config', data), // Invoices getAll: (params?: { status?: string; from?: string; to?: string; limit?: number }) => api.get('/invoices', { params }), getById: (id: string) => api.get(`/invoices/${id}`), create: (data: any) => api.post('/invoices', data), stamp: (id: string) => api.post(`/invoices/${id}/stamp`), cancel: (id: string, reason: string, uuidReplacement?: string) => api.post(`/invoices/${id}/cancel`, { reason, uuidReplacement }), send: (id: string, email?: string) => api.post(`/invoices/${id}/send`, { email }), getSummary: (month?: string) => api.get('/invoices/summary', { params: { month } }), }; // Marketplace API export const marketplaceApi = { // Suppliers getSuppliers: (params?: { category?: string; zipCode?: string; search?: string; limit?: number }) => api.get('/marketplace/suppliers', { params }), getSupplier: (id: string) => api.get(`/marketplace/suppliers/${id}`), getSupplierProducts: (id: string, params?: { category?: string; search?: string }) => api.get(`/marketplace/suppliers/${id}/products`, { params }), getSupplierReviews: (id: string, params?: { limit?: number }) => api.get(`/marketplace/suppliers/${id}/reviews`, { params }), // Orders createOrder: (data: any) => api.post('/marketplace/orders', data), getOrders: (params?: { status?: string; supplierId?: string; limit?: number }) => api.get('/marketplace/orders', { params }), getOrder: (id: string) => api.get(`/marketplace/orders/${id}`), cancelOrder: (id: string, reason: string) => api.put(`/marketplace/orders/${id}/cancel`, { reason }), // Reviews createReview: (data: any) => api.post('/marketplace/reviews', data), // Favorites getFavorites: () => api.get('/marketplace/favorites'), addFavorite: (supplierId: string) => api.post(`/marketplace/favorites/${supplierId}`), removeFavorite: (supplierId: string) => api.delete(`/marketplace/favorites/${supplierId}`), // Stats getStats: () => api.get('/marketplace/stats'), };