import '../models/coupon_model.dart'; import './supabase_service.dart'; class CouponService { /// Fetches coupons with auto-reconnection and exact query logic from requirements static Future> getCoupons({ String? selectedCategory, String? sort, }) async { return await SupabaseService.withAutoReconnect(() async { final client = SupabaseService.client; // Exact query from requirements specification var query = client .from('coupons') .select( 'id, business_name, title, description, valid_until, image_url, category, is_active, created_at', ); // Apply the exact WHERE conditions from requirements query = query.eq('is_active', true); // Handle date filter: (valid_until IS NULL OR valid_until >= CURRENT_DATE) final currentDate = DateTime.now().toIso8601String().split('T')[0]; query = query.or('valid_until.is.null,valid_until.gte.$currentDate'); // Category filter: ignore when 'Todos' is selected if (selectedCategory != null && selectedCategory != 'Todos') { final categoryValue = _mapDisplayCategoryToDbValue(selectedCategory); query = query.eq('category', categoryValue); } // Apply sorting based on requirements final dynamic response; if (sort == 'Por vencer') { // Sort by expiring first (null values last) response = await query.order('valid_until', ascending: true, nullsFirst: false); } else { // Default: "Más recientes" - sort by created_at descending response = await query.order('created_at', ascending: false); } return (response as List) .map((data) => CouponModel.fromMap(data)) .toList(); }); } /// Maps display category names to database enum values static String _mapDisplayCategoryToDbValue(String displayCategory) { switch (displayCategory.toLowerCase()) { case 'restaurantes': return 'restaurantes'; case 'tiendas': return 'tiendas'; case 'servicios': return 'servicios'; case 'entretenimiento': return 'entretenimiento'; case 'salud': return 'salud'; case 'belleza': return 'belleza'; default: return 'restaurantes'; // fallback } } /// Gets available category options for filtering (Spanish UI) static List getCategoryOptions() { return [ 'Todos', 'Restaurantes', 'Tiendas', 'Servicios', 'Entretenimiento', 'Salud', 'Belleza', ]; } /// Gets available sort options (Spanish UI) static List getSortOptions() { return ['Más recientes', 'Por vencer']; } /// Gets a single coupon by ID with auto-reconnection static Future getCouponById(String id) async { try { return await SupabaseService.withAutoReconnect(() async { final client = SupabaseService.client; final response = await client .from('coupons') .select( 'id, business_name, title, description, valid_until, image_url, category, is_active, created_at', ) .eq('id', id) .eq('is_active', true) .single(); return CouponModel.fromMap(response); }); } catch (e) { // Silent failure - return null return null; } } /// Counts total coupons for a category with auto-reconnection static Future getCouponCount({String? category}) async { try { return await SupabaseService.withAutoReconnect(() async { final client = SupabaseService.client; var query = client.from('coupons').select('id').eq('is_active', true); if (category != null && category.toLowerCase() != 'todos') { final categoryValue = _mapDisplayCategoryToDbValue(category); query = query.eq('category', categoryValue); } final response = await query.count(); return response.count ?? 0; }); } catch (e) { // Silent failure - return 0 return 0; } } }