import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:uuid/uuid.dart'; import '../main.dart'; /// Handles uploading / deleting car images in Supabase Storage. /// /// Bucket: `car-images` (public, but URLs are unguessable) /// Path: `cars/{uuid}.jpg` — random UUID per image. /// /// Shared garage — any authenticated user can upload / replace / delete. class StorageService { StorageService._(); static const _bucket = 'car-images'; static const _uuid = Uuid(); /// Upload a photo from [file]. /// /// If [oldImageUrl] is provided the previous file is deleted first. /// Returns the public URL on success, or `null` on failure. static Future uploadCarImage({ required File file, String? oldImageUrl, }) async { try { // Clean up old image if re-uploading. if (oldImageUrl != null) { await _deleteByUrl(oldImageUrl); } final path = 'cars/${_uuid.v4()}.jpg'; await supabase.storage.from(_bucket).upload( path, file, fileOptions: const FileOptions( contentType: 'image/jpeg', ), ); // Return the public URL. final url = supabase.storage.from(_bucket).getPublicUrl(path); return url; } catch (e) { debugPrint('StorageService.uploadCarImage error: $e'); return null; } } /// Delete the image at the given public [imageUrl]. static Future deleteCarImage(String? imageUrl) async { if (imageUrl == null || imageUrl.isEmpty) return; await _deleteByUrl(imageUrl); } /// Extract the storage path from a public URL and remove the file. static Future _deleteByUrl(String imageUrl) async { try { // Public URLs look like: // .../storage/v1/object/public/car-images/cars/.jpg final marker = '/object/public/$_bucket/'; final idx = imageUrl.indexOf(marker); if (idx == -1) return; final path = imageUrl.substring(idx + marker.length); await supabase.storage.from(_bucket).remove([path]); } catch (e) { debugPrint('StorageService._deleteByUrl error: $e'); } } }