Amba-Agent-App/lib/services/requestService.ts
2026-01-16 00:22:35 +03:00

196 lines
5.5 KiB
TypeScript

/**
* 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<string | null> {
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<MoneyRequest, 'id' | 'createdAt' | 'updatedAt'>
): 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',
};
}
});
}
}