import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:my_attendance/models/attendance_entry.dart'; import 'package:my_attendance/utils/database_helper.dart'; class AttendanceService with ChangeNotifier { final DatabaseHelper _dbHelper = DatabaseHelper(); AttendanceEntry? _todayEntry; AttendanceEntry? get todayEntry => _todayEntry; List _history = []; List get history => _history; Map _monthlyStats = {}; Map get monthlyStats => _monthlyStats; Map _yearlyStats = {}; Map get yearlyStats => _yearlyStats; bool _isLoading = true; bool get isLoading => _isLoading; AttendanceService() { loadTodayEntry(); } Future logIn() async { _isLoading = true; notifyListeners(); try { final now = DateTime.now(); final date = DateTime(now.year, now.month, now.day); final entry = AttendanceEntry( date: date, loginTime: now, entryType: EntryType.work, ); final id = await _dbHelper.insertAttendance(entry); _todayEntry = entry.copyWith(id: id); } catch (e) { debugPrint("Error logging in: $e"); } finally { _isLoading = false; notifyListeners(); } } Future logOut() async { if (_todayEntry == null || _todayEntry!.logoutTime != null) return; _isLoading = true; notifyListeners(); try { final now = DateTime.now(); final updatedEntry = _todayEntry!.copyWith(logoutTime: now); await _dbHelper.updateAttendance(updatedEntry); _todayEntry = updatedEntry; } catch (e) { debugPrint("Error logging out: $e"); } finally { _isLoading = false; notifyListeners(); } } Future loadTodayEntry() async { _isLoading = true; notifyListeners(); try { final now = DateTime.now(); final date = DateTime(now.year, now.month, now.day); _todayEntry = await _dbHelper.getAttendanceForDate(date); } catch (e) { debugPrint("Error loading today's entry: $e"); } finally { _isLoading = false; notifyListeners(); } } Future loadHistory({int limit = 10}) async { _isLoading = true; notifyListeners(); try { _history = await _dbHelper.getAttendanceHistory(limit: limit); } catch (e) { debugPrint("Error loading history: $e"); } finally { _isLoading = false; notifyListeners(); } } Future updateNotes(int entryId, String notes) async { try { AttendanceEntry? entryToUpdate; if (_todayEntry?.id == entryId) { entryToUpdate = _todayEntry; } else { entryToUpdate = _history.firstWhere((e) => e.id == entryId); } if (entryToUpdate != null) { final updated = entryToUpdate.copyWith(notes: notes); await _dbHelper.updateAttendance(updated); await loadTodayEntry(); await loadHistory(); await calculateStats(); } } catch (e) { debugPrint("Error updating notes: $e"); } } Future markAsWfh() async { _isLoading = true; notifyListeners(); try { final now = DateTime.now(); final date = DateTime(now.year, now.month, now.day); final entry = AttendanceEntry(date: date, entryType: EntryType.wfh); final id = await _dbHelper.insertAttendance(entry); _todayEntry = entry.copyWith(id: id); await calculateStats(); } catch (e) { debugPrint("Error marking as WFH: $e"); } finally { _isLoading = false; notifyListeners(); } } Future markAsLeave(LeaveType leaveType) async { _isLoading = true; notifyListeners(); try { final now = DateTime.now(); final date = DateTime(now.year, now.month, now.day); final entry = AttendanceEntry( date: date, entryType: EntryType.leave, leaveType: leaveType, ); final id = await _dbHelper.insertAttendance(entry); _todayEntry = entry.copyWith(id: id); await calculateStats(); } catch (e) { debugPrint("Error marking as leave: $e"); } finally { _isLoading = false; notifyListeners(); } } Future resetData() async { _isLoading = true; notifyListeners(); try { await _dbHelper.resetDatabase(); _todayEntry = null; _history = []; await calculateStats(); } catch (e) { debugPrint("Error resetting data: $e"); } finally { _isLoading = false; notifyListeners(); } } Future updateOrCreateEntry(AttendanceEntry entry) async { final existingEntry = await _dbHelper.getAttendanceForDate(entry.date); if (existingEntry != null) { // Preserve the original ID when updating await _dbHelper.updateAttendance(entry.copyWith(id: existingEntry.id)); } else { await _dbHelper.insertAttendance(entry); } // Refresh data to reflect changes await loadTodayEntry(); await loadHistory(); await calculateStats(); } Future getEntryForDate(DateTime date) async { return await _dbHelper.getAttendanceForDate(date); } Future calculateStats() async { final now = DateTime.now(); // Monthly stats final monthStart = DateTime(now.year, now.month, 1); final monthEnd = DateTime(now.year, now.month + 1, 0); final monthlyEntries = await _dbHelper.getAttendanceInRange( monthStart, monthEnd, ); _monthlyStats = _calculateCounts(monthlyEntries); // Yearly stats final yearStart = DateTime(now.year, 1, 1); final yearEnd = DateTime(now.year, 12, 31); final yearlyEntries = await _dbHelper.getAttendanceInRange( yearStart, yearEnd, ); _yearlyStats = _calculateCounts(yearlyEntries); notifyListeners(); } Map _calculateCounts(List entries) { final counts = {}; for (final entry in entries) { if (entry.entryType == EntryType.wfh) { counts['Work From Home'] = (counts['Work From Home'] ?? 0) + 1; } else if (entry.entryType == EntryType.leave) { final leaveName = _getLeaveTypeName(entry.leaveType); counts[leaveName] = (counts[leaveName] ?? 0) + 1; } } return counts; } String _getLeaveTypeName(LeaveType? type) { switch (type) { case LeaveType.sick: return 'Sick Leave'; case LeaveType.annual: return 'Annual Leave'; case LeaveType.nationalHoliday: return 'National Holiday'; case LeaveType.companyWfh: return 'Company WFH'; default: return 'On Leave'; } } }