import 'package:freezed_annotation/freezed_annotation.dart'; part 'maintenance_schedule.freezed.dart'; @freezed class MaintenanceSchedule with _$MaintenanceSchedule { const MaintenanceSchedule._(); const factory MaintenanceSchedule({ required int equipmentHistoryId, required String maintenanceType, required int periodMonths, required DateTime startDate, required DateTime endDate, DateTime? lastMaintenanceDate, DateTime? nextMaintenanceDate, required double cost, String? description, @Default([]) List scheduledDates, @Default(MaintenanceScheduleStatus.active) MaintenanceScheduleStatus status, }) = _MaintenanceSchedule; // 다음 유지보수 날짜 계산 DateTime calculateNextMaintenanceDate() { final lastDate = lastMaintenanceDate ?? startDate; return lastDate.add(Duration(days: periodMonths * 30)); } // 남은 일수 계산 int getDaysUntilNextMaintenance() { final next = nextMaintenanceDate ?? calculateNextMaintenanceDate(); return next.difference(DateTime.now()).inDays; } // 만료 여부 확인 bool isOverdue() { final daysUntil = getDaysUntilNextMaintenance(); return daysUntil < 0; } // 곧 만료 예정 여부 확인 (30일 이내) bool isUpcoming({int daysThreshold = 30}) { final daysUntil = getDaysUntilNextMaintenance(); return daysUntil >= 0 && daysUntil <= daysThreshold; } // 전체 스케줄 생성 List generateFullSchedule() { final schedules = []; var currentDate = startDate; while (currentDate.isBefore(endDate)) { schedules.add(currentDate); currentDate = currentDate.add(Duration(days: periodMonths * 30)); } return schedules; } // 남은 유지보수 횟수 계산 int getRemainingMaintenanceCount() { final now = DateTime.now(); final schedules = generateFullSchedule(); return schedules.where((date) => date.isAfter(now)).length; } // 총 비용 계산 double getTotalCost() { final totalCount = generateFullSchedule().length; return cost * totalCount; } // 남은 비용 계산 double getRemainingCost() { return cost * getRemainingMaintenanceCount(); } } enum MaintenanceScheduleStatus { active, // 활성 paused, // 일시중지 completed,// 완료 cancelled // 취소 } // 유지보수 알림 설정 @freezed class MaintenanceAlert with _$MaintenanceAlert { const MaintenanceAlert._(); const factory MaintenanceAlert({ required int maintenanceId, required int equipmentHistoryId, required String equipmentName, required DateTime scheduledDate, required String maintenanceType, required int daysUntil, required AlertPriority priority, String? description, double? estimatedCost, }) = _MaintenanceAlert; // Backward compatibility getter int get daysUntilDue => daysUntil; factory MaintenanceAlert.fromSchedule( MaintenanceSchedule schedule, String equipmentName, ) { final daysUntil = schedule.getDaysUntilNextMaintenance(); final priority = _getPriority(daysUntil); return MaintenanceAlert( maintenanceId: 0, // Will be set from actual maintenance equipmentHistoryId: schedule.equipmentHistoryId, equipmentName: equipmentName, scheduledDate: schedule.nextMaintenanceDate ?? schedule.calculateNextMaintenanceDate(), maintenanceType: schedule.maintenanceType, daysUntil: daysUntil, priority: priority, description: schedule.description, ); } static AlertPriority _getPriority(int daysUntil) { if (daysUntil < 0) return AlertPriority.critical; if (daysUntil <= 7) return AlertPriority.high; if (daysUntil <= 30) return AlertPriority.medium; return AlertPriority.low; } } enum AlertPriority { critical, // 만료됨 high, // 7일 이내 medium, // 30일 이내 low // 30일 초과 }