__author__ = 'tanshu'

import uuid
import datetime
from pyramid.security import authenticated_userid
from pyramid.view import view_config
from sqlalchemy import func
import transaction
from picard.models import DBSession
from picard.models.master import FoodTable, Product
from picard.models.validation_exception import TryCatchFunction
from picard.models.voucher import Voucher, VoucherType, Kot, Inventory


@view_config(request_method='GET', route_name='api_voucher_id', renderer='json')
@TryCatchFunction
def get_voucher_id(request):
    item = Voucher.by_id(uuid.UUID(request.matchdict['id']))
    return get_voucher(voucher=item)


@view_config(request_method='GET', route_name='api_voucher', renderer='json')
@TryCatchFunction
def get_voucher_http(request):
    table = request.GET.get('t', None)
    if table is not None:
        table = FoodTable.by_normalized_name(table)
    return get_voucher(food_table=table)


def get_voucher(food_table=None, voucher=None):
    if food_table is not None:
        if food_table.info is not None:
            voucher = food_table.info.voucher
        else:
            return {'FoodTable': {'FoodTableID': food_table.id, 'Name': food_table.name}, 'Kots': [{'Inventories': []}]}
    if voucher is not None:
        info = {'VoucherID': voucher.id, 'KotID': voucher.kot_id, 'BillID': voucher.bill_id, 'Date': voucher.date,
                'CreationDate': voucher.creation_date, 'LastEditDate': voucher.last_edit_date, 'Pax': voucher.pax,
                'PerSeat': voucher.per_seat,
                'FoodTable': {'FoodTableID': voucher.food_table.id, 'Name': voucher.food_table.name},
                'User': voucher.user.name,
                'Kots': []}
        for kot in voucher.kots:
            kot_info = {'KotID': kot.id, 'Code': kot.code, 'FoodTable': kot.food_table.name, 'Date': kot.date,
                        'User': kot.user.name, 'Inventories': []}
            for inv in kot.inventories:
                inv_info = {'InventoryID': inv.id,
                            'Product': {'ProductID': inv.product.id, 'Name': inv.product.full_name},
                            'Quantity': inv.quantity, 'Price': inv.price, 'Discount': inv.discount,
                            'IsHappyHour': inv.is_happy_hour, 'ServiceTaxRate': inv.service_tax_rate,
                            'VatRate': inv.vat_rate, 'ServiceCharge': inv.service_charge, 'ScTaxable': inv.sc_taxable}
                if voucher.per_seat:
                    inv_info['Chair'] = inv.chair
                kot_info['Inventories'].append(inv_info)
            info['Kots'].append(kot_info)
        if voucher.bill_id is None:
            info['Kots'].append({'Inventories': []})
        return info
    else:
        return {'Kots': [{'Inventories': []}]}


@view_config(request_method='POST', route_name='api_voucher', renderer='json')
@TryCatchFunction
def save(request):
    json = request.json_body
    food_table_id = json['FoodTable']['FoodTableID']
    pax = json['Pax']
    per_seat = json['PerSeat'] if 'PerSeat' in json else False
    user_id = uuid.UUID(authenticated_userid(request))
    dt = datetime.datetime.utcnow()
    voucher_type = VoucherType.by_name('Regular Bill')

    kot_id = DBSession.query(func.max(Voucher.kot_id)).scalar()
    if kot_id is None:
        kot_id = 1
    else:
        kot_id += 1

    is_bill = request.GET.get('type', 'Kot') == 'Bill'
    if is_bill:
        bill_id = DBSession.query(func.max(Voucher.bill_id)).filter(Voucher.type == voucher_type).scalar()
        if bill_id is None:
            bill_id = 1
        else:
            bill_id += 1

    voucher = Voucher(dt, dt, dt, voucher_type, kot_id, bill_id if is_bill else None, user_id, food_table_id, pax,
                      per_seat)

    DBSession.add(voucher)
    for kot_json in json['Kots']:
        kot_code = DBSession.query(func.max(Kot.code)).scalar()
        if kot_code is None:
            kot_code = 1
        else:
            kot_code += 1

        kot = Kot(kot_code, food_table_id, dt, user_id)
        voucher.kots.append(kot)
        for inv_json in kot_json['Inventories']:
            product = Product.by_id(uuid.UUID(inv_json['Product']['ProductID']))
            quantity = inv_json['Quantity']
            discount = inv_json['Discount']
            inv = Inventory(0, product.id, quantity, product.price, discount, product.is_happy_hour,
                            product.service_tax_id, product.service_tax.rate, product.vat_id, product.vat.rate,
                            product.service_charge, product.sc_taxable)
            inv.chair = inv_json['Chair'] if voucher.per_seat else 0
            kot.inventories.append(inv)
    transaction.commit()
    return {}


