import datetime
from sqlalchemy.sql.expression import func, desc

from pyramid.view import view_config

from brewman.models import DBSession
from brewman.models.master import LedgerBase

from brewman.models.voucher import Voucher, Journal, VoucherType
from brewman.views.services.session import session_period_finish, session_period_start


@view_config(request_method='GET', route_name='net_transactions', renderer='brewman:templates/angular_base.mako',
             permission='Net Transactions')
def html(request):
    return {}


@view_config(request_method='GET', route_name='api_net_transactions', renderer='json', permission='Net Transactions')
def report(request):
    start_date = request.GET.get('StartDate', None)
    finish_date = request.GET.get('FinishDate', None)
    if start_date and finish_date:
        return {'StartDate': start_date, 'FinishDate': finish_date, 'Body': build_report(start_date, finish_date)}
    else:
        return {'StartDate': session_period_start(request),
                'FinishDate': session_period_finish(request), 'Body': []}


def build_report(start_date, finish_date):
    if not isinstance(start_date, datetime.datetime):
        start_date = datetime.datetime.strptime(start_date, '%d-%b-%Y')
    if not isinstance(finish_date, datetime.datetime):
        finish_date = datetime.datetime.strptime(finish_date, '%d-%b-%Y')

    amount_sum = func.sum(Journal.amount * Journal.debit).label('Amount')
    query = DBSession.query(LedgerBase, amount_sum) \
        .join(Journal.voucher).join(Journal.ledger) \
        .filter(Voucher.date >= start_date) \
        .filter(Voucher.date <= finish_date) \
        .filter(Voucher.type != VoucherType.by_name('Issue').id) \
        .group_by(LedgerBase).order_by(LedgerBase.type).order_by(desc(func.abs(amount_sum))).all()

    body = []
    for ledger, amount in query:
        if amount != 0:
            tag = 'Debit' if amount > 0 else 'Credit'
            body.append({'Type': ledger.type_object.name, 'Name': ledger.name, tag: amount})
    return body
