import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:intl/intl.dart'; import '../../../data/services/myquran_sholat_service.dart'; import '../../../data/services/prayer_service.dart'; import '../../../data/services/location_service.dart'; import '../../../data/local/hive_boxes.dart'; import '../../../data/local/models/app_settings.dart'; /// Represents a single prayer time entry. class PrayerTimeEntry { final String name; final String time; // "HH:mm" final bool isActive; PrayerTimeEntry({ required this.name, required this.time, this.isActive = false, }); } /// Full day prayer schedule from myQuran API. class DaySchedule { final String cityName; final String province; final String date; // yyyy-MM-dd final String tanggal; // formatted date from API final Map times; // {imsak, subuh, terbit, dhuha, dzuhur, ashar, maghrib, isya} DaySchedule({ required this.cityName, required this.province, required this.date, required this.tanggal, required this.times, }); /// Is this schedule for tomorrow? bool get isTomorrow { final todayStr = DateFormat('yyyy-MM-dd').format(DateTime.now()); return date.compareTo(todayStr) > 0; } /// Get prayer time entries as a list. List get prayerList { final now = DateTime.now(); final formatter = DateFormat('HH:mm'); final currentTime = formatter.format(now); final prayers = [ PrayerTimeEntry(name: 'Imsak', time: times['imsak'] ?? '-'), PrayerTimeEntry(name: 'Subuh', time: times['subuh'] ?? '-'), PrayerTimeEntry(name: 'Terbit', time: times['terbit'] ?? '-'), PrayerTimeEntry(name: 'Dhuha', time: times['dhuha'] ?? '-'), PrayerTimeEntry(name: 'Dzuhur', time: times['dzuhur'] ?? '-'), PrayerTimeEntry(name: 'Ashar', time: times['ashar'] ?? '-'), PrayerTimeEntry(name: 'Maghrib', time: times['maghrib'] ?? '-'), PrayerTimeEntry(name: 'Isya', time: times['isya'] ?? '-'), ]; // Find the next prayer int activeIndex = -1; if (isTomorrow) { // User specifically requested to show tomorrow's Subuh as upcoming activeIndex = 1; // 0=Imsak, 1=Subuh } else { for (int i = 0; i < prayers.length; i++) { if (prayers[i].time != '-' && prayers[i].time.compareTo(currentTime) > 0) { activeIndex = i; break; } } } if (activeIndex >= 0) { prayers[activeIndex] = PrayerTimeEntry( name: prayers[activeIndex].name, time: prayers[activeIndex].time, isActive: true, ); } return prayers; } /// Get the next prayer name and time. PrayerTimeEntry? get nextPrayer { final list = prayerList; for (final p in list) { if (p.isActive) return p; } // If none active and it's today, all prayers have passed return null; } } /// Default Jakarta city ID from myQuran API. const _defaultCityId = '58a2fc6ed39fd083f55d4182bf88826d'; /// Provider for the user's selected city ID (stored in Hive settings). final selectedCityIdProvider = StateProvider((ref) { final box = Hive.box(HiveBoxes.settings); final settings = box.get('default'); final stored = settings?.lastCityName ?? ''; if (stored.contains('|')) { return stored.split('|').last; } return _defaultCityId; }); /// Provider for today's prayer times using myQuran API. final prayerTimesProvider = FutureProvider((ref) async { final cityId = ref.watch(selectedCityIdProvider); final today = DateFormat('yyyy-MM-dd').format(DateTime.now()); DaySchedule? schedule; // Try API first final jadwal = await MyQuranSholatService.instance.getDailySchedule(cityId, today); if (jadwal != null) { final cityInfo = await MyQuranSholatService.instance.getCityInfo(cityId); schedule = DaySchedule( cityName: cityInfo?['kabko'] ?? 'Jakarta', province: cityInfo?['prov'] ?? 'DKI Jakarta', date: today, tanggal: jadwal['tanggal'] ?? today, times: jadwal, ); } // Check if all prayers today have passed if (schedule != null && !schedule.isTomorrow && schedule.nextPrayer == null) { // All prayers passed, fetch tomorrow's schedule final tomorrow = DateTime.now().add(const Duration(days: 1)); final tomorrowStr = DateFormat('yyyy-MM-dd').format(tomorrow); final tmrwJadwal = await MyQuranSholatService.instance.getDailySchedule(cityId, tomorrowStr); if (tmrwJadwal != null) { final cityInfo = await MyQuranSholatService.instance.getCityInfo(cityId); schedule = DaySchedule( cityName: cityInfo?['kabko'] ?? 'Jakarta', province: cityInfo?['prov'] ?? 'DKI Jakarta', date: tomorrowStr, tanggal: tmrwJadwal['tanggal'] ?? tomorrowStr, times: tmrwJadwal, ); } } if (schedule != null) { return schedule; } // Fallback to adhan package final position = await LocationService.instance.getCurrentLocation(); double lat = position?.latitude ?? -6.2088; double lng = position?.longitude ?? 106.8456; final result = PrayerService.instance.getPrayerTimes(lat, lng, DateTime.now()); if (result != null) { final timeFormat = DateFormat('HH:mm'); return DaySchedule( cityName: 'Jakarta', province: 'DKI Jakarta', date: today, tanggal: DateFormat('EEEE, dd/MM/yyyy').format(DateTime.now()), times: { 'imsak': timeFormat.format(result.fajr.subtract(const Duration(minutes: 10))), 'subuh': timeFormat.format(result.fajr), 'terbit': timeFormat.format(result.sunrise), 'dhuha': timeFormat.format(result.sunrise.add(const Duration(minutes: 15))), 'dzuhur': timeFormat.format(result.dhuhr), 'ashar': timeFormat.format(result.asr), 'maghrib': timeFormat.format(result.maghrib), 'isya': timeFormat.format(result.isha), }, ); } return null; }); /// Provider for monthly prayer schedule (for Imsakiyah screen). final monthlyScheduleProvider = FutureProvider.family>, String>( (ref, month) async { final cityId = ref.watch(selectedCityIdProvider); return MyQuranSholatService.instance.getMonthlySchedule(cityId, month); }); /// Provider for current city name. final cityNameProvider = FutureProvider((ref) async { final box = Hive.box(HiveBoxes.settings); final settings = box.get('default'); final stored = settings?.lastCityName ?? ''; if (stored.contains('|')) { return stored.split('|').first; } final cityId = ref.watch(selectedCityIdProvider); final info = await MyQuranSholatService.instance.getCityInfo(cityId); if (info != null) { return '${info['kabko']}, ${info['prov']}'; } return 'Kota Jakarta, DKI Jakarta'; });