/// A training program. Deload weeks are scheduled and enforced — training
/// through a deload logs as non-compliance, same as skipping.
class Program {
  String? id;

  String name;

  int weeks;

  int sessionsPerWeek;

  /// 1-based week indices that are deloads.
  List<int> deloadWeeks;

  /// Weekly ceiling on plyometric ground contacts. Plyo is the one modality
  /// where the app stops you rather than pushes you.
  int weeklyContactCeiling;

  /// Mandatory hours between high-intensity lower-body sessions.
  int lowerBodyRecoveryHours;

  bool active;

  Program({
    this.id,
    this.name = "",
    this.weeks = 0,
    this.sessionsPerWeek = 0,
    List<int>? deloadWeeks,
    this.weeklyContactCeiling = 0,
    this.lowerBodyRecoveryHours = 48,
    this.active = false,
  }) : deloadWeeks = deloadWeeks ?? <int>[];

  factory Program.fromJson(Map<String, dynamic> json) {
    return Program(
      id: json['id'],
      name: json['name'] ?? "",
      weeks: json['weeks'] ?? 0,
      sessionsPerWeek: json['sessionsPerWeek'] ?? 0,
      deloadWeeks: json['deloadWeeks'] == null
          ? <int>[]
          : (json['deloadWeeks'] as List).map((item) => item as int).toList(),
      weeklyContactCeiling: json['weeklyContactCeiling'] ?? 0,
      lowerBodyRecoveryHours: json['lowerBodyRecoveryHours'] ?? 48,
      active: json['active'] ?? false,
    );
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['id'] = id;
    data['name'] = name;
    data['weeks'] = weeks;
    data['sessionsPerWeek'] = sessionsPerWeek;
    data['deloadWeeks'] = deloadWeeks;
    data['weeklyContactCeiling'] = weeklyContactCeiling;
    data['lowerBodyRecoveryHours'] = lowerBodyRecoveryHours;
    data['active'] = active;
    return data;
  }

  bool isDeloadWeek(int week) {
    return deloadWeeks.contains(week);
  }
}
