package com.gridnine.xtrip.server.reports.templates

import com.gridnine.xtrip.common.vip.model.booking.transfers.TransferProductIndex;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.math.BigDecimal;
import com.gridnine.xtrip.server.vip.transfers.ServiceType

createStyle(name: 'title', fontBold: false,  h_alignment: 'LEFT', v_alignment: 'CENTER', fontHeight:8)
createStyle(name: 'header',fontBold: false,  h_alignment: 'CENTER', v_alignment: 'CENTER', fontHeight:10, leftBorder:'MEDIUM', rightBorder:'MEDIUM', topBorder:'MEDIUM', bottomBorder:'MEDIUM', wrapText: true, foreground: 'GREY_25_PERCENT')
createStyle(name: 'data',fontBold: false,  h_alignment: 'CENTER', v_alignment: 'CENTER', fontHeight:10, leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN')
createStyle(name: 'textData', parent: 'data')
createStyle(name: 'numberData', parent: 'data', h_alignment: 'RIGHT')
createStyle(name: 'total', fontBold : true, h_alignment: 'LEFT', v_alignment: 'CENTER', fontHeight:10, leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN')
createStyle(name: 'numberTotal', parent: 'total', h_alignment: 'RIGHT')

titleRowHeight = 10;
headerRowHeight = 40;
dataRowHeight = 12;
totalRowHeight = 12;
groupDelimeterHeight = 12;

class Aggregator {
    private BigDecimal totalClientProductPrice = BigDecimal.ZERO;
    private BigDecimal clientFee = BigDecimal.ZERO;
    
    public void append(TransferProductIndex transfer) {
        if (transfer.totalClientProductPrice != null) {
            totalClientProductPrice = totalClientProductPrice.add(transfer.totalClientProductPrice)
        }
        if (transfer.clientFee != null) {
            clientFee = clientFee.add(transfer.clientFee)
        }
    }
}

def printTitle() {
    int titleCellWidth = 11;
    
    nextRow()
    rowHeight(titleRowHeight)
    
    nextRow()
    rowHeight(titleRowHeight)
    text('Отчёт по продажам услуги трансфер', 'title', titleCellWidth, 0);
    
    nextRow()
    rowHeight(titleRowHeight)
    text('Дата составления отчёта: ' + parameters['REPORT_DATE'], 'title', titleCellWidth, 0);
    
    nextRow()
    rowHeight(titleRowHeight)
    text('Период: ' + parameters['REPORT_PERIOD'], 'title', titleCellWidth, 0);
    
    if (!parameters['SUBAGENTS'].empty) {
        nextRow()
        rowHeight(titleRowHeight)
        text('По субагентам: ' + parameters['SUBAGENTS'], 'title', titleCellWidth, 0);
    }
    
    if (!parameters['CLIENTS'].empty) {
        nextRow()
        rowHeight(titleRowHeight)
        text('По клиентам: ' + parameters['CLIENTS'], 'title', titleCellWidth, 0);
    }
    
    if (!parameters['AGENTS'].empty) {
        nextRow()
        rowHeight(titleRowHeight)
        text('По агентам: ' + parameters['AGENTS'], 'title', titleCellWidth, 0);
    }
    
    if (!parameters['SUPPLIER_TYPES'].empty) {
        nextRow()
        rowHeight(titleRowHeight)
        text('По поставщикам: ' + parameters['SUPPLIER_TYPES'], 'title', titleCellWidth, 0)
    }
    
    if (parameters['GROUP_BY_AGENTS']) {
        nextRow()
        rowHeight(titleRowHeight)
        text('сгруппированный по агентам', 'title', titleCellWidth, 0);
    } else if (parameters['GROUP_BY_CLIENTS']) {
        nextRow()
        rowHeight(titleRowHeight)
        text('сгруппированный по клиентам', 'title', titleCellWidth, 0);
    }
    
    nextRow()
    rowHeight(titleRowHeight)
}

def printHeader() {
    
    nextRow()
    rowHeight(headerRowHeight)
    
    text('Код субагента', 'header')
    columnWidth(22)
    
    nextColumn()
    text('Выписывающий агент', 'header')
    columnWidth(30)
    
    nextColumn()
    text('Направление', 'header')
    columnWidth(50)
    
    nextColumn()
    text('Статус', 'header')
    columnWidth(20)
    
    nextColumn()
    text('Дата', 'header')
    columnWidth(15)
    
    nextColumn()
    text('Номер заказа', 'header')
    columnWidth(20)
    
    nextColumn()
    text('Номер заказа поставщика', 'header')
    columnWidth(20)
    
    nextColumn()
    text("Класс обслуживания", "header")
    columnWidth(20)
    
    nextColumn()
    text("Тип услуги", "header")
    columnWidth(30)
    
    nextColumn()
    text("Стоимость, руб.", "header")
    columnWidth(20)
    
    nextColumn()
    text("Сборы ПРТБ")
    columnWidth(20)
    
    nextColumn()
    text("Итого", "header")
    columnWidth(20)
    
}

String getDateString(Date date) {
    if (date == null) {
        return ""
    }
    SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");
    return format.format(date);
}

def String getServiceTypeString(ServiceType serviceType) {
    if (serviceType == null) {
        return null;
    } else if (serviceType == ServiceType.TRANSFER) {
        return "трансфер"
    } else if (serviceType == ServiceType.CAR_RENTAL_WITH_A_DRIVER) {
        return "аренда с водителем"
    } else {
        throw new RuntimeException("invalid serviceType: " + serviceType);
    }
}

def BigDecimal getSum(BigDecimal a, BigDecimal b) {
    if (a == null) {
        return b
    } else if (b == null) {
        return a
    } else {
        return a.add(b);
    }
}

String getAgentName(TransferProductIndex transfer) {
    if (transfer.agentFirstName != null && transfer.agentLastName != null) {
        return transfer.agentFirstName + ' ' + transfer.agentLastName
    }
    if (transfer.agentFirstName != null) {
        return transfer.agentFirstName
    }
    if (transfer.agentLastName != null) {
        return transfer.agentLastName
    }
    return null
}

def printTransfer(TransferProductIndex transfer) {
    nextRow()
    rowHeight(dataRowHeight)
    
    text(transfer.subagencyCode, 'textData')
    
    nextColumn()
    text(getAgentName(transfer), 'textData')
    
    nextColumn()
    text(transfer.startPlaceName + ' - ' + transfer.endPlaceName, 'textData')
    
    nextColumn()
    text(transfer.status.toString(), 'textData')
    
    nextColumn()
    text(getDateString(transfer.issueDate), 'textData')
    
    nextColumn()
    text(transfer.bookingNumber, 'textData')
    
    nextColumn()
    text(transfer.systemNumber, 'textData')
    
    nextColumn()
    text(transfer.carClass, "textData")
        
    nextColumn()
    text(getServiceTypeString(transfer.serviceType), "textData")
    
    nextColumn()
    number(transfer.totalClientProductPrice, "numberData")
    
    nextColumn()
    number(transfer.clientFee, "numberData")
    
    nextColumn()
    number(getSum(transfer.totalClientProductPrice, transfer.clientFee), 'numberData')
}

def printAggregator(Aggregator aggregator) {
    nextRow()
    rowHeight(totalRowHeight)
    
    int totalCellWidth = 9
    text('ИТОГО', 'total', totalCellWidth, 0);
    
    totalCellWidth.times {nextColumn()};
    number(aggregator.totalClientProductPrice, "numberTotal")
    
    nextColumn()
    number(aggregator.clientFee, "numberTotal")
    
    nextColumn()
    number(getSum(aggregator.totalClientProductPrice, aggregator.clientFee), "numberTotal")
}

def isGrouping() {
    return parameters['GROUP_BY_AGENTS'] || parameters['GROUP_BY_CLIENTS'];
}

def isNextGroup(TransferProductIndex previousTransfer, TransferProductIndex currentTransfer) {
    if (!isGrouping() || previousTransfer == null) {
        return false;
    }
    if (currentTransfer == null) {
        return true;
    }
    if (parameters['GROUP_BY_AGENTS']) {
        return previousTransfer.agent != currentTransfer.agent;
    }
    if (parameters['GROUP_BY_CLIENTS']) {
        return previousTransfer.clientProfile != currentTransfer.clientProfile;
    }
    throw new RuntimeException("something wrong");
}

def checkNextGroup(TransferProductIndex previousTransfer, TransferProductIndex currentTransfer, Aggregator groupAggregator) {
    if (isNextGroup(previousTransfer, currentTransfer)) {
        printAggregator(groupAggregator);
        nextRow();
        rowHeight(groupDelimeterHeight);
        groupAggregator = new Aggregator();
    }
    return groupAggregator;
}

printTitle()
printHeader()
Aggregator globalAggregator = new Aggregator();
Aggregator groupAggregator = new Aggregator();
TransferProductIndex previousTransfer = null;

tickets {
    groupAggregator = checkNextGroup(previousTransfer, it, groupAggregator)
    globalAggregator.append(it);
    groupAggregator.append(it);
    printTransfer(it)
    previousTransfer = it;
}

checkNextGroup(previousTransfer, null, groupAggregator)
printAggregator(globalAggregator)
