// Imports


import com.gridnine.xtrip.common.l10n.model.LocaleHelper
import com.gridnine.xtrip.common.model.booking.OperationBatch
import com.gridnine.xtrip.common.model.booking.TransportationType
import com.gridnine.xtrip.common.model.dict.MCOCategory
import com.gridnine.xtrip.common.model.entity.EntityStorage
import com.gridnine.xtrip.common.model.helpers.PersonalLocalizableNameFormatter
import com.gridnine.xtrip.common.model.helpers.SystemHelper
import com.gridnine.xtrip.common.model.system.MetadataKey
import com.gridnine.xtrip.common.reports.model.AirTicketsTemplateReportTicket
import com.gridnine.xtrip.common.reports.model.AirTicketsTemplateReportTicketType
import com.gridnine.xtrip.common.util.MiscUtil

import java.text.SimpleDateFormat

// Styles
createStyle(name: 'title', h_alignment: 'CENTER', v_alignment: 'CENTER', fontFamily: "TimesNewRoman")
createStyle(name: 'titleH1', fontHeight: 14, parent: 'title')
createStyle(name: 'titleH2', fontHeight: 12, parent: 'title')
createStyle(name: 'titleH3', fontHeight: 11, parent: 'title')
createStyle(name: 'header', h_alignment: 'CENTER', v_alignment: 'CENTER', fontHeight: 11, fontFamily: "TimesNewRoman")
createStyle(name: 'columnHeader', h_alignment: 'CENTER', parent: 'header')
createStyle(name: 'rowHeader', parent: 'header')
createStyle(name: 'data', h_alignment: 'CENTER', v_alignment: 'CENTER', fontHeight: 11, fontFamily: "TimesNewRoman")
createStyle(name: 'dataText', parent: 'data')
createStyle(name: 'dataNumber', format: '#,##0.00', parent: 'data')
createStyle(name: 'wrap', wrapText: true)
createStyle(name: 'ahl', h_alignment: 'LEFT')
createStyle(name: 'ahc', h_alignment: 'CENTER')
createStyle(name: 'ahr', h_alignment: 'RIGHT')
createStyle(name: 'avt', v_alignment: 'TOP')
createStyle(name: 'avc', v_alignment: 'CENTER')
createStyle(name: 'avb', v_alignment: 'BOTTOM')
createStyle(name: 'aac', h_alignment: 'CENTER', v_alignment: 'CENTER')
createStyle(name: 'bold', fontBold: true)
createStyle(name: 'italic', fontItalic: true)
createStyle(name: 'bt', topBorder: 'THICK')
createStyle(name: 'bl', leftBorder: 'THICK')
createStyle(name: 'bb', bottomBorder: 'THICK')
createStyle(name: 'br', rightBorder: 'THICK')
createStyle(name: 'ba', topBorder: 'THICK', leftBorder: 'THICK', bottomBorder: 'THICK', rightBorder: 'THICK')

// Closures
def period = {
    SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy")
    def periodBeginParameter = parameters['key-report-params']?.periodBegin
    def periodEndParameter = parameters['key-report-params']?.periodEnd
    return (periodBeginParameter ? sdf.format(periodBeginParameter) : "") +
            "-" +
            (periodEndParameter ? sdf.format(periodEndParameter) : "")
}

def agencyCode = {
    def organization = EntityStorage.get().resolve(parameters['key-report-params']?.agency)?.entity
    return organization ? SystemHelper.findMetadataAsString(organization.getMetadata(), MetadataKey.KEY_HZ_AGENCY_CODE) : 'Не указано'
}

def accountantName = {
    def person = EntityStorage.get().resolve(requestedParameter('accountant'))?.entity
    def format = new PersonalLocalizableNameFormatter(PersonalLocalizableNameFormatter.SIMPLE)
    return person ? format.format(person, LocaleHelper.RU_LOCALE, false) : '?'
}

def formatDate = {
    SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy")
    return it ? sdf.format(it) : ''
}

def date = {
    SimpleDateFormat format = new SimpleDateFormat("\"dd\" MMMM yyyy год", LocaleHelper.RU_LOCALE)
    return format.format(new Date())
}

page { 'Реестр обменов' } {

    // Set portrait mode
    landscape(true)

    // Set narrow margins
    margin(0.25, 0.25, 0.75, 0.75)

    // Set scale
    scale(100)

    // Set preserve mode
    preserve(true)

    //Sorting data by transportation type
    def flights = [:]
    flights = [(TransportationType.INTERNATIONAL): [], (TransportationType.DOMESTIC): []]

    tickets { AirTicketsTemplateReportTicket ticket ->
        if (ticket.type != AirTicketsTemplateReportTicketType.PRODUCT) {
            return
        }
        if (ticket.transportationType == TransportationType.INTERNATIONAL) {
            flights[TransportationType.INTERNATIONAL].add(ticket)
        } else if (ticket.transportationType == TransportationType.DOMESTIC) {
            flights[TransportationType.DOMESTIC].add(ticket)
        }
    }

// Report header
    rowHeight(17)
    text('РЕЕСТР ОБМЕНА ВВЛ/МВЛ', 'titleH3|bold|br', 17, 1)
    nextRow()
    text('EXCHANGE LIST Domestic routes', 'titleH3|italic|br', 17, 1)
    nextRow()

    text('Авиакомпания:', 'data|bold|bt|br', 3, 1)
    3.times { nextColumn() }
    text('АО «АВИАКОМПАНИЯ «АВРОРА»', 'data|bold|ba', 4, 2)
    4.times { nextColumn() }
    text('Код:', 'data|bold|bt|br', 2, 1)
    2.times { nextColumn() }
    text('ИЕ', 'data|bold|ba', 1, 2)
    nextColumn()
    text('Отчёт:', 'data|bold|bt|br', 3, 1)
    3.times { nextColumn() }
    text('1', 'data|bold|ba', 4, 2)
    nextRow()
    text('Airline:', 'data|bold|italic|bb|br', 3, 1)
    7.times { nextColumn() }
    text('Code:', 'data|bold|italic|bb|br', 2, 1)
    3.times { nextColumn() }
    text('Report:', 'data|bold|italic|bb|br', 3, 1)
    nextRow()

    text('Агент:', 'data|bold|bt|br', 3, 1)
    3.times { nextColumn() }
    text('Название Агента', 'data|bold|ba', 4, 2)
    4.times { nextColumn() }
    text('Код:', 'data|bold|bt|br', 2, 1)
    2.times { nextColumn() }
    text((agencyCode() ? agencyCode() : ''), 'data|bold|ba', 1, 2)
    nextColumn()
    text('Период:', 'data|bold|bt|br', 3, 1)
    3.times { nextColumn() }
    text(period(), 'data|bold|ba', 4, 2)
    nextRow()
    text('Agent:', 'data|bold|italic|bb|br', 3, 1)
    7.times { nextColumn() }
    text('Code:', 'data|bold|italic|bb|br', 2, 1)
    3.times { nextColumn() }
    text('Period:', 'data|bold|italic|bb|br', 3, 1)
    nextRow()
    text('', 'data|br', 17, 1)
    nextRow()

// Table header
    def drawTableHeader = {
        rowHeight(45)
        text('№ п/п', 'columnHeader|bt|br|bl', 1, 1)
        nextColumn()
        text('Номер документа', 'columnHeader|bt|br|bl', 3, 1)
        3.times { nextColumn() }
        text('Маршрут', 'columnHeader|bt|br|bl', 2, 1)
        2.times { nextColumn() }
        text('Доплата по тарифу', 'columnHeader|bt|br|bl', 2, 1)
        2.times { nextColumn() }
        text('Доплата по таске', 'columnHeader|bt|br|bl', 3, 1)
        3.times { nextColumn() }
        text('Штраф', 'columnHeader|bt|br|bl', 3, 1)
        3.times { nextColumn() }
        text('% комиссии', 'columnHeader|bt|br|bl', 1, 1)
        nextColumn()
        text('Сумма\nкомиссии', 'columnHeader|bt|br|bl', 1, 1)
        nextColumn()
        text('Итого', 'columnHeader|bt|br|bl', 1, 1)
        nextRow()

        rowHeight(30)
        text('Ref.No.', 'columnHeader|italic|br|bl', 1, 1)
        nextColumn()
        text('Document No.', 'columnHeader|italic|br|bl', 3, 1)
        3.times { nextColumn() }
        text('Route', 'columnHeader|italic|br|bl', 2, 1)
        2.times { nextColumn() }
        text('AL amount surcharge', 'columnHeader|italic|br|bl', 2, 1)
        2.times { nextColumn() }
        text('Taxes surcharge', 'columnHeader|italic|br|bl', 3, 1)
        3.times { nextColumn() }
        text('Penalty', 'columnHeader|italic|bb|br|bl', 3, 1)
        3.times { nextColumn() }
        text('% commission', 'columnHeader|italic|br|bl', 1, 1)
        nextColumn()
        text('Commission\namount', 'columnHeader|italic|br|bl', 1, 1)
        nextColumn()
        text('Total', 'columnHeader|italic|br|bl', 1, 1)
        nextRow()

        rowHeight(17)
        text('', 'columnHeader|italic|br|bl', 1, 1)
        nextColumn()
        text('', 'columnHeader|italic|br|bl', 3, 1)
        3.times { nextColumn() }
        text('', 'columnHeader|italic|br|bl', 2, 1)
        2.times { nextColumn() }
        text('', 'columnHeader|italic|br|bl', 2, 1)
        2.times { nextColumn() }
        text('', 'columnHeader|italic|br|bl', 3, 1)
        3.times { nextColumn() }
        text('Сумма', 'columnHeader|bt|br|bl', 1, 1)
        nextColumn()
        text('№ MCO', 'columnHeader|bt|br|bl', 2, 1)
        2.times { nextColumn() }
        text('', 'columnHeader|italic|br|bl', 1, 1)
        nextColumn()
        text('', 'columnHeader|italic|br|bl', 1, 1)
        nextColumn()
        text('', 'columnHeader|italic|br|bl', 1, 1)
        nextRow()

        text('', 'columnHeader|italic|bb|br|bl', 1, 1)
        nextColumn()
        text('', 'columnHeader|italic|bb|br|bl', 3, 1)
        3.times { nextColumn() }
        text('', 'columnHeader|italic|bb|br|bl', 2, 1)
        2.times { nextColumn() }
        text('', 'columnHeader|italic|bb|br|bl', 2, 1)
        2.times { nextColumn() }
        text('', 'columnHeader|italic|bb|br|bl', 3, 1)
        3.times { nextColumn() }
        text('Amount', 'columnHeader|italic|bb|br|bl', 1, 1)
        nextColumn()
        text('MCO №', 'columnHeader|italic|bb|br|bl', 2, 1)
        2.times { nextColumn() }
        text('', 'columnHeader|italic|bb|br|bl', 1, 1)
        nextColumn()
        text('', 'columnHeader|italic|bb|br|bl', 1, 1)
        nextColumn()
        text('', 'columnHeader|italic|bb|br|bl', 1, 1)
        nextRow()
    }

    def drawTableTop = {
        rowHeight(17)
        text('1', 'columnHeader|ba', 1, 1)
        nextColumn()
        text('2', 'columnHeader|ba', 1, 1)
        nextColumn()
        text('3', 'columnHeader|ba', 2, 1)
        2.times { nextColumn() }
        text('4', 'columnHeader|ba', 2, 1)
        2.times { nextColumn() }
        text('5', 'columnHeader|ba', 2, 1)
        2.times { nextColumn() }
        text('6', 'columnHeader|ba', 3, 1)
        3.times { nextColumn() }
        text('7', 'columnHeader|ba', 1, 1)
        nextColumn()
        text('8', 'columnHeader|ba', 2, 1)
        2.times { nextColumn() }
        text('9', 'columnHeader|ba', 1, 1)
        nextColumn()
        text('10', 'columnHeader|ba', 1, 1)
        nextColumn()
        text('11', 'columnHeader|ba', 1, 1)
        nextRow()
    }

// Table

    Total total
    Total grandTotal = new Total()
    int counter = 0

    def drawSection = {
        number(++counter, 'dataText|bold|ba', 1, 1)
        nextColumn()
        text(it.relatedTicketNumber ? it.relatedTicketNumber : "", 'dataText|bold|ba')
        nextColumn()
        text(it.ticketNumber ? it.ticketNumber : "", 'dataText|bold|ba', 2, 1)
        2.times { nextColumn() }
        text(it.routeLine, 'dataText|bold|ba', 2, 1)
        2.times { nextColumn() }

        def tariff = it.equivalentFare ? it.equivalentFare : BigDecimal.ZERO
        number(tariff, 'dataNumber|ba', 2, 1)
        total.tariff = MiscUtil.sum(total.tariff, tariff)
        2.times { nextColumn() }
        def taxesSum = it.taxesSum ? it.taxesSum : BigDecimal.ZERO
        number(taxesSum, 'dataNumber|ba', 3, 1)
        total.tax = MiscUtil.sum(total.tax, taxesSum)
        3.times { nextColumn() }
        def penalty = it.penalty ? it.penalty : it.penaltyMCO ? it.penaltyMCO : BigDecimal.ZERO
        number(penalty, 'dataNumber|ba', 1, 1)
        total.penalty = MiscUtil.sum(total.penalty, penalty)
        nextColumn()
        text(it.penaltyMCONumber ? it.penaltyMCONumber : '', 'dataText|ba', 2, 1)
        2.times { nextColumn() }
        number(it.vendorCommissionRate, 'dataText|ba', 1, 1)
        nextColumn()
        def vendorComValue = it.vendorCommissionValue ? it.vendorCommissionValue : BigDecimal.ZERO
        number(vendorComValue, 'dataNumber|ba', 1, 1)
        total.commission = MiscUtil.sum(total.commission, vendorComValue)
        nextColumn()
        def vendorSum = MiscUtil.sub(MiscUtil.sum(tariff, taxesSum, penalty), vendorComValue)
        number(vendorSum, 'dataNumber|ba', 1, 1)
        total.vendorSum = MiscUtil.sum(total.vendorSum, vendorSum)
        nextRow()
    }

    //Total
    def drawTotal = {
        text('Итого:', 'dataText|bold|italic|bt|br|bl', 6, 1)
        6.times { nextColumn() }
        number(it.tariff, 'dataNumber|bold|ba', 2, 2)
        2.times { nextColumn() }
        number(it.tax, 'dataNumber|bold|ba', 3, 2)
        3.times { nextColumn() }
        number(it.penalty, 'dataNumber|bold|ba', 1, 2)
        nextColumn()
        text('', 'dataText|bold|ba', 2, 2)
        2.times { nextColumn() }
        text('', 'dataText|bold|ba', 1, 2)
        nextColumn()
        number(it.commission, 'dataNumber|bold|ba', 1, 2)
        nextColumn()
        number(it.vendorSum, 'dataNumber|bold|ba', 1, 2)
        nextRow()
        text('Total:', 'dataText|bold|italic|bb|br|bl', 6, 1)
    }

    def drawGrandTotal = {
        rowHeight(17)
        text('Всего', 'dataText|bold|br|bt|bl', 6, 1)
        6.times { nextColumn() }
        number(it.tariff, 'dataNumber|bold|ba', 2, 2)
        2.times { nextColumn() }
        number(it.tax, 'dataNumber|bold|ba', 3, 2)
        3.times { nextColumn() }
        number(it.penalty, 'dataNumber|bold|ba', 1, 2)
        nextColumn()
        text('', 'dataText|bold|ba', 2, 2)
        2.times { nextColumn() }
        text('', 'dataText|bold|ba', 1, 2)
        nextColumn()
        number(it.commission, 'dataNumber|bold|ba', 1, 2)
        nextColumn()
        number(it.vendorSum, 'dataNumber|bold|ba', 1, 2)
        nextRow()
        text('Subtotal:', 'dataText|bold|italic|br|bb|bl', 6, 1)
    }

    def drawTable = {
        total = new Total()
        flights.get(it).each { drawSection(it) }
        drawTotal(total)
        grandTotal = grandTotal.sum(total)
        counter = 0
    }

    fillTable:
    {
        drawTableHeader('ВВЛ')
        drawTableTop()
        drawTable(TransportationType.DOMESTIC)
        nextRow()
        drawTableHeader('МВЛ')
        drawTable(TransportationType.INTERNATIONAL)
        nextRow()
        drawGrandTotal(grandTotal)
    }

    //Footer
    4.times { nextRow() }
    text('ПОДПИСИ СТОРОН', 'dataText|bold', 17, 1)
    nextRow()
    text('ПЕРЕВОЗЧИК', 'dataText', 3, 1)
    9.times { nextColumn() }
    text('АГЕНТ', 'dataText', 3, 1)
    nextRow()
    text('_______________/                        /', 'dataText', 3, 1)
    9.times { nextColumn() }
    text('_______________/                        /', 'dataText', 3, 1)
    2.times { nextRow() }
    text(date(), 'dataText', 3, 1)
    9.times { nextColumn() }
    text(date(), 'dataText', 3, 1)

    nextRow()
    columnWidth(10)
    nextColumn()
    columnWidth(12)
    nextColumn()
    columnWidth(10)
    nextColumn()
    columnWidth(6)
    nextColumn()
    columnWidth(10)
    nextColumn()
    columnWidth(12)
    nextColumn()
    columnWidth(10)
    nextColumn()
    columnWidth(10)
    nextColumn()
    columnWidth(10)
    nextColumn()
    columnWidth(10)
    nextColumn()
    columnWidth(10)
    nextColumn()
    columnWidth(14)
    nextColumn()
    columnWidth(10)
    nextColumn()
    columnWidth(10)
    nextColumn()
    columnWidth(12)
    nextColumn()
    columnWidth(10)
    nextColumn()
    columnWidth(10)

}

class Total {
    def tariff = BigDecimal.ZERO
    def tax = BigDecimal.ZERO
    def price = BigDecimal.ZERO
    def commission = BigDecimal.ZERO
    def vendorSum = BigDecimal.ZERO
    def penalty = BigDecimal.ZERO
    def taxYR = BigDecimal.ZERO

    Total sum(Total a) {
        tariff = MiscUtil.sum(tariff, a.tariff)
        tax = MiscUtil.sum(tax, a.tax)
        price = MiscUtil.sum(price, a.price)
        commission = MiscUtil.sum(commission, a.commission)
        vendorSum = MiscUtil.sum(vendorSum, a.vendorSum)
        penalty = MiscUtil.sum(penalty, a.penalty)
        taxYR = MiscUtil.sum(taxYR, a.taxYR)
        return this
    }
}