import { Condo, Family, Payment, AppSettings, User, AuthResponse, Ticket, TicketComment, ExtraordinaryExpense, Notice, AlertDefinition, NoticeRead } from '../types'; const API_URL = '/api'; async function request(endpoint: string, options: RequestInit = {}): Promise { const token = localStorage.getItem('condo_token'); const headers: HeadersInit = { 'Content-Type': 'application/json', ...options.headers as any, }; if (token) { headers['Authorization'] = `Bearer ${token}`; } const response = await fetch(`${API_URL}${endpoint}`, { ...options, headers, }); if (!response.ok) { const errorText = await response.text(); throw new Error(errorText || response.statusText); } // Handle empty responses const text = await response.text(); return text ? JSON.parse(text) : undefined; } export const CondoService = { // Auth & User login: async (email: string, password: string): Promise => { const data = await request('/auth/login', { method: 'POST', body: JSON.stringify({ email, password }) }); localStorage.setItem('condo_token', data.token); localStorage.setItem('condo_user', JSON.stringify(data.user)); }, logout: () => { localStorage.removeItem('condo_token'); localStorage.removeItem('condo_user'); window.location.href = '/#/login'; }, getCurrentUser: (): User | null => { const u = localStorage.getItem('condo_user'); return u ? JSON.parse(u) : null; }, updateProfile: async (data: any): Promise => { const res = await request<{success: boolean, user: User}>('/profile', { method: 'PUT', body: JSON.stringify(data) }); if (res.user) { localStorage.setItem('condo_user', JSON.stringify(res.user)); } }, // Settings getSettings: async (): Promise => { return request('/settings'); }, updateSettings: async (settings: AppSettings): Promise => { return request('/settings', { method: 'PUT', body: JSON.stringify(settings) }); }, testSmtpConfig: async (config: any): Promise => { return request('/settings/smtp-test', { method: 'POST', body: JSON.stringify(config) }); }, getAvailableYears: async (): Promise => { return request('/years'); }, // Condos getCondos: async (): Promise => { return request('/condos'); }, getActiveCondoId: (): string | undefined => { return localStorage.getItem('active_condo_id') || undefined; }, getActiveCondo: async (): Promise => { const id = localStorage.getItem('active_condo_id'); const condos = await CondoService.getCondos(); if (id) { return condos.find(c => c.id === id); } return condos.length > 0 ? condos[0] : undefined; }, setActiveCondo: (id: string) => { localStorage.setItem('active_condo_id', id); window.dispatchEvent(new Event('condo-updated')); window.location.reload(); }, saveCondo: async (condo: Condo): Promise => { if (condo.id) { await request(`/condos/${condo.id}`, { method: 'PUT', body: JSON.stringify(condo) }); return condo; } else { return request('/condos', { method: 'POST', body: JSON.stringify(condo) }); } }, deleteCondo: async (id: string): Promise => { return request(`/condos/${id}`, { method: 'DELETE' }); }, // Families getFamilies: async (condoId?: string): Promise => { let url = '/families'; const activeId = condoId || CondoService.getActiveCondoId(); if (activeId) url += `?condoId=${activeId}`; return request(url); }, addFamily: async (family: any): Promise => { const activeId = CondoService.getActiveCondoId(); return request('/families', { method: 'POST', body: JSON.stringify({ ...family, condoId: activeId }) }); }, updateFamily: async (family: Family): Promise => { return request(`/families/${family.id}`, { method: 'PUT', body: JSON.stringify(family) }); }, deleteFamily: async (id: string): Promise => { return request(`/families/${id}`, { method: 'DELETE' }); }, // Payments seedPayments: () => { /* No-op for real backend */ }, getPaymentsByFamily: async (familyId: string): Promise => { return request(`/payments?familyId=${familyId}`); }, getCondoPayments: async (condoId: string): Promise => { return request(`/payments?condoId=${condoId}`); }, addPayment: async (payment: any): Promise => { return request('/payments', { method: 'POST', body: JSON.stringify(payment) }); }, // Users getUsers: async (condoId?: string): Promise => { let url = '/users'; if (condoId) url += `?condoId=${condoId}`; return request(url); }, createUser: async (user: any): Promise => { return request('/users', { method: 'POST', body: JSON.stringify(user) }); }, updateUser: async (id: string, user: any): Promise => { return request(`/users/${id}`, { method: 'PUT', body: JSON.stringify(user) }); }, deleteUser: async (id: string): Promise => { return request(`/users/${id}`, { method: 'DELETE' }); }, // Alerts getAlerts: async (condoId?: string): Promise => { let url = '/alerts'; if (condoId) url += `?condoId=${condoId}`; return request(url); }, saveAlert: async (alert: AlertDefinition): Promise => { const activeId = CondoService.getActiveCondoId(); if (alert.id) { await request(`/alerts/${alert.id}`, { method: 'PUT', body: JSON.stringify(alert) }); return alert; } else { return request('/alerts', { method: 'POST', body: JSON.stringify({ ...alert, condoId: activeId }) }); } }, deleteAlert: async (id: string): Promise => { return request(`/alerts/${id}`, { method: 'DELETE' }); }, // Notices getNotices: async (condoId?: string): Promise => { let url = '/notices'; const activeId = condoId || CondoService.getActiveCondoId(); if (activeId) url += `?condoId=${activeId}`; return request(url); }, getUnreadNoticesForUser: async (userId: string, condoId: string): Promise => { return request(`/notices/unread?userId=${userId}&condoId=${condoId}`); }, getNoticeReadStatus: async (noticeId: string): Promise => { return request(`/notices/${noticeId}/read-status`); }, markNoticeAsRead: async (noticeId: string, userId: string): Promise => { return request(`/notices/${noticeId}/read`, { method: 'POST', body: JSON.stringify({ userId }) }); }, saveNotice: async (notice: Notice): Promise => { if (notice.id) { return request(`/notices/${notice.id}`, { method: 'PUT', body: JSON.stringify(notice) }); } else { return request('/notices', { method: 'POST', body: JSON.stringify(notice) }); } }, deleteNotice: async (id: string): Promise => { return request(`/notices/${id}`, { method: 'DELETE' }); }, // Tickets getTickets: async (): Promise => { const activeId = CondoService.getActiveCondoId(); return request(`/tickets?condoId=${activeId}`); }, createTicket: async (data: any): Promise => { const activeId = CondoService.getActiveCondoId(); return request('/tickets', { method: 'POST', body: JSON.stringify({ ...data, condoId: activeId }) }); }, updateTicket: async (id: string, data: any): Promise => { return request(`/tickets/${id}`, { method: 'PUT', body: JSON.stringify(data) }); }, deleteTicket: async (id: string): Promise => { return request(`/tickets/${id}`, { method: 'DELETE' }); }, getTicketComments: async (ticketId: string): Promise => { return request(`/tickets/${ticketId}/comments`); }, addTicketComment: async (ticketId: string, text: string): Promise => { return request(`/tickets/${ticketId}/comments`, { method: 'POST', body: JSON.stringify({ text }) }); }, getTicketAttachment: async (ticketId: string, attachmentId: string): Promise => { return request(`/tickets/${ticketId}/attachments/${attachmentId}`); }, // Extraordinary Expenses getExpenses: async (condoId?: string): Promise => { let url = '/expenses'; const activeId = condoId || CondoService.getActiveCondoId(); if (activeId) url += `?condoId=${activeId}`; return request(url); }, getExpenseDetails: async (id: string): Promise => { return request(`/expenses/${id}`); }, createExpense: async (data: any): Promise => { const activeId = CondoService.getActiveCondoId(); if (!activeId) throw new Error("No active condo"); return request('/expenses', { method: 'POST', body: JSON.stringify({ ...data, condoId: activeId }) }); }, updateExpense: async (id: string, data: any): Promise => { return request(`/expenses/${id}`, { method: 'PUT', body: JSON.stringify(data) }); }, deleteExpense: async (id: string): Promise => { return request(`/expenses/${id}`, { method: 'DELETE' }); }, getExpenseAttachment: async (expenseId: string, attachmentId: string): Promise => { return request(`/expenses/${expenseId}/attachments/${attachmentId}`); }, getMyExpenses: async (): Promise => { const activeId = CondoService.getActiveCondoId(); return request(`/my-expenses?condoId=${activeId}`); }, payExpense: async (expenseId: string, amount: number): Promise => { return request(`/expenses/${expenseId}/pay`, { method: 'POST', body: JSON.stringify({ amount, notes: 'PayPal Payment' }) }); } };