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(4)
  none, // No flow / Precautionary

  @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<String>? 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;

  @HiveField(32)
  String? prayerRequest;

  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,
    this.prayerRequest,
  });

  List<bool> 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<String>? cravings,
    int? sleepHours,
    int? waterIntake,
    bool? hadExercise,
    bool? hadIntimacy,
    bool? intimacyProtected,
    DateTime? createdAt,
    DateTime? updatedAt,
    String? husbandNotes,
    bool? usedPantyliner,
    int? pantylinerCount,
    String? prayerRequest,
  }) {
    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,
      prayerRequest: prayerRequest ?? this.prayerRequest,
    );
  }
}

/// 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.none:
        return 'No Flow';
      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<Color> get gradientColors {
    switch (this) {
      case CyclePhase.menstrual:
        return [AppColors.rose, AppColors.menstrualPhase, AppColors.blushPink];
      case CyclePhase.follicular:
        return [
          AppColors.sageGreen,
          AppColors.follicularPhase,
          AppColors.sageGreen.withValues(alpha: 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';
    }
  }
}
