// Chat API Service with configurable endpoints import { mockChatData } from './mockChatData'; export interface User { id: string; name: string; email: string; avatar: string; online: boolean; lastSeen?: string; serviceType?: 'taxi' | 'restaurant' | 'hotel' | 'guide' | 'politur' | 'support'; } export interface Message { id: string; chatId: string; senderId: string; senderName: string; senderAvatar: string; content: string; timestamp: string; isOwn: boolean; status: 'sent' | 'delivered' | 'read'; } export interface Chat { id: string; name: string; type: 'direct' | 'group'; participants: User[]; lastMessage?: Message; unreadCount: number; avatar?: string; online?: boolean; lastActivity: string; serviceType?: 'taxi' | 'restaurant' | 'hotel' | 'guide' | 'politur' | 'support'; } class ChatApiService { private baseUrl: string; private apiKey: string; private useMockData: boolean; constructor() { // In a real environment, these would come from environment variables this.baseUrl = import.meta.env.VITE_CHAT_API_URL || 'http://localhost:3001/api'; this.apiKey = import.meta.env.VITE_CHAT_API_KEY || ''; this.useMockData = !this.apiKey || import.meta.env.DEV; } private async apiCall(endpoint: string, options: RequestInit = {}): Promise { if (this.useMockData) { // Return mock data return this.getMockData(endpoint) as T; } const response = await fetch(`${this.baseUrl}${endpoint}`, { ...options, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.apiKey}`, ...options.headers, }, }); if (!response.ok) { throw new Error(`API call failed: ${response.statusText}`); } return response.json(); } private getMockData(endpoint: string): any { // Simulate API responses with mock data const delay = () => new Promise(resolve => setTimeout(resolve, 100 + Math.random() * 500)); return new Promise(async (resolve) => { await delay(); if (endpoint.includes('/chats')) { resolve(mockChatData.chats); } else if (endpoint.includes('/users')) { resolve(mockChatData.users); } else if (endpoint.includes('/messages')) { const chatId = endpoint.split('/')[2]; resolve(mockChatData.messages.filter(m => m.chatId === chatId)); } else if (endpoint.includes('/search')) { resolve(mockChatData.users); } else { resolve([]); } }); } // Get all chats for current user async getChats(): Promise { return this.apiCall('/chats'); } // Get messages for a specific chat async getMessages(chatId: string): Promise { return this.apiCall(`/chats/${chatId}/messages`); } // Send a message async sendMessage(chatId: string, content: string): Promise { if (this.useMockData) { const newMessage: Message = { id: Date.now().toString(), chatId, senderId: 'current-user', senderName: 'You', senderAvatar: '/api/placeholder/40/40', content, timestamp: new Date().toLocaleTimeString(), isOwn: true, status: 'sent' }; mockChatData.messages.push(newMessage); return newMessage; } return this.apiCall(`/chats/${chatId}/messages`, { method: 'POST', body: JSON.stringify({ content }), }); } // Search users async searchUsers(query: string): Promise { if (this.useMockData) { await new Promise(resolve => setTimeout(resolve, 300)); return mockChatData.users.filter(user => user.name.toLowerCase().includes(query.toLowerCase()) || user.email.toLowerCase().includes(query.toLowerCase()) ); } return this.apiCall(`/users/search?q=${encodeURIComponent(query)}`); } // Create a new chat async createChat(participantIds: string[]): Promise { if (this.useMockData) { const participants = mockChatData.users.filter(user => participantIds.includes(user.id) ); const newChat: Chat = { id: Date.now().toString(), name: participants.length === 1 ? participants[0].name : `Group Chat`, type: participants.length === 1 ? 'direct' : 'group', participants, unreadCount: 0, lastActivity: new Date().toISOString(), avatar: participants[0]?.avatar, online: participants[0]?.online }; mockChatData.chats.push(newChat); return newChat; } return this.apiCall('/chats', { method: 'POST', body: JSON.stringify({ participantIds }), }); } // Get online users async getOnlineUsers(): Promise { const users = await this.apiCall('/users/online'); return users.filter(user => user.online); } // Mark messages as read async markAsRead(chatId: string): Promise { if (this.useMockData) { // Update mock data const chat = mockChatData.chats.find(c => c.id === chatId); if (chat) { chat.unreadCount = 0; } return; } await this.apiCall(`/chats/${chatId}/read`, { method: 'POST' }); } } export const chatApi = new ChatApiService();