import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:flux/features/customers/models/customer_file_model.dart'; import 'package:get_it/get_it.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import '../models/customer_model.dart'; class CustomerRepository { final SupabaseClient _client = GetIt.I(); // Crea un nuovo cliente Future saveCustomer(CustomerModel customer) async { try { final response = await _client .from('customer') .upsert(customer.toJson()) .select() .single(); return CustomerModel.fromJson(response); } catch (e) { throw 'Errore durante il salvataggio del cliente: $e'; } } Future updateCustomer(CustomerModel customer) async { try { final response = await _client .from('customer') .update(customer.toJson()) .eq('id', customer.id!) .select() .single(); return CustomerModel.fromJson(response); } catch (e) { throw 'Errore durante la modifica del cliente: $e'; } } // Recupera tutti i clienti dell'azienda Future> getCustomers(String companyId) async { try { final response = await _client .from('customer') .select('*, customer_file(count)') .eq('company_id', companyId) .eq('is_active', true) .order('nome'); return (response as List).map((c) => CustomerModel.fromJson(c)).toList(); } catch (e) { throw 'Errore nel recupero clienti'; } } // Ricerca clienti per nome o telefono (fondamentale per la UX) Future> searchCustomers( String companyId, String query, ) async { try { final response = await _client .from('customer') .select() .eq('company_id', companyId) .or('nome.ilike.%$query%,telefono.ilike.%$query%') .limit(10); return (response as List).map((c) => CustomerModel.fromJson(c)).toList(); } catch (e) { return []; } } /// Recupera i file di un cliente specifico Future> getCustomerFiles(String customerId) async { try { final response = await _client .from('customer_file') .select() .eq('customer_id', customerId); return (response as List) .map((f) => CustomerFileModel.fromJson(f)) .toList(); } catch (e) { throw 'Errore recupero file: $e'; } } /// Salva il riferimento del file nel DB Future saveFileReference(CustomerFileModel file) async { await _client.from('customer_file').insert(file.toJson()); } /// Carica un file e salva il riferimento nel database Future uploadAndRegisterFile({ required String customerId, required PlatformFile pickedFile, }) async { try { final user = _client.auth.currentUser; if (user == null) throw 'Utente non autenticato'; final fileName = pickedFile.name; final extension = pickedFile.extension ?? ''; final path = '${user.id}/$customerId/${DateTime.now().millisecondsSinceEpoch}_$fileName'; // Usiamo bytes invece del path per massima compatibilità if (pickedFile.bytes == null && pickedFile.path == null) { throw 'Impossibile leggere il contenuto del file'; } // Se siamo su desktop/mobile abbiamo il path, su web abbiamo i bytes if (pickedFile.bytes != null) { await _client.storage .from('documents') .uploadBinary(path, pickedFile.bytes!); } else { final file = File(pickedFile.path!); await _client.storage.from('documents').upload(path, file); } final String publicUrl = _client.storage .from('documents') .getPublicUrl(path); final fileRecord = CustomerFileModel( customerId: customerId, name: fileName, url: publicUrl, extension: extension, ); final response = await _client .from('customer_file') .insert(fileRecord.toJson()) .select() .single(); return CustomerFileModel.fromJson(response); } catch (e) { throw 'Errore durante l\'upload: $e'; } } /// Aggiorna la lista degli URL nel database Future updateCustomerDocuments(int id, List urls) async { await _client.from('customer').update({'document_urls': urls}).eq('id', id); } /// Elimina un file dallo storage Future deleteDocument(String fullPath) async { // Il path dovrebbe essere ricavato dall'URL final path = fullPath.split('documents/').last; await _client.storage.from('documents').remove([path]); } }