/// Domain Entity: Quote Item
///
/// Represents a single line item in a quotation.
library;

/// Quote Item Entity
///
/// Contains item-level information in a quote:
/// - Product reference
/// - Quantity and pricing
/// - Price negotiation
/// - Discounts
class QuoteItem {
  /// Unique quote item identifier
  final String quoteItemId;

  /// Quote ID this item belongs to
  final String quoteId;

  /// Product ID
  final String productId;

  /// Quantity quoted
  final double quantity;

  /// Original/list price per unit
  final double originalPrice;

  /// Negotiated price per unit
  final double negotiatedPrice;

  /// Discount percentage
  final double discountPercent;

  /// Subtotal (quantity * negotiatedPrice)
  final double subtotal;

  /// Item notes
  final String? notes;

  const QuoteItem({
    required this.quoteItemId,
    required this.quoteId,
    required this.productId,
    required this.quantity,
    required this.originalPrice,
    required this.negotiatedPrice,
    required this.discountPercent,
    required this.subtotal,
    this.notes,
  });

  /// Calculate subtotal at original price
  double get subtotalAtOriginalPrice => quantity * originalPrice;

  /// Calculate discount amount per unit
  double get discountPerUnit => originalPrice - negotiatedPrice;

  /// Calculate total discount amount
  double get totalDiscountAmount =>
      (quantity * originalPrice) - (quantity * negotiatedPrice);

  /// Calculate effective discount percentage
  double get effectiveDiscountPercentage {
    if (originalPrice == 0) return 0;
    return ((originalPrice - negotiatedPrice) / originalPrice) * 100;
  }

  /// Check if item has discount
  bool get hasDiscount => negotiatedPrice < originalPrice;

  /// Check if price was negotiated
  bool get isNegotiated => negotiatedPrice != originalPrice;

  /// Copy with method for immutability
  QuoteItem copyWith({
    String? quoteItemId,
    String? quoteId,
    String? productId,
    double? quantity,
    double? originalPrice,
    double? negotiatedPrice,
    double? discountPercent,
    double? subtotal,
    String? notes,
  }) {
    return QuoteItem(
      quoteItemId: quoteItemId ?? this.quoteItemId,
      quoteId: quoteId ?? this.quoteId,
      productId: productId ?? this.productId,
      quantity: quantity ?? this.quantity,
      originalPrice: originalPrice ?? this.originalPrice,
      negotiatedPrice: negotiatedPrice ?? this.negotiatedPrice,
      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 QuoteItem &&
        other.quoteItemId == quoteItemId &&
        other.quoteId == quoteId &&
        other.productId == productId &&
        other.quantity == quantity &&
        other.originalPrice == originalPrice &&
        other.negotiatedPrice == negotiatedPrice &&
        other.subtotal == subtotal;
  }

  @override
  int get hashCode {
    return Object.hash(
      quoteItemId,
      quoteId,
      productId,
      quantity,
      originalPrice,
      negotiatedPrice,
      subtotal,
    );
  }

  @override
  String toString() {
    return 'QuoteItem(quoteItemId: $quoteItemId, productId: $productId, '
        'quantity: $quantity, originalPrice: $originalPrice, '
        'negotiatedPrice: $negotiatedPrice, subtotal: $subtotal)';
  }
}
