/// Cart State
///
/// Immutable state class for cart management.
library;

import 'package:worker/features/products/domain/entities/product.dart';

/// Cart Item Data
///
/// Represents a product in the cart with quantity.
class CartItemData { // Number of tiles/boxes needed

  const CartItemData({
    required this.product,
    required this.quantity,
    required this.quantityConverted,
    required this.boxes,
  });
  final Product product;
  final double quantity;
  final double quantityConverted; // Rounded-up quantity for actual billing
  final int boxes;

  /// Calculate line total using CONVERTED quantity (important for accurate billing)
  double get lineTotal => product.basePrice * quantityConverted;

  CartItemData copyWith({
    Product? product,
    double? quantity,
    double? quantityConverted,
    int? boxes,
  }) {
    return CartItemData(
      product: product ?? this.product,
      quantity: quantity ?? this.quantity,
      quantityConverted: quantityConverted ?? this.quantityConverted,
      boxes: boxes ?? this.boxes,
    );
  }
}

/// Cart State
///
/// Represents the complete state of the shopping cart.
class CartState {

  const CartState({
    required this.items,
    required this.selectedItems,
    required this.selectedWarehouse,
    this.discountCode,
    required this.discountCodeApplied,
    required this.memberTier,
    required this.memberDiscountPercent,
    required this.subtotal,
    required this.memberDiscount,
    required this.shippingFee,
    required this.total,
    this.isLoading = false,
    this.errorMessage,
  });

  factory CartState.initial() {
    return const CartState(
      items: [],
      selectedItems: {},
      selectedWarehouse: 'Kho Hà Nội - Nguyễn Trãi',
      discountCode: null,
      discountCodeApplied: false,
      memberTier: '',
      memberDiscountPercent: 0.0,
      subtotal: 0.0,
      memberDiscount: 0.0,
      shippingFee: 0.0,
      total: 0.0,
    );
  }
  final List<CartItemData> items;
  final Map<String, bool> selectedItems; // productId -> isSelected
  final String selectedWarehouse;
  final String? discountCode;
  final bool discountCodeApplied;
  final String memberTier;
  final double memberDiscountPercent;
  final double subtotal;
  final double memberDiscount;
  final double shippingFee;
  final double total;
  final bool isLoading;
  final String? errorMessage;

  bool get isEmpty => items.isEmpty;
  bool get isNotEmpty => items.isNotEmpty;
  int get itemCount => items.length;

  /// Get total quantity across all items
  double get totalQuantity {
    return items.fold<double>(0.0, (sum, item) => sum + item.quantity);
  }

  /// Get number of selected items
  int get selectedCount {
    return selectedItems.values.where((selected) => selected).length;
  }

  /// Check if all items are selected
  bool get isAllSelected {
    return items.isNotEmpty && selectedCount == items.length;
  }

  /// Get total of selected items only
  double get selectedTotal {
    double total = 0.0;
    for (final item in items) {
      if (selectedItems[item.product.productId] == true) {
        total += item.lineTotal;
      }
    }
    return total;
  }

  CartState copyWith({
    List<CartItemData>? items,
    Map<String, bool>? selectedItems,
    String? selectedWarehouse,
    String? discountCode,
    bool? discountCodeApplied,
    String? memberTier,
    double? memberDiscountPercent,
    double? subtotal,
    double? memberDiscount,
    double? shippingFee,
    double? total,
    bool? isLoading,
    String? errorMessage,
  }) {
    return CartState(
      items: items ?? this.items,
      selectedItems: selectedItems ?? this.selectedItems,
      selectedWarehouse: selectedWarehouse ?? this.selectedWarehouse,
      discountCode: discountCode ?? this.discountCode,
      discountCodeApplied: discountCodeApplied ?? this.discountCodeApplied,
      memberTier: memberTier ?? this.memberTier,
      memberDiscountPercent:
          memberDiscountPercent ?? this.memberDiscountPercent,
      subtotal: subtotal ?? this.subtotal,
      memberDiscount: memberDiscount ?? this.memberDiscount,
      shippingFee: shippingFee ?? this.shippingFee,
      total: total ?? this.total,
      isLoading: isLoading ?? this.isLoading,
      errorMessage: errorMessage,
    );
  }
}
