from collections import defaultdict


class Product:
    
    def __init__(self, name, price):
        self.name = name
        self.price = price


class User:

    def __init__(self, login, balance=0):
        self.login = login
        self.balance = balance

    @property
    def balance(self):
        return self.__balance
    
    @balance.setter
    def balance(self, value):
        self.__balance = value

    def __str__(self):
        return f"Пользователь {self.login}, баланс - {self.balance}"

    def deposit(self, value):
        self.balance += value

    def is_money_enough(self, value):
        return value <= self    .balance
    
    def payment(self, value):
        if self.is_money_enough(value):
            self.balance -= value
            return True
        else:
            print("Не хватает средств на балансе. Пополните счет")
            return False


class Cart:

    def __init__(self, user:User) -> None:
        self.user = user
        self.goods = defaultdict()
        self.__total = 0

    def add(self, product:Product, count=1):
        if product not in self.goods.keys():
            self.goods[product] = count
        else:
            self.goods[product] += count

        self.__total += product.price * count
    
    def remove(self, product:Product, number=1):
        if number >= self.goods[product]:
            number = self.goods[product]
            self.goods[product] = self.goods.get(product, 0) - number
            self.__total -= number * product.price


    @property
    def total(self):
        return self.__total
    
    def order(self):
        order_price = 0
        for key in self.goods.keys():
            order_price += key.price * self.goods[key]
        if self.user.payment(order_price):
            print("Заказ оплачен")
        else:
            print("Проблема с оплатой")

    def print_check(self):
        sorted_list = sorted(self.goods, key=lambda x: x.name)
        print("---Your check---")
        for element in sorted_list:
            if self.goods[element] > 0:
                print(f"{element.name} {element.price} {self.goods[element]} {element.price*self.goods[element]}")
        print(f"---Total: {self.total}---")



def main():

    billy = User('billy@rambler.ru')

    lemon = Product('lemon', 20)
    carrot = Product('carrot', 30)

    cart_billy = Cart(billy)
    print(cart_billy.user) # Пользователь billy@rambler.ru, баланс - 0
    cart_billy.add(lemon, 2)
    cart_billy.add(carrot)
    cart_billy.print_check()
    ''' Печатает текст ниже
    ---Your check---
    carrot 30 1 30
    lemon 20 2 40
    ---Total: 70---'''
    cart_billy.add(lemon, 3)
    cart_billy.print_check()
    ''' Печатает текст ниже
    ---Your check---
    carrot 30 1 30
    lemon 20 5 100
    ---Total: 130---'''
    cart_billy.remove(lemon, 6)
    cart_billy.print_check()
    ''' Печатает текст ниже
    ---Your check---
    carrot 30 1 30
    ---Total: 30---'''
    print(cart_billy.total) # 30
    cart_billy.add(lemon, 5)
    cart_billy.print_check()
    ''' Печатает текст ниже
    ---Your check---
    carrot 30 1 30
    lemon 20 5 100
    ---Total: 130---'''
    cart_billy.order()
    ''' Печатает текст ниже
    Не хватает средств на балансе. Пополните счет
    Проблема с оплатой'''
    cart_billy.user.deposit(150)
    cart_billy.order() # Заказ оплачен
    print(cart_billy.user.balance) # 20


if __name__ == '__main__':
    main()