/// Domain Entity: Review
///
/// Represents a product review with rating and comment.
library;

/// Review entity
///
/// Contains user feedback for a product including:
/// - Unique review ID (name field from API)
/// - Product item code
/// - Rating (0-1 from API, converted to 0-5 stars for display)
/// - Review comment text
/// - Reviewer information
/// - Review date
class Review {
  const Review({
    required this.id,
    required this.itemId,
    required this.rating,
    required this.comment,
    this.reviewerName,
    this.reviewerEmail,
    this.reviewDate,
  });

  /// Unique review identifier (format: ITEM-{item_id}-{user_email})
  final String id;

  /// Product item code being reviewed
  final String itemId;

  /// Rating from API (0-5 scale)
  /// Note: API already provides rating on 0-5 scale, no conversion needed
  final double rating;

  /// Review comment text
  final String comment;

  /// Name of the reviewer (if available)
  final String? reviewerName;

  /// Email of the reviewer (if available)
  final String? reviewerEmail;

  /// Date when the review was created (if available)
  final DateTime? reviewDate;

  /// Get star rating rounded to nearest integer (0-5)
  ///
  /// Examples:
  /// - API rating 0.5 = 1 star
  /// - API rating 2.25 = 2 stars
  /// - API rating 4.0 = 4 stars
  int get starsRating => rating.round();

  /// Get rating as exact decimal (0-5 scale)
  ///
  /// This is useful for average rating calculations and display
  /// API already returns this on 0-5 scale
  double get starsRatingDecimal => rating;

  /// Copy with method for creating modified copies
  Review copyWith({
    String? id,
    String? itemId,
    double? rating,
    String? comment,
    String? reviewerName,
    String? reviewerEmail,
    DateTime? reviewDate,
  }) {
    return Review(
      id: id ?? this.id,
      itemId: itemId ?? this.itemId,
      rating: rating ?? this.rating,
      comment: comment ?? this.comment,
      reviewerName: reviewerName ?? this.reviewerName,
      reviewerEmail: reviewerEmail ?? this.reviewerEmail,
      reviewDate: reviewDate ?? this.reviewDate,
    );
  }

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

    return other is Review &&
        other.id == id &&
        other.itemId == itemId &&
        other.rating == rating &&
        other.comment == comment &&
        other.reviewerName == reviewerName &&
        other.reviewerEmail == reviewerEmail &&
        other.reviewDate == reviewDate;
  }

  @override
  int get hashCode {
    return Object.hash(
      id,
      itemId,
      rating,
      comment,
      reviewerName,
      reviewerEmail,
      reviewDate,
    );
  }

  @override
  String toString() {
    return 'Review(id: $id, itemId: $itemId, rating: $rating, '
        'starsRating: $starsRating, comment: ${comment.substring(0, comment.length > 30 ? 30 : comment.length)}..., '
        'reviewerName: $reviewerName, reviewDate: $reviewDate)';
  }
}
