from flask import Blueprint, request, Response
import io
import json
import pandas as pd
import numpy as np
import datetime


ventas_blueprint = Blueprint('ventas', __name__,)


def format_data(data):
    df = pd.DataFrame(data)
    int_columns = ['Departamento', 'Estacionamientos', 'Bodegas']
    for col in int_columns:
        df[col] = pd.to_numeric(df[col], errors='ignore')
    float_columns = ['Valor Promesa', 'Pie', 'Pie Pagado', '% Pie Pagado', 'Bono Pie', 'Valor Operador',
                     'Premios', 'Subsidio', 'Ahorro', 'Credito', 'Valor Ests & Bods', 'Valor Neto',
                     'UF/m²*', 'Comision', 'Venta s/Comision', 'Precio']
    for col in float_columns:
        if col in df.columns:
            df[col] = pd.to_numeric(df[col], errors='coerce')
    df = df.replace(np.nan, 0, regex=True)

    df['Fecha Venta'] = pd.to_datetime(df['Fecha Venta'], format='%Y-%m-%d')
    df = df.sort_values(by=['Fecha Venta', 'Departamento'])
    df['Fecha Venta'] = df['Fecha Venta'].dt.strftime('%d.%m.%Y')

    return df


def format_columns(workbook, columns):
    column_settings = [{'header': column} for column in columns]

    center_format = workbook.add_format({'align': 'center'})
    amount_format = workbook.add_format({'num_format': '#,##0.00'})
    percent_format = workbook.add_format({'num_format': '0.00%'})

    amount_columns = ['m² Ponderados', 'Valor Promesa', 'Pie', 'Pie Pagado', 'Bono Pie', 'Valor Operador', 'Premios',
                      'Subsidio', 'Ahorro', 'Credito', 'Valor Ests & Bods', 'Valor Neto', 'UF/m²*', 'Comision',
                      'Venta s/Comision', 'Precio']
    center_columns = ['Departamento', 'Estacionamientos', 'Bodegas']
    sum_columns = ['m² Ponderados', 'Valor Promesa', 'Pie', 'Pie Pagado', 'Bono Pie', 'Subsidio', 'Ahorro', 'Credito',
                   'Valor Operador', 'Premios', 'Valor Ests & Bods', 'Valor Neto', 'Comision']
    count_columns = ['Departamento', 'Estacionamientos', 'Bodegas']

    for (k, col) in enumerate(column_settings):
        if col['header'] in amount_columns:
            column_settings[k]['format'] = amount_format
        if col['header'] in center_columns:
            column_settings[k]['format'] = center_format
        if col['header'] in sum_columns:
            column_settings[k]['total_function'] = 'sum'
        if col['header'] in count_columns:
            column_settings[k]['total_function'] = 'count'
        if col['header'] == '% Pie Pagado':
            column_settings[k]['format'] = percent_format
        if col['header'] == 'Propietario':
            column_settings[k]['total_string'] = 'TOTAL'

    return column_settings


def format_excel(workbook, worksheet, data):
    center_format = workbook.add_format({'align': 'center'})
    amount_format = workbook.add_format({'num_format': '#,##0.00'})
    percent_format = workbook.add_format({'num_format': '0.00%'})

    amount_columns = ['m² Ponderados', 'Valor Promesa', 'Pie', 'Pie Pagado', 'Bono Pie', 'Valor Operador', 'Premios',
                      'Subsidio', 'Ahorro', 'Credito', 'Valor Ests & Bods', 'Valor Neto', 'UF/m²*', 'Comision',
                      'Venta s/Comision', 'Precio']
    center_columns = ['Departamento', 'Estacionamientos', 'Bodegas']

    for col in amount_columns:
        if col not in data.columns:
            continue
        k = data.columns.get_loc(col) + 1
        worksheet.set_column(k, k, cell_format=amount_format)
    for col in center_columns:
        if col not in data.columns:
            continue
        k = data.columns.get_loc(col) + 1
        worksheet.set_column(k, k, cell_format=center_format)
    col = '% Pie Pagado'
    k = data.columns.get_loc(col) + 1
    worksheet.set_column(k, k, cell_format=percent_format)

    return worksheet


@ventas_blueprint.route('', methods=['POST'])
def ventas():
    data = json.loads(request.data)
    output = io.BytesIO()
    writer = pd.ExcelWriter('tmp.xlsx', engine='xlsxwriter')
    df = format_data(data['data'])

    start_row = 4
    if 'Compañía' in data:
        start_row += 1
    df.to_excel(writer, startrow=start_row+1, startcol=1, header=False, index=False, sheet_name='Ventas')
    wb = writer.book
    wb.filename = output

    title_format = wb.add_format({'font_size': 16, 'bold': True})
    ws = writer.sheets['Ventas']
    (max_row, max_col) = df.shape

    if 'Compañía' in data:
        ws.merge_range(1, 1, 1, max_col, data['Compañía'])
    ws.merge_range(start_row-3, 1, start_row-3, max_col, data['Proyecto'], cell_format=title_format)
    ws.write_string(start_row-2, 1, 'Ventas')
    column_settings = format_columns(wb, df.columns)
    ws.add_table(start_row, 1, max_row+start_row+1, max_col, {'name': 'Ventas', 'total_row': 1,
                                                              'columns': column_settings,
                                                              'style': 'Table Style Medium 1'})
    ws = format_excel(wb, ws, df)

    column_widths = {
        'B': 46,
        'C': 16,
        'D': 18,
        'E': 10,
        'F': 13,
        'G': 7,
        'H': 8,
        'I': 16,
        'J': 16,
        'K': 13,
        'L': 14
    }
    for (col, wd) in column_widths.items():
        ws.set_column('{0}:{0}'.format(col), wd)

    writer.save()
    output.seek(0)
    date = datetime.date.today()
    filename = "Informe de Ventas - {0} - {1}.xlsx".format(data['Proyecto'], date.strftime('%Y-%m-%d'))
    return Response(output, mimetype="application/ms-excel",
                    headers={"Content-Disposition": "attachment;filename={0}".format(filename),
                             "Content-Type": 'application/octet-stream; charset=utf-8'})
