import 'package:hive/hive.dart';
import 'teaching_plan.dart';

part 'user_profile.g.dart';

/// User's relationship status
@HiveType(typeId: 0)
enum RelationshipStatus {
  @HiveField(0)
  single,

  @HiveField(1)
  engaged,

  @HiveField(2)
  married,
}

/// Fertility tracking goal for married users
@HiveType(typeId: 1)
enum FertilityGoal {
  @HiveField(0)
  tryingToConceive, // TTC

  @HiveField(1)
  tryingToAvoid, // TTA - NFP

  @HiveField(2)
  justTracking,
}

@HiveType(typeId: 9)
enum BibleTranslation {
  @HiveField(0)
  esv,
  @HiveField(1)
  niv,
  @HiveField(2)
  nkjv,
  @HiveField(3)
  nlt,
  @HiveField(4)
  nasb,
  @HiveField(5)
  kjv,
  @HiveField(6)
  msg,
}

@HiveType(typeId: 11)
enum AppThemeMode {
  @HiveField(0)
  system,
  @HiveField(1)
  light,
  @HiveField(2)
  dark,
}

@HiveType(typeId: 13)
enum PadType {
  @HiveField(0)
  pantyLiner,
  @HiveField(1)
  regular,
  @HiveField(2)
  superPad,
  @HiveField(3)
  overnight,
  @HiveField(4)
  tamponRegular,
  @HiveField(5)
  tamponSuper,
  @HiveField(6)
  menstrualCup,
  @HiveField(7)
  menstrualDisc,
  @HiveField(8)
  periodUnderwear,
}

extension PadTypeExtension on PadType {
  String get label {
    switch (this) {
      case PadType.pantyLiner:
        return 'Liner';
      case PadType.regular:
        return 'Regular Pad';
      case PadType.superPad:
        return 'Super Pad';
      case PadType.overnight:
        return 'Overnight';
      case PadType.tamponRegular:
        return 'Tampon (Regular)';
      case PadType.tamponSuper:
        return 'Tampon (Super)';
      case PadType.menstrualCup:
        return 'Cup';
      case PadType.menstrualDisc:
        return 'Disc';
      case PadType.periodUnderwear:
        return 'Period Underwear';
    }
  }
}

@HiveType(typeId: 12)
class SupplyItem extends HiveObject {
  @HiveField(0)
  String brand;
  @HiveField(1)
  PadType type;
  @HiveField(2)
  int absorbency; // 1-5
  @HiveField(3)
  int count;

  SupplyItem({
    required this.brand,
    required this.type,
    required this.absorbency,
    required this.count,
  });

  SupplyItem copyWith({
    String? brand,
    PadType? type,
    int? absorbency,
    int? count,
  }) {
    return SupplyItem(
      brand: brand ?? this.brand,
      type: type ?? this.type,
      absorbency: absorbency ?? this.absorbency,
      count: count ?? this.count,
    );
  }
}

/// User profile model
@HiveType(typeId: 2)
class UserProfile extends HiveObject {
  @HiveField(0)
  String id;

  @HiveField(1)
  String name;

  @HiveField(2, defaultValue: RelationshipStatus.single)
  RelationshipStatus relationshipStatus;

  @HiveField(3)
  FertilityGoal? fertilityGoal;

  @HiveField(4, defaultValue: 28)
  int averageCycleLength;

  @HiveField(5, defaultValue: 5)
  int averagePeriodLength;

  @HiveField(6)
  DateTime? lastPeriodStartDate;

  @HiveField(7)
  DateTime? lastPadChangeTime;

  @HiveField(8, defaultValue: true)
  bool notificationsEnabled;

  @HiveField(9, defaultValue: false)
  bool hasCompletedOnboarding;

  @HiveField(10)
  DateTime createdAt;

  @HiveField(11)
  DateTime updatedAt;

  @HiveField(12)
  String? partnerName; // For married users

  @HiveField(14, defaultValue: UserRole.wife)
  UserRole role;

  @HiveField(15, defaultValue: false)
  bool isIrregularCycle;

  @HiveField(41, defaultValue: 21)
  int minCycleLength;

  @HiveField(42, defaultValue: 40)
  int maxCycleLength;

  @HiveField(16, defaultValue: BibleTranslation.esv)
  BibleTranslation bibleTranslation;

  @HiveField(17)
  List<String>? favoriteFoods;

  @HiveField(18, defaultValue: false)
  bool isDataShared;

  @HiveField(19, defaultValue: AppThemeMode.system)
  AppThemeMode themeMode;

  @HiveField(20, defaultValue: '0xFFA8C5A8')
  String accentColor;

  // Sharing settings
  @HiveField(21, defaultValue: true)
  bool shareMoods;

  @HiveField(22, defaultValue: true)
  bool shareSymptoms;

  @HiveField(23, defaultValue: true)
  bool shareCravings;

  @HiveField(24, defaultValue: true)
  bool shareEnergyLevels;

  @HiveField(25, defaultValue: true)
  bool shareSleep;

  @HiveField(26, defaultValue: true)
  bool shareIntimacy;

  // Pad Tracking
  @HiveField(27, defaultValue: false)
  bool isPadTrackingEnabled;

  @HiveField(28)
  int? typicalFlowIntensity; // 1-5

  @HiveField(29)
  String? padBrand;

  @HiveField(30)
  int? padAbsorbency; // 1-5 scale

  @HiveField(31, defaultValue: 0)
  int padInventoryCount;

  @HiveField(32, defaultValue: 5)
  int lowInventoryThreshold;

  @HiveField(33, defaultValue: true)
  bool isAutoInventoryEnabled;

  @HiveField(34)
  DateTime? lastInventoryUpdate;

  @HiveField(38)
  List<SupplyItem>? padSupplies;

  // Granular Notification Settings
  @HiveField(35, defaultValue: true)
  bool notifyPeriodEstimate;

  @HiveField(36, defaultValue: true)
  bool notifyPeriodStart;

  @HiveField(37, defaultValue: true)
  bool notifyLowSupply;

  @HiveField(39, defaultValue: true)
  bool showPadTimerMinutes;

  @HiveField(40, defaultValue: false)
  bool showPadTimerSeconds;

  @HiveField(43, defaultValue: false)
  bool notifyPad1Hour;

  @HiveField(44, defaultValue: false)
  bool notifyPad2Hours;

  @HiveField(45)
  String? privacyPin;

  @HiveField(46, defaultValue: false)
  bool isBioProtected;

  @HiveField(47, defaultValue: false)
  bool isHistoryProtected;

  @HiveField(48, defaultValue: false)
  bool notifyPad30Mins;

  @HiveField(49, defaultValue: true)
  bool notifyPadNow;

  @HiveField(50, defaultValue: false)
  bool isLogProtected;

  @HiveField(51, defaultValue: false)
  bool isCalendarProtected;

  @HiveField(52, defaultValue: false)
  bool isSuppliesProtected;

  @HiveField(53)
  List<TeachingPlan>? teachingPlans;

  // Husband-specific theme settings
  @HiveField(54, defaultValue: AppThemeMode.system)
  AppThemeMode husbandThemeMode;

  @HiveField(55, defaultValue: '0xFF1A3A5C')
  String husbandAccentColor;

  // Whether to use example/demo data (for husband not connected to wife)
  @HiveField(56, defaultValue: false)
  bool useExampleData;

  UserProfile({
    required this.id,
    required this.name,
    this.relationshipStatus = RelationshipStatus.single,
    this.fertilityGoal,
    this.averageCycleLength = 28,
    this.averagePeriodLength = 5,
    this.lastPeriodStartDate,
    this.notificationsEnabled = true,
    this.hasCompletedOnboarding = false,
    required this.createdAt,
    required this.updatedAt,
    this.partnerName,
    this.role = UserRole.wife,
    this.isIrregularCycle = false,
    this.minCycleLength = 21,
    this.maxCycleLength = 40,
    this.bibleTranslation = BibleTranslation.esv,
    this.favoriteFoods,
    this.isDataShared = false,
    this.themeMode = AppThemeMode.system,
    this.accentColor = '0xFFA8C5A8',
    this.shareMoods = true,
    this.shareSymptoms = true,
    this.shareCravings = true,
    this.shareEnergyLevels = true,
    this.shareSleep = true,
    this.shareIntimacy = true,
    this.isPadTrackingEnabled = false,
    this.typicalFlowIntensity,
    this.padBrand,
    this.padAbsorbency,
    this.padInventoryCount = 0,
    this.lowInventoryThreshold = 5,
    this.isAutoInventoryEnabled = true,
    this.lastInventoryUpdate,
    this.notifyPeriodEstimate = true,
    this.notifyPeriodStart = true,
    this.notifyLowSupply = true,
    this.lastPadChangeTime,
    this.padSupplies,
    this.showPadTimerMinutes = true,
    this.showPadTimerSeconds = false,
    this.notifyPad1Hour = false,
    this.notifyPad2Hours = false,
    this.privacyPin,
    this.isBioProtected = false,
    this.isHistoryProtected = false,
    this.notifyPad30Mins = false,
    this.notifyPadNow = true,
    this.isLogProtected = false,
    this.isCalendarProtected = false,
    this.isSuppliesProtected = false,
    this.teachingPlans,
    this.husbandThemeMode = AppThemeMode.system,
    this.husbandAccentColor = '0xFF1A3A5C',
    this.useExampleData = false,
  });

  /// Check if user is married
  bool get isMarried => relationshipStatus == RelationshipStatus.married;

  /// Check if user is trying to conceive
  bool get isTTC => fertilityGoal == FertilityGoal.tryingToConceive;

  /// Check if user is practicing NFP
  bool get isNFP => fertilityGoal == FertilityGoal.tryingToAvoid;

  /// Check if user is husband
  bool get isHusband => role == UserRole.husband;

  /// Should show fertility content
  bool get showFertilityContent =>
      !isHusband &&
      isMarried &&
      fertilityGoal != FertilityGoal.justTracking &&
      fertilityGoal != null;

  /// Should show intimacy recommendations
  bool get showIntimacyContent => isMarried;

  /// Copy with updated fields
  UserProfile copyWith({
    String? id,
    String? name,
    RelationshipStatus? relationshipStatus,
    FertilityGoal? fertilityGoal,
    int? averageCycleLength,
    int? averagePeriodLength,
    DateTime? lastPeriodStartDate,
    bool? notificationsEnabled,
    bool? hasCompletedOnboarding,
    DateTime? createdAt,
    DateTime? updatedAt,
    String? partnerName,
    UserRole? role,
    bool? isIrregularCycle,
    int? minCycleLength,
    int? maxCycleLength,
    BibleTranslation? bibleTranslation,
    List<String>? favoriteFoods,
    bool? isDataShared,
    AppThemeMode? themeMode,
    String? accentColor,
    bool? shareMoods,
    bool? shareSymptoms,
    bool? shareCravings,
    bool? shareEnergyLevels,
    bool? shareSleep,
    bool? shareIntimacy,
    bool? isPadTrackingEnabled,
    int? typicalFlowIntensity,
    String? padBrand,
    int? padAbsorbency,
    int? padInventoryCount,
    int? lowInventoryThreshold,
    bool? isAutoInventoryEnabled,
    DateTime? lastInventoryUpdate,
    bool? notifyPeriodEstimate,
    bool? notifyPeriodStart,
    bool? notifyLowSupply,
    DateTime? lastPadChangeTime,
    List<SupplyItem>? padSupplies,
    bool? showPadTimerMinutes,
    bool? showPadTimerSeconds,
    bool? notifyPad1Hour,
    bool? notifyPad2Hours,
    String? privacyPin,
    bool? isBioProtected,
    bool? isHistoryProtected,
    bool? notifyPad30Mins,
    bool? notifyPadNow,
    bool? isLogProtected,
    bool? isCalendarProtected,
    bool? isSuppliesProtected,
    List<TeachingPlan>? teachingPlans,
    AppThemeMode? husbandThemeMode,
    String? husbandAccentColor,
    bool? useExampleData,
  }) {
    return UserProfile(
      id: id ?? this.id,
      name: name ?? this.name,
      relationshipStatus: relationshipStatus ?? this.relationshipStatus,
      fertilityGoal: fertilityGoal ?? this.fertilityGoal,
      averageCycleLength: averageCycleLength ?? this.averageCycleLength,
      averagePeriodLength: averagePeriodLength ?? this.averagePeriodLength,
      lastPeriodStartDate: lastPeriodStartDate ?? this.lastPeriodStartDate,
      notificationsEnabled: notificationsEnabled ?? this.notificationsEnabled,
      hasCompletedOnboarding:
          hasCompletedOnboarding ?? this.hasCompletedOnboarding,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? DateTime.now(),
      partnerName: partnerName ?? this.partnerName,
      role: role ?? this.role,
      isIrregularCycle: isIrregularCycle ?? this.isIrregularCycle,
      minCycleLength: minCycleLength ?? this.minCycleLength,
      maxCycleLength: maxCycleLength ?? this.maxCycleLength,
      bibleTranslation: bibleTranslation ?? this.bibleTranslation,
      favoriteFoods: favoriteFoods ?? this.favoriteFoods,
      isDataShared: isDataShared ?? this.isDataShared,
      themeMode: themeMode ?? this.themeMode,
      accentColor: accentColor ?? this.accentColor,
      shareMoods: shareMoods ?? this.shareMoods,
      shareSymptoms: shareSymptoms ?? this.shareSymptoms,
      shareCravings: shareCravings ?? this.shareCravings,
      shareEnergyLevels: shareEnergyLevels ?? this.shareEnergyLevels,
      shareSleep: shareSleep ?? this.shareSleep,
      shareIntimacy: shareIntimacy ?? this.shareIntimacy,
      isPadTrackingEnabled: isPadTrackingEnabled ?? this.isPadTrackingEnabled,
      typicalFlowIntensity: typicalFlowIntensity ?? this.typicalFlowIntensity,
      padBrand: padBrand ?? this.padBrand,
      padAbsorbency: padAbsorbency ?? this.padAbsorbency,
      padInventoryCount: padInventoryCount ?? this.padInventoryCount,
      lowInventoryThreshold:
          lowInventoryThreshold ?? this.lowInventoryThreshold,
      isAutoInventoryEnabled:
          isAutoInventoryEnabled ?? this.isAutoInventoryEnabled,
      lastInventoryUpdate: lastInventoryUpdate ?? this.lastInventoryUpdate,
      notifyPeriodEstimate: notifyPeriodEstimate ?? this.notifyPeriodEstimate,
      notifyPeriodStart: notifyPeriodStart ?? this.notifyPeriodStart,
      notifyLowSupply: notifyLowSupply ?? this.notifyLowSupply,
      lastPadChangeTime: lastPadChangeTime ?? this.lastPadChangeTime,
      padSupplies: padSupplies ?? this.padSupplies,
      showPadTimerMinutes: showPadTimerMinutes ?? this.showPadTimerMinutes,
      showPadTimerSeconds: showPadTimerSeconds ?? this.showPadTimerSeconds,
      notifyPad1Hour: notifyPad1Hour ?? this.notifyPad1Hour,
      notifyPad2Hours: notifyPad2Hours ?? this.notifyPad2Hours,
      privacyPin: privacyPin ?? this.privacyPin,
      isBioProtected: isBioProtected ?? this.isBioProtected,
      isHistoryProtected: isHistoryProtected ?? this.isHistoryProtected,
      notifyPad30Mins: notifyPad30Mins ?? this.notifyPad30Mins,
      notifyPadNow: notifyPadNow ?? this.notifyPadNow,
      isLogProtected: isLogProtected ?? this.isLogProtected,
      isCalendarProtected: isCalendarProtected ?? this.isCalendarProtected,
      isSuppliesProtected: isSuppliesProtected ?? this.isSuppliesProtected,
      teachingPlans: teachingPlans ?? this.teachingPlans,
      husbandThemeMode: husbandThemeMode ?? this.husbandThemeMode,
      husbandAccentColor: husbandAccentColor ?? this.husbandAccentColor,
      useExampleData: useExampleData ?? this.useExampleData,
    );
  }
}

extension BibleTranslationExtension on BibleTranslation {
  String get label {
    switch (this) {
      case BibleTranslation.esv:
        return 'ESV';
      case BibleTranslation.niv:
        return 'NIV';
      case BibleTranslation.nkjv:
        return 'NKJV';
      case BibleTranslation.nlt:
        return 'NLT';
      case BibleTranslation.nasb:
        return 'NASB';
      case BibleTranslation.kjv:
        return 'KJV';
      case BibleTranslation.msg:
        return 'MSG';
    }
  }
}

@HiveType(typeId: 8)
enum UserRole {
  @HiveField(0)
  wife,
  @HiveField(1)
  husband,
}
