import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../models/vitamin_model.dart'; import '../services/vitamin_service.dart'; class VitaminController { final VitaminService _vitaminService = VitaminService(); List _vitaminList = []; Map? _anakData; int? anakId; bool _isLoading = false; String? _error; // Key for caching data static const String _cacheKeyPrefix = 'vitamin_data_'; static const String _anakDataCacheKeyPrefix = 'anak_data_'; // Getters List get vitaminList => _vitaminList; Map? get anakData => _anakData; bool get isLoading => _isLoading; String? get error => _error; // Constructor VitaminController() { // Tidak perlu inisialisasi data default } // Fetch vitamin data for a specific child Future fetchVitaminData(int childId) async { _isLoading = true; _error = null; anakId = childId; try { // Cek dulu apakah anak ada try { await fetchAnakData(childId); } catch (e) { _isLoading = false; throw Exception('Silakan tambahkan data anak terlebih dahulu'); } final vitaminData = await _vitaminService.getVitaminByAnakId(childId); _vitaminList = vitaminData.map((data) { return Vitamin( id: data['id'] ?? 0, jenis: data['jenis_vitamin']?['nama'] ?? 'Tidak diketahui', tanggal: data['tanggal'] ?? '', status: data['status'] ?? 'Belum', lokasi: data['lokasi'] ?? 'Posyandu', usia: data['usia'] ?? 'Tidak diketahui', color: _getColorForVitamin(data['jenis_vitamin']?['nama'] ?? ''), deskripsi: data['deskripsi'] ?? 'Tidak ada deskripsi', manfaat: data['manfaat'] ?? 'Tidak ada informasi manfaat', ); }).toList(); _isLoading = false; } catch (e) { print('Error fetching vitamin data: $e'); _isLoading = false; _error = e.toString(); _vitaminList = []; throw e; } } // Fetch anak data Future fetchAnakData(int childId) async { try { _anakData = await _vitaminService.getAnakData(childId); } catch (e) { _anakData = null; throw e; } } // Update vitamin status Future updateVitaminStatus(int vitaminId, String newStatus) async { try { final updatedVitamin = await _vitaminService.updateVitaminStatus( vitaminId, newStatus ); // Update local list final index = _vitaminList.indexWhere((v) => v.id == vitaminId); if (index != -1) { _vitaminList[index] = Vitamin.fromJson(updatedVitamin); } // Update cache if (anakId != null) { await _refreshCachedVitaminData(anakId!); } return true; } catch (e) { print('Error updating vitamin status: $e'); return false; } } // Get count by status int getCountByStatus(String status) { if (_vitaminList.isEmpty) return 0; try { if (status == 'Sudah') { return _vitaminList.where((v) => v.status == 'Sudah' || v.status.toLowerCase().contains('sudah') || v.status.toLowerCase().contains('selesai') ).length; } return _vitaminList.where((v) => v.status == status).length; } catch (e) { print('Error in getCountByStatus: $e'); return 0; } } // Get child age from anak data String getChildAge() { if (_anakData == null) return ''; if (_anakData!.containsKey('umur_bulan') && _anakData!['umur_bulan'] != null) { return '${_anakData!['umur_bulan']} bulan'; } if (_anakData!.containsKey('umur_hari') && _anakData!['umur_hari'] != null) { final hari = _anakData!['umur_hari']; if (hari >= 30) { final bulan = (hari / 30).floor(); return '$bulan bulan'; } return '$hari hari'; } return ''; } // Helper method to get color based on vitamin type Color _getColorForVitamin(String jenis) { if (jenis.isEmpty) return Colors.grey; switch (jenis.toLowerCase()) { case 'vitamin a': case 'a biru': case 'a merah': return Colors.orange.shade700; case 'vitamin b': case 'b kompleks': return Colors.green.shade700; case 'vitamin c': return Colors.yellow.shade700; case 'vitamin d': return Colors.purple.shade700; case 'zat besi': return Colors.red.shade700; default: return Colors.blue.shade700; } } // Cache vitamin data Future _cacheVitaminData(int childId, List data) async { try { final prefs = await SharedPreferences.getInstance(); final cacheKey = '$_cacheKeyPrefix$childId'; // Convert data to JSON string final dataStr = jsonEncode(data); // Save to SharedPreferences await prefs.setString(cacheKey, dataStr); print('Cached vitamin data for child ID: $childId'); } catch (e) { print('Error caching vitamin data: $e'); } } // Get cached vitamin data Future?> _getCachedVitaminData(int childId) async { try { final prefs = await SharedPreferences.getInstance(); final cacheKey = '$_cacheKeyPrefix$childId'; final dataStr = prefs.getString(cacheKey); if (dataStr != null) { // Parse the string back to list of maps return jsonDecode(dataStr) as List; } return null; } catch (e) { print('Error retrieving cached vitamin data: $e'); return null; } } // Update cached vitamin data after a change Future _refreshCachedVitaminData(int childId) async { try { final apiData = await _vitaminService.getVitaminByAnakId(childId); await _cacheVitaminData(childId, apiData); } catch (e) { print('Error refreshing cached vitamin data: $e'); } } // Cache anak data Future _cacheAnakData(int childId, Map data) async { try { final prefs = await SharedPreferences.getInstance(); final cacheKey = '$_anakDataCacheKeyPrefix$childId'; // Convert data to JSON string final dataStr = jsonEncode(data); // Save to SharedPreferences await prefs.setString(cacheKey, dataStr); print('Cached anak data for child ID: $childId'); } catch (e) { print('Error caching anak data: $e'); } } // Get cached anak data Future?> _getCachedAnakData(int childId) async { try { final prefs = await SharedPreferences.getInstance(); final cacheKey = '$_anakDataCacheKeyPrefix$childId'; final dataStr = prefs.getString(cacheKey); if (dataStr != null) { // Parse the string back to map return jsonDecode(dataStr) as Map; } return null; } catch (e) { print('Error retrieving cached anak data: $e'); return null; } } }