import 'package:hive/hive.dart'; part 'cycle_entry.g.dart'; /// Mood levels for tracking @HiveType(typeId: 3) enum MoodLevel { @HiveField(0) verySad, @HiveField(1) sad, @HiveField(2) neutral, @HiveField(3) happy, @HiveField(4) veryHappy, } /// Flow intensity for period days @HiveType(typeId: 4) enum FlowIntensity { @HiveField(0) spotting, @HiveField(1) light, @HiveField(2) medium, @HiveField(3) heavy, } /// Cervical mucus type for NFP tracking @HiveType(typeId: 5) enum CervicalMucusType { @HiveField(0) dry, @HiveField(1) sticky, @HiveField(2) creamy, @HiveField(3) eggWhite, @HiveField(4) watery, } /// Cycle phase @HiveType(typeId: 6) enum CyclePhase { @HiveField(0) menstrual, @HiveField(1) follicular, @HiveField(2) ovulation, @HiveField(3) luteal, } /// Daily cycle entry @HiveType(typeId: 7) class CycleEntry extends HiveObject { @HiveField(0) String id; @HiveField(1) DateTime date; @HiveField(2) bool isPeriodDay; @HiveField(3) FlowIntensity? flowIntensity; @HiveField(4) MoodLevel? mood; @HiveField(5) int? energyLevel; // 1-5 @HiveField(6) int? crampIntensity; // 1-5 @HiveField(7) bool hasHeadache; @HiveField(8) bool hasBloating; @HiveField(9) bool hasBreastTenderness; @HiveField(10) bool hasFatigue; @HiveField(11) bool hasAcne; @HiveField(12) double? basalBodyTemperature; // in Fahrenheit @HiveField(13) CervicalMucusType? cervicalMucus; @HiveField(14) bool? ovulationTestPositive; @HiveField(15) String? notes; @HiveField(16) int? sleepHours; @HiveField(17) int? waterIntake; // glasses @HiveField(18) bool hadExercise; @HiveField(19) bool hadIntimacy; // For married users only @HiveField(20) DateTime createdAt; @HiveField(21) DateTime updatedAt; CycleEntry({ required this.id, required this.date, this.isPeriodDay = false, this.flowIntensity, this.mood, this.energyLevel, this.crampIntensity, this.hasHeadache = false, this.hasBloating = false, this.hasBreastTenderness = false, this.hasFatigue = false, this.hasAcne = false, this.basalBodyTemperature, this.cervicalMucus, this.ovulationTestPositive, this.notes, this.sleepHours, this.waterIntake, this.hadExercise = false, this.hadIntimacy = false, required this.createdAt, required this.updatedAt, }); /// Check if any symptoms are logged bool get hasSymptoms => hasHeadache || hasBloating || hasBreastTenderness || hasFatigue || hasAcne || (crampIntensity != null && crampIntensity! > 0); /// Check if NFP data is logged bool get hasNFPData => basalBodyTemperature != null || cervicalMucus != null || ovulationTestPositive != null; /// Get symptom count int get symptomCount { int count = 0; if (hasHeadache) count++; if (hasBloating) count++; if (hasBreastTenderness) count++; if (hasFatigue) count++; if (hasAcne) count++; if (crampIntensity != null && crampIntensity! > 0) count++; return count; } /// Copy with updated fields CycleEntry copyWith({ String? id, DateTime? date, bool? isPeriodDay, FlowIntensity? flowIntensity, MoodLevel? mood, int? energyLevel, int? crampIntensity, bool? hasHeadache, bool? hasBloating, bool? hasBreastTenderness, bool? hasFatigue, bool? hasAcne, double? basalBodyTemperature, CervicalMucusType? cervicalMucus, bool? ovulationTestPositive, String? notes, int? sleepHours, int? waterIntake, bool? hadExercise, bool? hadIntimacy, DateTime? createdAt, DateTime? updatedAt, }) { return CycleEntry( id: id ?? this.id, date: date ?? this.date, isPeriodDay: isPeriodDay ?? this.isPeriodDay, flowIntensity: flowIntensity ?? this.flowIntensity, mood: mood ?? this.mood, energyLevel: energyLevel ?? this.energyLevel, crampIntensity: crampIntensity ?? this.crampIntensity, hasHeadache: hasHeadache ?? this.hasHeadache, hasBloating: hasBloating ?? this.hasBloating, hasBreastTenderness: hasBreastTenderness ?? this.hasBreastTenderness, hasFatigue: hasFatigue ?? this.hasFatigue, hasAcne: hasAcne ?? this.hasAcne, basalBodyTemperature: basalBodyTemperature ?? this.basalBodyTemperature, cervicalMucus: cervicalMucus ?? this.cervicalMucus, ovulationTestPositive: ovulationTestPositive ?? this.ovulationTestPositive, notes: notes ?? this.notes, sleepHours: sleepHours ?? this.sleepHours, waterIntake: waterIntake ?? this.waterIntake, hadExercise: hadExercise ?? this.hadExercise, hadIntimacy: hadIntimacy ?? this.hadIntimacy, createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? DateTime.now(), ); } } /// Extension to get display string for enums extension MoodLevelExtension on MoodLevel { String get emoji { switch (this) { case MoodLevel.verySad: return '😢'; case MoodLevel.sad: return '😕'; case MoodLevel.neutral: return '😐'; case MoodLevel.happy: return '🙂'; case MoodLevel.veryHappy: return '😄'; } } String get label { switch (this) { case MoodLevel.verySad: return 'Very Sad'; case MoodLevel.sad: return 'Sad'; case MoodLevel.neutral: return 'Neutral'; case MoodLevel.happy: return 'Happy'; case MoodLevel.veryHappy: return 'Very Happy'; } } } extension FlowIntensityExtension on FlowIntensity { String get label { switch (this) { case FlowIntensity.spotting: return 'Spotting'; case FlowIntensity.light: return 'Light'; case FlowIntensity.medium: return 'Medium'; case FlowIntensity.heavy: return 'Heavy'; } } } extension CyclePhaseExtension on CyclePhase { String get label { switch (this) { case CyclePhase.menstrual: return 'Menstrual'; case CyclePhase.follicular: return 'Follicular'; case CyclePhase.ovulation: return 'Ovulation'; case CyclePhase.luteal: return 'Luteal'; } } String get emoji { switch (this) { case CyclePhase.menstrual: return '🩸'; case CyclePhase.follicular: return '🌱'; case CyclePhase.ovulation: return '🌸'; case CyclePhase.luteal: return '🌙'; } } String get description { switch (this) { case CyclePhase.menstrual: return 'A time for rest and reflection'; case CyclePhase.follicular: return 'A time of renewal and energy'; case CyclePhase.ovulation: return 'Peak fertility window'; case CyclePhase.luteal: return 'A time for patience and self-care'; } } }