import 'package:posyandu/services/api_service.dart'; import 'package:posyandu/models/jadwal_model.dart'; import 'package:http/http.dart' as http; import 'package:shared_preferences/shared_preferences.dart'; import 'dart:convert'; class JadwalService { final ApiService _apiService = ApiService(); // Singleton pattern static final JadwalService _instance = JadwalService._internal(); factory JadwalService() { return _instance; } JadwalService._internal(); /// Mendapatkan semua jadwal (gabungan dari pemeriksaan, imunisasi, dan vitamin) Future> getAllJadwal() async { try { final response = await _apiService.get('jadwal'); final data = response['data']; if (response['status'] == 'success' && data is List) { final jadwalList = data.map((json) => JadwalModel.fromJson(json)).toList(); print('Berhasil mendapatkan ${jadwalList.length} jadwal dari API'); return List.from(jadwalList); } else { print('API mengembalikan status bukan success atau data bukan List: ${response['status']}'); throw Exception(response['message'] ?? 'Gagal mendapatkan data jadwal'); } } catch (e) { print('Error saat mengambil data jadwal: $e'); return []; } } /// Mendapatkan jadwal yang akan datang Future> getUpcomingJadwal() async { try { final response = await _apiService.get('jadwal/upcoming'); final data = response['data']; if (response['status'] == 'success' && data is List) { final jadwalList = data.map((json) => JadwalModel.fromJson(json)).toList(); print('Berhasil mendapatkan ${jadwalList.length} jadwal upcoming dari API'); return List.from(jadwalList); } else { print('API mengembalikan status bukan success atau data bukan List: ${response['status']}'); throw Exception(response['message'] ?? 'Gagal mendapatkan data jadwal upcoming'); } } catch (e) { print('Error saat mengambil data jadwal upcoming: $e'); return []; } } /// Mendapatkan jadwal yang akan datang untuk anak tertentu (filter usia) Future> getUpcomingJadwalForChild(int anakId) async { try { final response = await _apiService.get('jadwal/upcoming/anak/$anakId'); final data = response['data']; if (response['status'] == 'success' && data is List) { final jadwalList = data.map((json) => JadwalModel.fromJson(json)).toList(); print('Berhasil mendapatkan ${jadwalList.length} jadwal upcoming untuk anak $anakId dari API'); return List.from(jadwalList); } else { print('API mengembalikan status bukan success atau data bukan List: ${response['status']}'); throw Exception(response['message'] ?? 'Gagal mendapatkan data jadwal upcoming untuk anak'); } } catch (e) { print('Error saat mengambil data jadwal upcoming untuk anak: $e'); return []; } } /// Mendapatkan riwayat jadwal untuk anak tertentu Future> getRiwayatJadwalAnak(int anakId) async { try { final response = await _apiService.get('jadwal/riwayat/anak/$anakId'); final data = response['data']; if (response['status'] == 'success' && data is List) { final jadwalList = data.map((json) => JadwalModel.fromJson(json)).toList(); print('Berhasil mendapatkan ${jadwalList.length} riwayat jadwal untuk anak $anakId dari API'); return List.from(jadwalList); } else { print('API mengembalikan status bukan success atau data bukan List: ${response['status']}'); throw Exception(response['message'] ?? 'Gagal mendapatkan riwayat jadwal anak'); } } catch (e) { print('Error saat mengambil riwayat jadwal anak: $e'); return []; } } /// Menandai jadwal sebagai selesai Future> markJadwalAsSelesai(int jadwalId, String jenisJadwal) async { try { String endpoint; Map requestData = {'is_implemented': true}; switch (jenisJadwal.toLowerCase()) { case 'pemeriksaan rutin': endpoint = 'jadwal/pemeriksaan/$jadwalId/status'; break; case 'imunisasi': endpoint = 'jadwal/imunisasi/$jadwalId/status'; break; case 'vitamin': endpoint = 'jadwal/vitamin/$jadwalId/status'; break; default: throw Exception('Jenis jadwal tidak dikenali: $jenisJadwal'); } final response = await _apiService.post(endpoint, requestData); if (response['success'] == true) { print('Berhasil menandai jadwal $jadwalId ($jenisJadwal) sebagai selesai'); return { 'status': 'success', 'message': response['message'] ?? 'Jadwal berhasil ditandai sebagai selesai' }; } else { print('API mengembalikan status bukan success: ${response['success']}'); throw Exception(response['message'] ?? 'Gagal menandai jadwal sebagai selesai'); } } catch (e) { print('Error saat menandai jadwal sebagai selesai: $e'); rethrow; } } /// Mendapatkan jadwal terdekat untuk anak tertentu Future getNearestJadwalForChild(int anakId) async { try { final response = await _apiService.get('jadwal/nearest/$anakId'); final data = response['data']; if (response['status'] == 'success' && data != null) { return JadwalModel.fromJson(data); } else { print('Tidak ada jadwal terdekat untuk anak $anakId.'); return null; } } catch (e) { print('Error getNearestJadwalForChild: $e'); return null; } } /// Mendapatkan jadwal baru yang ditambahkan sejak timestamp tertentu /// /// Parameter [lastChecked] adalah timestamp dari waktu pengecekan terakhir /// Format timestamp: 2023-12-31 23:59:59 Future> getNewJadwal(int anakId, String lastChecked) async { try { final response = await _apiService.get( 'jadwal/new/$anakId', queryParameters: {'since': lastChecked} ); final data = response['data']; if (response['status'] == 'success' && data is List) { final jadwalList = data.map((json) => JadwalModel.fromJson(json)).toList(); print('Berhasil mendapatkan ${jadwalList.length} jadwal baru dari API'); return List.from(jadwalList); } else { print('Tidak ada jadwal baru untuk anak $anakId'); return []; } } catch (e) { print('Error saat mengambil jadwal baru: $e'); return []; } } /// Menyimpan tanggal/waktu pengecekan terakhir untuk jadwal baru Future saveLastCheckTime() async { final prefs = await SharedPreferences.getInstance(); final now = DateTime.now().toString(); await prefs.setString('last_jadwal_check', now); print('Waktu cek jadwal terakhir disimpan: $now'); } /// Mendapatkan tanggal/waktu pengecekan terakhir untuk jadwal baru Future getLastCheckTime() async { final prefs = await SharedPreferences.getInstance(); final lastCheck = prefs.getString('last_jadwal_check'); if (lastCheck == null) { // Jika tidak ada timestamp pengecekan terakhir, gunakan 7 hari yang lalu final sevenDaysAgo = DateTime.now().subtract(Duration(days: 7)); return sevenDaysAgo.toString(); } return lastCheck; } }