/** * Request Service - Platform-aware money request management * Uses Firebase abstraction layer for cross-platform support */ import { doc, collection, FieldValue } from '../firebase'; import { withGlobalLoading } from '../stores/uiStore'; export interface MoneyRequest { id?: string; requestorName: string; requesteeName: string; requestorPhoneNumber: string; requesteePhoneNumber: string; requestorType: 'saved' | 'contact'; amount: number; note?: string; notificationMethod: 'SMS' | 'WhatsApp'; status: 'pending' | 'accepted' | 'declined' | 'expired'; createdAt: Date; updatedAt: Date; } export class RequestService { private static snapshotExists(docSnap: any): boolean { const existsValue = docSnap?.exists; if (typeof existsValue === 'function') { try { return !!existsValue.call(docSnap); } catch { return false; } } return !!existsValue; } /** * Find user UID by phone number */ static async findUserByPhoneNumber(phoneNumber: string): Promise { try { const usersCollection = collection('users'); const querySnapshot = await usersCollection .where('phoneNumber', '==', phoneNumber) .get(); if (querySnapshot.empty) { return null; } return querySnapshot.docs[0].id; } catch (error) { console.error('Error finding user by phone number:', error); return null; } } /** * Get user details by phone number */ static async getUserByPhoneNumber(phoneNumber: string): Promise<{ success: boolean; user?: { uid: string; displayName: string; phoneNumber: string }; error?: string }> { try { const usersCollection = collection('users'); const querySnapshot = await usersCollection .where('phoneNumber', '==', phoneNumber) .get(); if (querySnapshot.empty) { return { success: false, error: 'User not found' }; } const userDoc = querySnapshot.docs[0]; const userData = userDoc.data(); return { success: true, user: { uid: userDoc.id, displayName: userData.displayName || userData.name || 'Unknown', phoneNumber: userData.phoneNumber } }; } catch (error) { console.error('Error getting user by phone number:', error); return { success: false, error: error instanceof Error ? error.message : 'Failed to get user' }; } } /** * Get request by ID */ static async getRequestById(requestId: string): Promise<{ success: boolean; request?: MoneyRequest; error?: string }> { try { const requestRef = doc('requests', requestId); const requestSnapshot = await requestRef.get(); if (!RequestService.snapshotExists(requestSnapshot)) { return { success: false, error: 'Request not found' }; } const requestData = requestSnapshot.data() as any; const request: MoneyRequest = { id: requestSnapshot.id, requestorName: requestData.requestorName, requesteeName: requestData.requesteeName, requestorPhoneNumber: requestData.requestorPhoneNumber, requesteePhoneNumber: requestData.requesteePhoneNumber, requestorType: requestData.requestorType, amount: requestData.amount, note: requestData.note, notificationMethod: requestData.notificationMethod || 'SMS', status: requestData.status, createdAt: requestData.createdAt?.toDate?.() || new Date(), updatedAt: requestData.updatedAt?.toDate?.() || new Date(), }; return { success: true, request }; } catch (error) { console.error('Error getting request by ID:', error); return { success: false, error: error instanceof Error ? error.message : 'Failed to get request' }; } } /** * Update request status */ static async updateRequestStatus( requestId: string, status: 'pending' | 'accepted' | 'declined' | 'expired' ): Promise<{ success: boolean; error?: string }> { return withGlobalLoading(async () => { try { const requestRef = doc('requests', requestId); await requestRef.update({ status, updatedAt: FieldValue.serverTimestamp(), }); return { success: true, }; } catch (error) { console.error('Error updating request status:', error); return { success: false, error: error instanceof Error ? error.message : 'Failed to update request status', }; } }); } /** * Create a new money request */ static async createRequest( uid: string, requestData: Omit ): Promise<{ success: boolean; requestId?: string; error?: string }> { return withGlobalLoading(async () => { try { // Generate a unique request ID const requestId = `request_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; const request = { ...requestData, uid, createdAt: FieldValue.serverTimestamp(), updatedAt: FieldValue.serverTimestamp(), }; const requestRef = doc('requests', requestId); await requestRef.set(request); return { success: true, requestId, }; } catch (error) { console.error('Error creating money request:', error); return { success: false, error: error instanceof Error ? error.message : 'Failed to create request', }; } }); } }