/// Domain Entity: Promotion
///
/// Represents a promotional offer or campaign displayed on the home screen.
/// This entity contains all information needed to display promotion banners.
///
/// This is a pure domain entity with no external dependencies.
library;

/// Promotion status enum
enum PromotionStatus {
  /// Currently active promotion
  active,

  /// Promotion starting in the future
  upcoming,

  /// Expired promotion
  expired,
}

/// Promotion Entity
///
/// Contains all information needed to display a promotion:
/// - Basic info (title, description)
/// - Visual assets (image URL)
/// - Validity period
/// - Optional discount information
class Promotion {
  /// Unique promotion ID
  final String id;

  /// Promotion title
  final String title;

  /// Detailed description
  final String description;

  /// Banner/cover image URL
  final String imageUrl;

  /// Promotion start date
  final DateTime startDate;

  /// Promotion end date
  final DateTime endDate;

  /// Optional discount percentage (e.g., 30 for 30%)
  final int? discountPercentage;

  /// Optional discount amount
  final double? discountAmount;

  /// Optional terms and conditions
  final String? terms;

  /// Optional link to detailed page
  final String? detailsUrl;

  /// Constructor
  const Promotion({
    required this.id,
    required this.title,
    required this.description,
    required this.imageUrl,
    required this.startDate,
    required this.endDate,
    this.discountPercentage,
    this.discountAmount,
    this.terms,
    this.detailsUrl,
  });

  /// Get current promotion status
  PromotionStatus get status {
    final now = DateTime.now();

    if (now.isBefore(startDate)) {
      return PromotionStatus.upcoming;
    } else if (now.isAfter(endDate)) {
      return PromotionStatus.expired;
    } else {
      return PromotionStatus.active;
    }
  }

  /// Check if promotion is currently active
  bool get isActive => status == PromotionStatus.active;

  /// Get days remaining until expiry (null if expired or upcoming)
  int? get daysRemaining {
    if (status != PromotionStatus.active) return null;

    return endDate.difference(DateTime.now()).inDays;
  }

  /// Format discount display text
  String? get discountText {
    if (discountPercentage != null) {
      return 'Giảm $discountPercentage%';
    } else if (discountAmount != null) {
      return 'Giảm ${discountAmount?.toStringAsFixed(0) ?? '0'}₫';
    }
    return null;
  }

  /// Copy with method for immutability
  Promotion copyWith({
    String? id,
    String? title,
    String? description,
    String? imageUrl,
    DateTime? startDate,
    DateTime? endDate,
    int? discountPercentage,
    double? discountAmount,
    String? terms,
    String? detailsUrl,
  }) {
    return Promotion(
      id: id ?? this.id,
      title: title ?? this.title,
      description: description ?? this.description,
      imageUrl: imageUrl ?? this.imageUrl,
      startDate: startDate ?? this.startDate,
      endDate: endDate ?? this.endDate,
      discountPercentage: discountPercentage ?? this.discountPercentage,
      discountAmount: discountAmount ?? this.discountAmount,
      terms: terms ?? this.terms,
      detailsUrl: detailsUrl ?? this.detailsUrl,
    );
  }

  /// Equality operator
  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;

    return other is Promotion &&
        other.id == id &&
        other.title == title &&
        other.description == description &&
        other.imageUrl == imageUrl &&
        other.startDate == startDate &&
        other.endDate == endDate &&
        other.discountPercentage == discountPercentage &&
        other.discountAmount == discountAmount &&
        other.terms == terms &&
        other.detailsUrl == detailsUrl;
  }

  /// Hash code
  @override
  int get hashCode {
    return Object.hash(
      id,
      title,
      description,
      imageUrl,
      startDate,
      endDate,
      discountPercentage,
      discountAmount,
      terms,
      detailsUrl,
    );
  }

  /// String representation
  @override
  String toString() {
    return 'Promotion(id: $id, title: $title, description: $description, '
        'imageUrl: $imageUrl, startDate: $startDate, endDate: $endDate, '
        'discountPercentage: $discountPercentage, discountAmount: $discountAmount, '
        'terms: $terms, detailsUrl: $detailsUrl)';
  }
}
