/// What the user can realistically absorb, learned from history rather than
/// asserted. Drives the capacity block at plan time.
class CapacityProfile {
  /// p50 of historically completed minutes, keyed by weekday (1 = Monday).
  Map<int, double> completedMinutesByWeekday;

  /// Per-category estimation multiplier — you say 30min, you take 70min -> 2.3.
  Map<String, double> estimationMultipliers;

  CapacityProfile({
    Map<int, double>? completedMinutesByWeekday,
    Map<String, double>? estimationMultipliers,
  })  : completedMinutesByWeekday = completedMinutesByWeekday ?? <int, double>{},
        estimationMultipliers = estimationMultipliers ?? <String, double>{};

  factory CapacityProfile.fromJson(Map<String, dynamic> json) {
    final Map<int, double> minutes = <int, double>{};
    if (json['completedMinutesByWeekday'] != null) {
      (json['completedMinutesByWeekday'] as Map<String, dynamic>)
          .forEach((key, value) {
        minutes[int.tryParse(key) ?? 1] = (value ?? 0).toDouble();
      });
    }

    final Map<String, double> multipliers = <String, double>{};
    if (json['estimationMultipliers'] != null) {
      (json['estimationMultipliers'] as Map<String, dynamic>)
          .forEach((key, value) {
        multipliers[key] = (value ?? 1).toDouble();
      });
    }

    return CapacityProfile(
      completedMinutesByWeekday: minutes,
      estimationMultipliers: multipliers,
    );
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['completedMinutesByWeekday'] = completedMinutesByWeekday
        .map((key, value) => MapEntry(key.toString(), value));
    data['estimationMultipliers'] = estimationMultipliers;
    return data;
  }

  /// The learned multiplier for a category, defaulting to honest 1.0 until
  /// there is enough history to say otherwise.
  double multiplierFor(String category) {
    return estimationMultipliers[category] ?? 1.0;
  }

  /// The p50 of what actually gets done on this weekday.
  double capacityFor(int weekday) {
    return completedMinutesByWeekday[weekday] ?? 0;
  }
}
