enum HealthReminderMetric { bloodPressure, heartRate, glucose, spo2, weight }

extension HealthReminderMetricX on HealthReminderMetric {
  String get label => switch (this) {
    HealthReminderMetric.bloodPressure => '血压',
    HealthReminderMetric.heartRate => '心率',
    HealthReminderMetric.glucose => '血糖',
    HealthReminderMetric.spo2 => '血氧',
    HealthReminderMetric.weight => '体重',
  };

  String get backendField => switch (this) {
    HealthReminderMetric.bloodPressure => 'healthRecordReminderBloodPressure',
    HealthReminderMetric.heartRate => 'healthRecordReminderHeartRate',
    HealthReminderMetric.glucose => 'healthRecordReminderGlucose',
    HealthReminderMetric.spo2 => 'healthRecordReminderSpO2',
    HealthReminderMetric.weight => 'healthRecordReminderWeight',
  };
}

class NotificationPrefs {
  final bool pushEnabled;
  final bool medicationReminder;
  final bool followUpReminder;
  final bool doctorReply;
  final bool abnormalAlert;
  final bool dndEnabled;
  final int dndStartMinutes;
  final int dndEndMinutes;
  final bool healthRecordReminder;
  final Set<HealthReminderMetric> enabledHealthMetrics;

  const NotificationPrefs({
    required this.pushEnabled,
    required this.medicationReminder,
    required this.followUpReminder,
    required this.doctorReply,
    required this.abnormalAlert,
    required this.dndEnabled,
    required this.dndStartMinutes,
    required this.dndEndMinutes,
    required this.healthRecordReminder,
    required this.enabledHealthMetrics,
  });

  factory NotificationPrefs.fromJson(Map<dynamic, dynamic> json) {
    final metrics = <HealthReminderMetric>{};
    for (final metric in HealthReminderMetric.values) {
      if ((json[metric.backendField] as bool?) ?? true) metrics.add(metric);
    }
    return NotificationPrefs(
      pushEnabled: (json['pushEnabled'] as bool?) ?? true,
      medicationReminder: (json['medicationReminder'] as bool?) ?? true,
      followUpReminder: (json['followUpReminder'] as bool?) ?? true,
      doctorReply: (json['doctorReply'] as bool?) ?? false,
      abnormalAlert: (json['abnormalAlert'] as bool?) ?? true,
      dndEnabled: (json['dndEnabled'] as bool?) ?? false,
      dndStartMinutes: (json['dndStartMinutes'] as num?)?.toInt() ?? 22 * 60,
      dndEndMinutes: (json['dndEndMinutes'] as num?)?.toInt() ?? 8 * 60,
      healthRecordReminder: (json['healthRecordReminder'] as bool?) ?? true,
      enabledHealthMetrics: Set.unmodifiable(metrics),
    );
  }
}

class NotificationPrefsViewState {
  final NotificationPrefs? prefs;
  final bool loading;
  final String? loadError;
  final Set<String> savingKeys;

  const NotificationPrefsViewState({
    this.prefs,
    this.loading = false,
    this.loadError,
    this.savingKeys = const {},
  });

  NotificationPrefsViewState copyWith({
    NotificationPrefs? prefs,
    bool? loading,
    String? loadError,
    bool clearLoadError = false,
    Set<String>? savingKeys,
  }) => NotificationPrefsViewState(
    prefs: prefs ?? this.prefs,
    loading: loading ?? this.loading,
    loadError: clearLoadError ? null : loadError ?? this.loadError,
    savingKeys: savingKeys ?? this.savingKeys,
  );
}

String healthMetricSummary(Set<HealthReminderMetric> metrics) {
  if (metrics.isEmpty) return '至少选择一项';
  if (metrics.length == HealthReminderMetric.values.length) return '全部指标';
  return HealthReminderMetric.values
      .where(metrics.contains)
      .map((metric) => metric.label)
      .join('、');
}

Map<String, bool> healthMetricUpdatePayload(
  Set<HealthReminderMetric> metrics,
) => {
  for (final metric in HealthReminderMetric.values)
    metric.backendField: metrics.contains(metric),
};
