/// Domain Entity: Stock Level
///
/// Represents inventory stock level for a product in a warehouse.
library;

/// Stock Level Entity
///
/// Contains inventory information for a product:
/// - Available quantity
/// - Reserved quantity (for pending orders)
/// - Ordered quantity (incoming stock)
/// - Warehouse location
class StockLevel {
  /// Product ID
  final String productId;

  /// Available quantity for sale
  final double availableQty;

  /// Quantity reserved for orders
  final double reservedQty;

  /// Quantity on order (incoming)
  final double orderedQty;

  /// Warehouse code
  final String warehouseCode;

  /// Last update timestamp
  final DateTime lastUpdated;

  const StockLevel({
    required this.productId,
    required this.availableQty,
    required this.reservedQty,
    required this.orderedQty,
    required this.warehouseCode,
    required this.lastUpdated,
  });

  /// Get total quantity (available + reserved + ordered)
  double get totalQty => availableQty + reservedQty + orderedQty;

  /// Check if product is in stock
  bool get isInStock => availableQty > 0;

  /// Check if stock is low (less than 10 units)
  bool get isLowStock => availableQty > 0 && availableQty < 10;

  /// Check if out of stock
  bool get isOutOfStock => availableQty <= 0;

  /// Get available percentage
  double get availablePercentage {
    if (totalQty == 0) return 0;
    return (availableQty / totalQty) * 100;
  }

  /// Copy with method for immutability
  StockLevel copyWith({
    String? productId,
    double? availableQty,
    double? reservedQty,
    double? orderedQty,
    String? warehouseCode,
    DateTime? lastUpdated,
  }) {
    return StockLevel(
      productId: productId ?? this.productId,
      availableQty: availableQty ?? this.availableQty,
      reservedQty: reservedQty ?? this.reservedQty,
      orderedQty: orderedQty ?? this.orderedQty,
      warehouseCode: warehouseCode ?? this.warehouseCode,
      lastUpdated: lastUpdated ?? this.lastUpdated,
    );
  }

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

    return other is StockLevel &&
        other.productId == productId &&
        other.availableQty == availableQty &&
        other.reservedQty == reservedQty &&
        other.orderedQty == orderedQty &&
        other.warehouseCode == warehouseCode;
  }

  @override
  int get hashCode {
    return Object.hash(
      productId,
      availableQty,
      reservedQty,
      orderedQty,
      warehouseCode,
    );
  }

  @override
  String toString() {
    return 'StockLevel(productId: $productId, availableQty: $availableQty, '
        'reservedQty: $reservedQty, orderedQty: $orderedQty, warehouseCode: $warehouseCode)';
  }
}
