// lib/features/events/services/events_service.dart
import '../../../core/api/api_client.dart';
import '../../../core/api/api_endpoints.dart';
import '../models/event_models.dart';

class EventsService {
  final ApiClient _api = ApiClient();

  // ---------------------------------------------------------------------------
  // In-memory caches with TTL
  // ---------------------------------------------------------------------------
  static List<EventTypeModel>? _cachedTypes;
  static DateTime? _typesCacheTime;
  static const _typesCacheTTL = Duration(minutes: 30);

  static List<EventModel>? _cachedAllEvents;
  static DateTime? _eventsCacheTime;
  static const _eventsCacheTTL = Duration(minutes: 5);

  /// Get event types (POST to /events/type-list/)
  /// Cached for 30 minutes since event types rarely change.
  Future<List<EventTypeModel>> getEventTypes() async {
    if (_cachedTypes != null &&
        _typesCacheTime != null &&
        DateTime.now().difference(_typesCacheTime!) < _typesCacheTTL) {
      return _cachedTypes!;
    }

    final res = await _api.post(ApiEndpoints.eventTypes, requiresAuth: false);
    final list = <EventTypeModel>[];
    final data = res['event_types'] ?? res;
    if (data is List) {
      for (final e in data) {
        if (e is Map<String, dynamic>) list.add(EventTypeModel.fromJson(e));
      }
    }

    _cachedTypes = list;
    _typesCacheTime = DateTime.now();
    return list;
  }

  /// Get events filtered by pincode with pagination.
  /// [page] starts at 1. [pageSize] defaults to 50.
  /// Returns a list of events for the requested page.
  Future<List<EventModel>> getEventsByPincode(String pincode, {int page = 1, int pageSize = 50, int perType = 5}) async {
    // Use cache for 'all' pincode queries (first page only for initial load)
    if (pincode == 'all' &&
        page == 1 &&
        _cachedAllEvents != null &&
        _eventsCacheTime != null &&
        DateTime.now().difference(_eventsCacheTime!) < _eventsCacheTTL) {
      return _cachedAllEvents!;
    }

    final Map<String, dynamic> body = {'pincode': pincode, 'page': page, 'page_size': pageSize};
    // Diverse mode: fetch a few events per type so all categories are represented
    if (perType > 0 && page == 1) body['per_type'] = perType;

    final res = await _api.post(
      ApiEndpoints.eventsByPincode,
      body: body,
      requiresAuth: false,
    );
    final list = <EventModel>[];
    final events = res['events'] ?? res['data'] ?? [];
    if (events is List) {
      for (final e in events) {
        if (e is Map<String, dynamic>) list.add(EventModel.fromJson(Map<String, dynamic>.from(e)));
      }
    }

    if (pincode == 'all' && page == 1) {
      _cachedAllEvents = list;
      _eventsCacheTime = DateTime.now();
    }
    return list;
  }

  /// Event details — requiresAuth: false so guests can fetch full details
  Future<EventModel> getEventDetails(int eventId) async {
    final res = await _api.post(ApiEndpoints.eventDetails, body: {'event_id': eventId}, requiresAuth: false);
    return EventModel.fromJson(Map<String, dynamic>.from(res));
  }

  /// Events by month and year for calendar (POST to /events/events-by-month-year/)
  Future<Map<String, dynamic>> getEventsByMonthYear(String month, int year) async {
    final res = await _api.post(ApiEndpoints.eventsByMonth, body: {'month': month, 'year': year}, requiresAuth: false);
    return res;
  }

  /// Convenience: get events for a specific date (YYYY-MM-DD).
  /// Uses the cached events list when available to avoid redundant API calls.
  Future<List<EventModel>> getEventsForDate(String date) async {
    final all = await getEventsByPincode('all');
    return all.where((e) {
      try {
        return e.startDate == date ||
            e.endDate == date ||
            (DateTime.parse(e.startDate).isBefore(DateTime.parse(date)) &&
                DateTime.parse(e.endDate).isAfter(DateTime.parse(date)));
      } catch (_) {
        return false;
      }
    }).toList();
  }
}
