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<DateTime> 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<DateTime> generateFullSchedule() {
    final schedules = <DateTime>[];
    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일 초과
}