import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:mobile_monitoring/data/services/planting_cycles_service.dart'; import 'package:mobile_monitoring/data/models/service_result.dart'; import 'package:mobile_monitoring/core/utils/cycle_phase_utils.dart'; import 'package:mobile_monitoring/core/utils/phase_display_utils.dart'; class GrowthPhaseService { final PlantingCyclesService _cyclesService; final FirebaseFirestore _firestore; final FirebaseAuth _auth; GrowthPhaseService({ PlantingCyclesService? cyclesService, FirebaseFirestore? firestore, FirebaseAuth? auth, }) : _cyclesService = cyclesService ?? PlantingCyclesService(), _firestore = firestore ?? FirebaseFirestore.instance, _auth = auth ?? FirebaseAuth.instance; String getCurrentUserId() => _auth.currentUser?.uid ?? ''; User? getCurrentUser() => _auth.currentUser; Stream?> activeCycleStream(String userId) { if (userId.isEmpty) { return Stream.value(null); } return _cyclesService.getActiveCycleStream(userId: userId); } DateTime? extractStartDate(Map? cycleData) { return CyclePhaseUtils.extractStartDate(cycleData); } // Calculate phase name based on days since planting String calculateCurrentPhase(int days) { return CyclePhaseUtils.calculateDisplayPhase(days); } // Get phase color Color getPhaseColor(String phase) { return PhaseDisplayUtils.fromName(phase).color; } // Apply alpha to a color Color applyAlpha(Color color, double opacity) { return color.withValues(alpha: (color.a * opacity).clamp(0.0, 1.0)); } // Format date for display (e.g., "5 Mei 2024") String formatDate(DateTime date) { return CyclePhaseUtils.formatIndonesianDate(date); } // Get phase data (duration, progress) for a given days count Map getPhaseData(int daysSincePlanting) { final progressData = PhaseDisplayUtils.progressData(daysSincePlanting); return { 'day': progressData.dayInPhase, 'duration': progressData.phaseDuration, 'progress': progressData.progress, }; } Future> savePlantingDate({ required String userId, required DateTime plantingDate, }) async { if (userId.isEmpty) { return ServiceResult.failure( message: 'User tidak terautentikasi', errorCode: 'unauthenticated', ); } try { final days = DateTime.now().difference(plantingDate).inDays; final phase = calculateCurrentPhase(days); await _cyclesService.addCycle(userId: userId, startDate: plantingDate); await _createPhaseSnapshot( userId: userId, phase: phase, daysSincePlanting: days, ); return ServiceResult.success(message: 'Tanggal tanam disimpan'); } catch (e) { return ServiceResult.failure( message: 'Gagal menyimpan tanggal tanam: $e', errorCode: 'save_cycle_failed', ); } } Future> resetCycle(String userId) async { if (userId.isEmpty) { return ServiceResult.failure( message: 'User tidak terautentikasi', errorCode: 'unauthenticated', ); } try { await _cyclesService.deleteCycle(userId: userId); return ServiceResult.success(message: 'Siklus direset'); } catch (e) { return ServiceResult.failure( message: 'Gagal reset siklus: $e', errorCode: 'reset_failed', ); } } Future> markHarvest(String userId) async { if (userId.isEmpty) { return ServiceResult.failure( message: 'User tidak terautentikasi', errorCode: 'unauthenticated', ); } try { // Hitung total hari siklus sebelum menghapus final daysSincePlanting = await _cyclesService .calculateCycleDaysBeforeDelete(userId: userId); // Catat snapshot panen untuk historikal await _createPhaseSnapshot( userId: userId, phase: 'Panen', daysSincePlanting: daysSincePlanting, ); // Hapus siklus aktif setelah panen dicatat await _cyclesService.deleteCycle(userId: userId); return ServiceResult.success(message: 'Panen dicatat, siklus selesai'); } catch (e) { return ServiceResult.failure( message: 'Gagal mencatat panen: $e', errorCode: 'harvest_failed', ); } } Future updatePhaseIfChanged({ required String userId, required String currentPhaseInDb, required String calculatedPhase, required int days, required DateTime startDate, }) async { if (currentPhaseInDb == calculatedPhase) return; await _cyclesService.updateCycleProgress( userId: userId, startDate: startDate, ); await _createPhaseSnapshot( userId: userId, phase: calculatedPhase, daysSincePlanting: days, ); } Future _createPhaseSnapshot({ required String userId, required String phase, int? daysSincePlanting, }) async { await _firestore.collection('hidroponik_data').add({ 'user_id': userId, 'growth_phase': phase, if (daysSincePlanting != null) 'days_since_planting': daysSincePlanting, 'pH_value': 0.0, 'nutrient_level': 0.0, 'pump_ph_up_status': false, 'pump_ph_down_status': false, 'pump_nutrient_status': false, 'pump_water_status': false, 'timestamp': FieldValue.serverTimestamp(), }); } }