/// Domain Entity: Order Item
///
/// Represents a single line item in an order.
library;

/// Order Item Entity
///
/// Contains item-level information in an order:
/// - Product reference
/// - Quantity and pricing
/// - Discounts
/// - Notes
class OrderItem {
  /// Unique order item identifier
  final String orderItemId;

  /// Order ID this item belongs to
  final String orderId;

  /// Product ID
  final String productId;

  /// Quantity ordered
  final double quantity;

  /// Unit price at time of order
  final double unitPrice;

  /// Discount percentage applied
  final double discountPercent;

  /// Subtotal (quantity * unitPrice * (1 - discountPercent/100))
  final double subtotal;

  /// Item notes
  final String? notes;

  const OrderItem({
    required this.orderItemId,
    required this.orderId,
    required this.productId,
    required this.quantity,
    required this.unitPrice,
    required this.discountPercent,
    required this.subtotal,
    this.notes,
  });

  /// Calculate subtotal before discount
  double get subtotalBeforeDiscount => quantity * unitPrice;

  /// Calculate discount amount
  double get discountAmount => subtotalBeforeDiscount * (discountPercent / 100);

  /// Calculate subtotal after discount (for verification)
  double get calculatedSubtotal => subtotalBeforeDiscount - discountAmount;

  /// Check if item has discount
  bool get hasDiscount => discountPercent > 0;

  /// Copy with method for immutability
  OrderItem copyWith({
    String? orderItemId,
    String? orderId,
    String? productId,
    double? quantity,
    double? unitPrice,
    double? discountPercent,
    double? subtotal,
    String? notes,
  }) {
    return OrderItem(
      orderItemId: orderItemId ?? this.orderItemId,
      orderId: orderId ?? this.orderId,
      productId: productId ?? this.productId,
      quantity: quantity ?? this.quantity,
      unitPrice: unitPrice ?? this.unitPrice,
      discountPercent: discountPercent ?? this.discountPercent,
      subtotal: subtotal ?? this.subtotal,
      notes: notes ?? this.notes,
    );
  }

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

    return other is OrderItem &&
        other.orderItemId == orderItemId &&
        other.orderId == orderId &&
        other.productId == productId &&
        other.quantity == quantity &&
        other.unitPrice == unitPrice &&
        other.discountPercent == discountPercent &&
        other.subtotal == subtotal;
  }

  @override
  int get hashCode {
    return Object.hash(
      orderItemId,
      orderId,
      productId,
      quantity,
      unitPrice,
      discountPercent,
      subtotal,
    );
  }

  @override
  String toString() {
    return 'OrderItem(orderItemId: $orderItemId, productId: $productId, '
        'quantity: $quantity, unitPrice: $unitPrice, subtotal: $subtotal)';
  }
}
