import 'package:firebase_database/firebase_database.dart'; import '../models/threshold_model.dart'; import 'notification_service.dart'; class ThresholdService { static const String kontrolPath = 'kontrol_1'; static final DatabaseReference _dbRef = FirebaseDatabase.instance.ref(); // Get semua threshold dari Firebase static Future> getAllThreshold() async { try { final snapshot = await _dbRef.child(kontrolPath).get(); if (!snapshot.exists) { return []; } final data = snapshot.value as Map?; if (data == null) return []; // Filter hanya yang key-nya dimulai dengan 'threshold_' final thresholdList = []; data.forEach((key, value) { if (key.toString().startsWith('threshold_') && value is Map) { try { final threshold = ThresholdModel.fromJson( key.toString(), Map.from(value), ); thresholdList.add(threshold); } catch (e) { print('Error parsing threshold $key: $e'); } } }); // Sort by ID (threshold_1, threshold_2, ...) thresholdList.sort((a, b) { final numA = int.tryParse(a.id.replaceAll('threshold_', '')) ?? 0; final numB = int.tryParse(b.id.replaceAll('threshold_', '')) ?? 0; return numA.compareTo(numB); }); return thresholdList; } catch (e) { print('Error getting all threshold: $e'); return []; } } // Save threshold (create atau update) static Future saveThreshold(ThresholdModel threshold) async { try { await _dbRef .child(kontrolPath) .child(threshold.id) .set(threshold.toJson()); return true; } catch (e) { print('Error saving threshold: $e'); return false; } } // Delete threshold static Future deleteThreshold(String id) async { try { await _dbRef.child(kontrolPath).child(id).remove(); return true; } catch (e) { print('Error deleting threshold: $e'); return false; } } // Toggle threshold aktif/nonaktif static Future toggleThresholdAktif(String id, bool aktif) async { try { await _dbRef.child(kontrolPath).child(id).child('aktif').set(aktif); return true; } catch (e) { print('Error toggling threshold: $e'); return false; } } // Duplicate threshold dengan ID baru static Future duplicateThreshold(ThresholdModel threshold) async { try { final allThresholds = await getAllThreshold(); // Cari ID tertinggi int maxId = 0; for (var t in allThresholds) { final num = int.tryParse(t.id.replaceAll('threshold_', '')) ?? 0; if (num > maxId) maxId = num; } final newId = 'threshold_${maxId + 1}'; final newThreshold = threshold.copyWith( id: newId, aktif: false, // Duplikat dimulai dengan nonaktif ); final success = await saveThreshold(newThreshold); return success ? newId : null; } catch (e) { print('Error duplicating threshold: $e'); return null; } } // Get single threshold by ID static Future getThreshold(String id) async { try { final snapshot = await _dbRef.child(kontrolPath).child(id).get(); if (!snapshot.exists) return null; final data = snapshot.value as Map?; if (data == null) return null; return ThresholdModel.fromJson(id, data); } catch (e) { print('Error getting threshold: $e'); return null; } } // Watch semua threshold (real-time stream) static Stream> watchAllThreshold() { return _dbRef.child(kontrolPath).onValue.map((event) { if (!event.snapshot.exists) return []; final data = event.snapshot.value as Map?; if (data == null) return []; final thresholdList = []; data.forEach((key, value) { if (key.toString().startsWith('threshold_') && value is Map) { try { final threshold = ThresholdModel.fromJson( key.toString(), Map.from(value), ); thresholdList.add(threshold); } catch (e) { print('Error parsing threshold $key: $e'); } } }); // Sort by ID thresholdList.sort((a, b) { final numA = int.tryParse(a.id.replaceAll('threshold_', '')) ?? 0; final numB = int.tryParse(b.id.replaceAll('threshold_', '')) ?? 0; return numA.compareTo(numB); }); return thresholdList; }); } // Cek apakah ada range yang overlap dengan threshold lain static Future isRangeOverlap( String currentId, int batasBawah, int batasAtas, List potAktif, ) async { try { final allThresholds = await getAllThreshold(); for (var threshold in allThresholds) { // Skip threshold yang sama if (threshold.id == currentId) continue; // Cek apakah ada pot yang sama final hasSamePot = threshold.potAktif.any( (pot) => potAktif.contains(pot), ); if (!hasSamePot) continue; // Cek apakah range overlap final rangeOverlap = !(batasAtas < threshold.batasBawah || batasBawah > threshold.batasAtas); if (rangeOverlap) return true; } return false; } catch (e) { print('Error checking range overlap: $e'); return false; } } // Get next available threshold ID static Future getNextThresholdId() async { try { final allThresholds = await getAllThreshold(); if (allThresholds.isEmpty) return 'threshold_1'; // Cari ID tertinggi int maxId = 0; for (var t in allThresholds) { final num = int.tryParse(t.id.replaceAll('threshold_', '')) ?? 0; if (num > maxId) maxId = num; } return 'threshold_${maxId + 1}'; } catch (e) { print('Error getting next threshold ID: $e'); return 'threshold_1'; } } // Get sensor mode status (otomatis) static Future getSensorModeStatus() async { try { final snapshot = await _dbRef.child(kontrolPath).child('otomatis').get(); return snapshot.value as bool? ?? false; } catch (e) { print('Error getting sensor mode status: $e'); return false; } } // Set sensor mode status (otomatis) static Future setSensorModeStatus(bool enabled) async { try { await _dbRef.child(kontrolPath).child('otomatis').set(enabled); print('✅ Sensor mode set to ${enabled ? "enabled" : "disabled"}'); await NotificationService.instance.showModeChangedNotification( modeLabel: 'otomatis berbasis sensor', enabled: enabled, ); return true; } catch (e) { print('❌ Error setting sensor mode: $e'); return false; } } }