import 'package:concierge/data/remote/models/area_details.dart';
import 'package:concierge/data/remote/models/product.dart';
import 'package:concierge/domain/models/data_state.dart';
import 'package:concierge/domain/models/delivery_location.dart';
import 'package:concierge/presentation/app/concierge_cubit.dart';
import 'package:concierge/presentation/base/base_cubit.dart';
import 'package:concierge/domain/models/app_error.dart';
import 'package:flutter/cupertino.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import '../../domain/models/product_in_cart.dart';
part '../../_generated/presentation/app/cart_cubit.freezed.dart';
class CartCubit extends BaseCubit<CartState> {
final ConciergeCubit _conciergeCubit;
CartCubit(this._conciergeCubit) : super(const CartState());
final orderCommentController = TextEditingController();
void updateProduct(int productId, Map<int, int> variantId, int quantity) {
final copy = Map.of(state.productsWithQuantity);
copy[productId] = ProductInCart(productId, variantId, quantity);
safeEmit(state.copyWith(productsWithQuantity: copy));
}
ProductInCart? getProduct(int productId) {
final product = state.productsWithQuantity[productId];
if (product == null) return null;
if (product.quantity == 0) return null;
return product;
}
int getQuantity(int productId) => state.productsWithQuantity[productId]?.quantity ?? 0;
void updateComment(String comment) {
safeEmit(state.copyWith(comment: comment));
}
void updateDelivery(bool isDelivery) {
safeEmit(state.copyWith(isDelivery: isDelivery));
}
void updateReadyTime(String time) {
safeEmit(state.copyWith(readyTime: time));
}
void updateSelectedArea(AreaDetails area) {
safeEmit(state.copyWith(selectedArea: area, productsWithQuantity: {}));
}
void updatePaymentMethod(bool chargeToRoom) {
safeEmit(state.copyWith(chargeToRoom: chargeToRoom));
}
void updateLocation(DeliveryLocation deliveryLocation) {
safeEmit(state.copyWith(deliveryLocation: deliveryLocation));
}
void updateLocationCode(String code) {
safeEmit(state.copyWith(deliveryLocationCode: code));
}
int get totalItems {
if (state.productsWithQuantity.isEmpty) return 0;
return state.productsWithQuantity.values
.map((p) => p.quantity)
.reduce((prev, curr) => prev + curr);
}
double get totalPrice {
double price = 0;
for (final product in products) {
final quantity = getProduct(product.id)?.quantity ?? 0;
price += product.price * quantity;
}
return price;
}
Iterable<Product> get products sync* {
for (final productId in state.productsWithQuantity.keys) {
final dataState = _conciergeCubit.getProductState(productId);
if (dataState is Success<Product> && getQuantity(productId) > 0) yield dataState.data;
}
}
}
@freezed
abstract class CartState with _$CartState {
const factory CartState({
@Default(false) bool isLoading,
@Default(AppError.none) AppError error,
@Default({}) Map<int, ProductInCart> productsWithQuantity,
@Default(false) bool isDelivery,
@Default(true) bool chargeToRoom,
@Default("") String comment,
@Default("") String readyTime,
@Default("") String deliveryLocationCode,
@Default(DeliveryLocation.room) DeliveryLocation deliveryLocation,
AreaDetails? selectedArea,
}) = _CartState;
const CartState._();
}