import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import '../theme/app_theme.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, defaultValue: false) bool isPeriodDay; @HiveField(3) FlowIntensity? flowIntensity; @HiveField(4) MoodLevel? mood; @HiveField(5) int? energyLevel; // 1-5 @HiveField(6) int? crampIntensity; // 1-5 @HiveField(7, defaultValue: false) bool hasHeadache; @HiveField(8, defaultValue: false) bool hasBloating; @HiveField(9, defaultValue: false) bool hasBreastTenderness; @HiveField(10, defaultValue: false) bool hasFatigue; @HiveField(11, defaultValue: false) bool hasAcne; @HiveField(22, defaultValue: false) bool hasLowerBackPain; @HiveField(23, defaultValue: false) bool hasConstipation; @HiveField(24, defaultValue: false) bool hasDiarrhea; @HiveField(25) int? stressLevel; // 1-5 @HiveField(26, defaultValue: false) bool hasInsomnia; @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, defaultValue: false) bool hadExercise; @HiveField(19, defaultValue: false) bool hadIntimacy; // For married users only @HiveField(20) DateTime createdAt; @HiveField(21) DateTime updatedAt; @HiveField(27) List? cravings; @HiveField(28) String? husbandNotes; // Separate notes for husband @HiveField(29) bool? intimacyProtected; // null = no selection, true = protected, false = unprotected @HiveField(30, defaultValue: false) bool usedPantyliner; @HiveField(31, defaultValue: 0) int pantylinerCount; 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.hasLowerBackPain = false, this.hasConstipation = false, this.hasDiarrhea = false, this.stressLevel, this.hasInsomnia = false, this.basalBodyTemperature, this.cervicalMucus, this.ovulationTestPositive, this.notes, this.cravings, this.sleepHours, this.waterIntake, this.hadExercise = false, this.hadIntimacy = false, this.intimacyProtected, required this.createdAt, required this.updatedAt, this.husbandNotes, this.usedPantyliner = false, this.pantylinerCount = 0, }); List get _symptomsList => [ hasHeadache, hasBloating, hasBreastTenderness, hasFatigue, hasAcne, hasLowerBackPain, hasConstipation, hasDiarrhea, hasInsomnia, (crampIntensity != null && crampIntensity! > 0), (stressLevel != null && stressLevel! > 1), ]; /// Check if any symptoms are logged bool get hasSymptoms => _symptomsList.contains(true); /// Check if NFP data is logged bool get hasNFPData => basalBodyTemperature != null || cervicalMucus != null || ovulationTestPositive != null; /// Get symptom count int get symptomCount => _symptomsList.where((s) => s).length; // ... (omitted getters) /// 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, bool? hasLowerBackPain, bool? hasConstipation, bool? hasDiarrhea, int? stressLevel, bool? hasInsomnia, double? basalBodyTemperature, CervicalMucusType? cervicalMucus, bool? ovulationTestPositive, String? notes, List? cravings, int? sleepHours, int? waterIntake, bool? hadExercise, bool? hadIntimacy, bool? intimacyProtected, DateTime? createdAt, DateTime? updatedAt, String? husbandNotes, bool? usedPantyliner, int? pantylinerCount, }) { 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, hasLowerBackPain: hasLowerBackPain ?? this.hasLowerBackPain, hasConstipation: hasConstipation ?? this.hasConstipation, hasDiarrhea: hasDiarrhea ?? this.hasDiarrhea, stressLevel: stressLevel ?? this.stressLevel, hasInsomnia: hasInsomnia ?? this.hasInsomnia, basalBodyTemperature: basalBodyTemperature ?? this.basalBodyTemperature, cervicalMucus: cervicalMucus ?? this.cervicalMucus, ovulationTestPositive: ovulationTestPositive ?? this.ovulationTestPositive, notes: notes ?? this.notes, cravings: cravings ?? this.cravings, sleepHours: sleepHours ?? this.sleepHours, waterIntake: waterIntake ?? this.waterIntake, hadExercise: hadExercise ?? this.hadExercise, hadIntimacy: hadIntimacy ?? this.hadIntimacy, intimacyProtected: intimacyProtected ?? this.intimacyProtected, createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? DateTime.now(), husbandNotes: husbandNotes ?? this.husbandNotes, usedPantyliner: usedPantyliner ?? this.usedPantyliner, pantylinerCount: pantylinerCount ?? this.pantylinerCount, ); } } /// 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 'Regular'; 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 '🌙'; } } Color get color { switch (this) { case CyclePhase.menstrual: return AppColors.menstrualPhase; case CyclePhase.follicular: return AppColors.follicularPhase; case CyclePhase.ovulation: return AppColors.ovulationPhase; case CyclePhase.luteal: return AppColors.lutealPhase; } } List get gradientColors { switch (this) { case CyclePhase.menstrual: return [AppColors.rose, AppColors.menstrualPhase, AppColors.blushPink]; case CyclePhase.follicular: return [ AppColors.sageGreen, AppColors.follicularPhase, AppColors.sageGreen.withOpacity(0.7) ]; case CyclePhase.ovulation: return [AppColors.lavender, AppColors.ovulationPhase, AppColors.rose]; case CyclePhase.luteal: return [ AppColors.lutealPhase, AppColors.lavender, AppColors.blushPink ]; } } 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'; } } }