import axios, { AxiosRequestHeaders } from 'axios' import { TripCreate, Trip, TripWithParticipants, ExpenseCreate, Expense, ParticipantCreate, Participant } from '@/types' // Smart API base URL configuration const getApiBaseUrl = () => { // Use configured base path from environment (e.g., /juntete) // Default to /juntete for production const basePath = process.env.NEXT_PUBLIC_BASE_PATH || '/juntete' // In production/browser, prepend the base path if (typeof window !== 'undefined') { return basePath } // In server-side context (optional, depending on internal routing) return basePath } const api = axios.create({ baseURL: getApiBaseUrl(), headers: { 'Content-Type': 'application/json', }, }) // Axios interceptor to add auth tokens api.interceptors.request.use( async (config) => { // Add authentication token if available if (typeof window !== 'undefined' && config.url) { // Extract trip_id from URL if it's a trip-related endpoint const tripIdMatch = config.url.match(/\/(trips|expenses|participants)\/(\d+)/) if (tripIdMatch) { const tripId = parseInt(tripIdMatch[2]) const { getTripToken } = await import('@/lib/trip-auth') const token = getTripToken(tripId) if (token) { if (!config.headers) { config.headers = {} as AxiosRequestHeaders } config.headers['Authorization'] = `Bearer ${token}` } } } return config }, (error) => Promise.reject(error) ) // Trip API export const tripApi = { create: async (data: TripCreate): Promise => { const response = await api.post('/api/trips', data) return response.data }, getById: async (id: number): Promise => { const response = await api.get(`/api/trips/${id}`) return response.data }, getByShareCode: async (shareCode: string): Promise => { const response = await api.get(`/api/trips/share/${shareCode}`) return response.data }, } // Participant API export const participantApi = { create: async (tripId: number, data: ParticipantCreate): Promise => { const response = await api.post(`/api/participants/${tripId}/participants`, data) return response.data }, getByTripId: async (tripId: number): Promise => { const response = await api.get(`/api/participants/${tripId}/participants`) return response.data }, identify: async (tripId: number, participantId: number, deviceId: string): Promise<{ message: string; name: string }> => { const response = await api.put(`/api/participants/${tripId}/participants/${participantId}/identify`, { device_id: deviceId, }) return response.data }, } // Expense API export const expenseApi = { create: async (tripId: number, data: ExpenseCreate): Promise => { const response = await api.post(`/api/expenses/${tripId}/expenses`, data) return response.data }, getByTripId: async (tripId: number): Promise => { const response = await api.get(`/api/expenses/${tripId}/expenses`) return response.data }, getById: async (tripId: number, expenseId: number): Promise => { const response = await api.get(`/api/expenses/${tripId}/expenses/${expenseId}`) return response.data }, } // Auth API (for anonymous user identification) export const authApi = { getTripByShareCode: async (shareCode: string): Promise<{ trip: Trip; participants: Participant[] }> => { const response = await api.get(`/api/auth/trip/${shareCode}`) return response.data }, identify: async (tripId: number, participantId: number, deviceId: string): Promise<{ message: string; participant_name: string }> => { const response = await api.post('/api/auth/identify', { trip_id: tripId, participant_id: participantId, device_id: deviceId, }) return response.data }, } // Trip token management export const getTripToken = (tripId: number): string | null => { if (typeof window === 'undefined') return null return localStorage.getItem(`trip_token_${tripId}`) } // Export convenience functions for backward compatibility export const createTrip = tripApi.create export const getTrip = tripApi.getById export const getTripByShareCode = tripApi.getByShareCode