"""!bal: show your current balance"""
from bm_shared import _get_cmd
from bm_model import *
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from bm_shared import _get_username_by_id
from bm_model import Balance, Expense


def _update_balance(session, id):
    """
    @todo: 1. incremental update 2. circular debt removal
    """
    balance = {}
    credits = session.query(Expense).filter(Expense.creditor == id)
    if credits.count() > 0:
        for credit in credits:
            try:
                balance[credit.debtor] += credit.amount
            except KeyError:
                balance[credit.debtor] = credit.amount

    debts = session.query(Expense).filter(Expense.debtor == id)
    if debts.count() > 0:
        for debt in debts:
            try:
                balance[debt.creditor] -= debt.amount
            except KeyError:
                balance[debt.creditor] = -debt.amount

    # bi-directional update
    for debtor, balance_amount in balance.iteritems():
        balance = Balance(creditor=id, debtor=debtor, amount=balance_amount)
        balancei = Balance(creditor=debtor, debtor=id, amount=-balance_amount)
        session.merge(balance)
        session.merge(balancei)
    session.commit()


def get_balance(session, id):
    balance_msg = "Your balance info:\n======\n"
    balances = session.query(Balance).filter(Balance.creditor == id)
    if balances.count() > 0:
        for balance in balances:
            if balance.amount > 0:
                balance_msg += "{0} owe you ${1}.\n".format(_get_username_by_id(session, balance.debtor),
                                                            balance.amount)
            elif balance.amount < 0:
                balance_msg += "You owe {0} ${1}.\n".format(_get_username_by_id(session, balance.debtor),
                                                            -balance.amount)
    else:
        balance_msg += "Your balance is clean."
    return balance_msg


def on_message(msg, server):
    text = msg.get("text", "")
    cmd = _get_cmd(text)

    engine = create_engine("sqlite:///bm.db")
    base.metadata.create_all(engine)
    maker = sessionmaker(bind=engine)
    session = maker()

    if cmd[0] == "!bal":
        return get_balance(session, msg.get("user"))
