import '../models/coupon_model.dart';
import './supabase_service.dart';

class CouponService {
  /// Fetches coupons with auto-reconnection and exact query logic from requirements
  static Future<List<CouponModel>> 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<String> getCategoryOptions() {
    return [
      'Todos',
      'Restaurantes',
      'Tiendas',
      'Servicios',
      'Entretenimiento',
      'Salud',
      'Belleza',
    ];
  }

  /// Gets available sort options (Spanish UI)
  static List<String> getSortOptions() {
    return ['Más recientes', 'Por vencer'];
  }

  /// Gets a single coupon by ID with auto-reconnection
  static Future<CouponModel?> 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<int> 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;
    }
  }
}