from collections import defaultdict
from Transaction import Transaction, TransactionType

class InvalidTransactionError(Exception):
    """This transaction is invalid"""
    pass

class TransactionExecutor:
    def __init__(self) -> None:
        self.accounts = defaultdict(int)
    
    def deposit(self, transaction: Transaction) -> None:
        self.accounts[transaction.receiver_account]+=transaction.amount

    def transfer(self, transaction: Transaction) -> None:
        if transaction.sender_account not in self.accounts or self.accounts[transaction.sender_account]<transaction.amount:
            raise InvalidTransactionError
        self.accounts[transaction.sender_account]-=transaction.amount
        self.accounts[transaction.receiver_account]+=transaction.amount
    
    def transaction(self, transaction: Transaction) -> None:
        try:
            if transaction.type==TransactionType.DEPOSIT:
                self.deposit(transaction)
            elif transaction.type==TransactionType.TRANSFER:
                self.transfer(transaction)
        except InvalidTransactionError:
            pass
        self.printTransactions()
    def printTransactions(self):
        items = self.accounts.items()
        items = sorted(items, key=lambda x: x[0])
        accountsString = ' '.join(f"{act}:{amt}" for act, amt in items)
        print(f"BALENCES {accountsString}")