from decimal import Decimal
import uuid
from pyramid.response import Response

from pyramid.view import view_config
import transaction

from brewman.models.master import Product, CostCenter, LedgerType, Ledger
from brewman.models.validation_exception import TryCatchFunction

@view_config(route_name='product_list', renderer='brewman:templates/angular_base.mako', permission='Authenticated')
@view_config(request_method='GET', route_name='product_id', renderer='brewman:templates/angular_base.mako',
    permission='Products')
@view_config(request_method='GET', route_name='product', renderer='brewman:templates/angular_base.mako',
    permission='Products')
def html(request):
    return {}


@view_config(request_method='POST', route_name='api_product', renderer='json', permission='Products')
@TryCatchFunction
def save(request):
    item = Product(0, request.json_body['Name'], request.json_body['Units'],
        Decimal(request.json_body['Fraction']), request.json_body['FractionUnits'],
        Decimal(request.json_body['Yeild']), request.json_body['ShowForPurchase'],
        uuid.UUID(request.json_body['ProductGroup']['ProductGroupID']), Ledger.all_purchases(),
        Decimal(request.json_body['Price']), request.json_body['Discontinued']).create()
    transaction.commit()
    return product_info(item.id)


@view_config(request_method='POST', route_name='api_product_id', renderer='json', permission='Products')
@TryCatchFunction
def update(request):
    item = Product.by_id(uuid.UUID(request.matchdict['id']))
    item.name = request.json_body['Name']
    item.units = request.json_body['Units']
    item.fraction = Decimal(request.json_body['Fraction'])
    item.fraction_units = request.json_body['FractionUnits']
    item.yeild = Decimal(request.json_body['Yeild'])
    item.show_for_purchase = request.json_body['ShowForPurchase']
    item.product_group_id = uuid.UUID(request.json_body['ProductGroup']['ProductGroupID'])
    item.ledger_id = Ledger.all_purchases()
    item.price = Decimal(request.json_body['Price'])
    item.discontinued = request.json_body['Discontinued']
    transaction.commit()
    return product_info(item.id)


@view_config(request_method='DELETE', route_name='api_product_id', renderer='json', permission='Products')
def delete(request):
    id = request.matchdict.get('id', None)
    if id is None:
        response = Response("Product is Null")
        response.status_int = 500
        return response
    else:
        response = Response("Product deletion not implemented")
        response.status_int = 500
        return response


@view_config(request_method='GET', route_name='api_product_id', renderer='json', permission='Products')
def show_id(request):
    return product_info(uuid.UUID(request.matchdict.get('id', None)))


@view_config(request_method='GET', route_name='api_product', renderer='json', permission='Products')
def show_blank(request):
    return product_info(None)


@view_config(request_method='GET', route_name='api_product', request_param='list', renderer='json',
    permission='Authenticated')
def show_list(request):
    list = Product.query().order_by(Product.discontinued).order_by(Product.product_group_id).order_by(
        Product.name).all()
    products = []
    for item in list:
        products.append({'Code': item.code, 'Name': item.name, 'Units': item.units, 'Price': item.price,
                         'ProductGroup': item.product_group.name, 'Discontinued': item.discontinued,
                         'Url': request.route_url('product_id', id=item.id)})
    return products


@view_config(request_method='GET', route_name='api_product', renderer='json', request_param='term',
    permission='Authenticated')
def show_term(request):
    filter = request.GET.get('term', None)
    filter = filter if filter is not None and filter is not '' else None
    count = request.GET.get('count', None)
    count = None if count is None or count == '' else int(count)
    list = []
    for index, item in enumerate(Product.list(filter)):
        list.append({'ProductID': item.id, 'Name': item.full_name, 'Price': item.price})
        if count is not None and index == count - 1:
            break
    return list


def product_info(id):
    if id is None:
        product = {'Code': '(Auto)', 'Type': LedgerType.by_name('Creditors').id, 'IsActive': True,
                   'CostCenter': CostCenter.overall(), 'ShowForPurchase': True, 'Discontinued': False}
    else:
        product = Product.by_id(id)
        product = {'ProductID': product.id, 'Code': product.code, 'Name': product.name, 'Units': product.units,
                   'Fraction': product.fraction, 'FractionUnits': product.fraction_units, 'Yeild': product.yeild,
                   'ShowForPurchase': product.show_for_purchase, 'Discontinued': product.discontinued,
                   'ProductGroup': {'ProductGroupID': product.product_group_id},
                   'Ledger': {'LedgerID': product.ledger_id}, 'Price': product.price}
    return product
