import { doc, setDoc, getDoc, updateDoc, deleteDoc } from 'firebase/firestore'; import { db } from './firebase'; import { processImage, validateImageFile, generateUniqueFileName, ProcessedImage } from '../utils/imageUtils'; export interface StoredImage { id: string; dataUrl: string; filename: string; originalSize: number; compressedSize: number; uploadedAt: number; width: number; height: number; } /** * Upload and store an image in Firestore * @param file - The image file to upload * @param collectionName - Firestore collection name (e.g., 'company-logos') * @param documentId - Document ID (e.g., orgId) * @param maxWidth - Maximum width for resizing (default: 128) * @param maxHeight - Maximum height for resizing (default: 128) * @returns Promise with stored image data */ export const uploadImage = async ( file: File, collectionName: string, documentId: string, maxWidth: number = 128, maxHeight: number = 128 ): Promise => { if (!db) { throw new Error('Firebase not initialized'); } // Validate the image file const validation = validateImageFile(file); if (!validation.valid) { throw new Error(validation.error); } // Process the image const processedImage: ProcessedImage = await processImage(file, maxWidth, maxHeight); // Generate unique filename const filename = generateUniqueFileName(file.name, 'logo'); // Create image data to store const imageData: StoredImage = { id: filename, dataUrl: processedImage.dataUrl, filename, originalSize: processedImage.originalSize, compressedSize: processedImage.compressedSize, uploadedAt: Date.now(), width: processedImage.width, height: processedImage.height, }; // Store in Firestore const docRef = doc(db, collectionName, documentId); try { // Get existing document to preserve other data const existingDoc = await getDoc(docRef); if (existingDoc.exists()) { // Update existing document await updateDoc(docRef, { logo: imageData, updatedAt: Date.now(), }); } else { // Create new document await setDoc(docRef, { logo: imageData, createdAt: Date.now(), updatedAt: Date.now(), }); } return imageData; } catch (error) { console.error('Failed to store image in Firestore:', error); throw new Error('Failed to upload image'); } }; /** * Retrieve an image from Firestore * @param collectionName - Firestore collection name * @param documentId - Document ID * @returns Promise with stored image data or null if not found */ export const getImage = async ( collectionName: string, documentId: string ): Promise => { if (!db) { throw new Error('Firebase not initialized'); } try { const docRef = doc(db, collectionName, documentId); const docSnap = await getDoc(docRef); if (docSnap.exists()) { const data = docSnap.data(); return data.logo || null; } return null; } catch (error) { console.error('Failed to retrieve image from Firestore:', error); return null; } }; /** * Delete an image from Firestore * @param collectionName - Firestore collection name * @param documentId - Document ID * @returns Promise indicating success */ export const deleteImage = async ( collectionName: string, documentId: string ): Promise => { if (!db) { throw new Error('Firebase not initialized'); } try { const docRef = doc(db, collectionName, documentId); const docSnap = await getDoc(docRef); if (docSnap.exists()) { const data = docSnap.data(); if (data.logo) { // Remove only the logo field, keep other data const updatedData = { ...data }; delete updatedData.logo; updatedData.updatedAt = Date.now(); await updateDoc(docRef, updatedData); return true; } } return false; } catch (error) { console.error('Failed to delete image from Firestore:', error); return false; } }; /** * Company-specific image upload (convenience function) */ export const uploadCompanyLogo = async ( file: File, orgId: string ): Promise => { return uploadImage(file, 'company-logos', orgId, 128, 128); }; /** * Get company logo (convenience function) */ export const getCompanyLogo = async (orgId: string): Promise => { return getImage('company-logos', orgId); }; /** * Delete company logo (convenience function) */ export const deleteCompanyLogo = async (orgId: string): Promise => { return deleteImage('company-logos', orgId); };