import com.gridnine.xtrip.common.l10n.model.LocaleHelper
import com.gridnine.xtrip.common.model.EntityContainer
import com.gridnine.xtrip.common.model.EntityReference
import com.gridnine.xtrip.common.model.booking.air.Tax
import com.gridnine.xtrip.common.model.entity.EntityStorage
import com.gridnine.xtrip.common.model.profile.Organization
import com.gridnine.xtrip.common.reports.model.AirTicketsTemplateReportParameters
import com.gridnine.xtrip.common.reports.model.AirTicketsTemplateReportTicket
import com.gridnine.xtrip.common.util.MiscUtil
import com.gridnine.xtrip.common.util.TextUtil

import java.text.SimpleDateFormat

createStyle(name: "left", h_alignment: "LEFT")
createStyle(name: "right", h_alignment: "RIGHT")
createStyle(name: "center", h_alignment: "CENTER")
createStyle(name: "left-bold", h_alignment: "LEFT", fontBold : true)
createStyle(name: "right-bold", h_alignment: "RIGHT", fontBold : true)
createStyle(name: "center-bold", h_alignment: "CENTER", fontBold : true)
createStyle(name: "left-bold-border", h_alignment: "LEFT", fontBold : true,
        leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "right-bold-border", h_alignment: "RIGHT", fontBold : true,
        leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "center-bold-border", h_alignment: "CENTER", fontBold : true,
        leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "left-border", h_alignment: "LEFT", leftBorder:'THIN', rightBorder:'THIN',
        topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "right-border", h_alignment: "RIGHT", leftBorder:'THIN', rightBorder:'THIN',
        topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "center-border", h_alignment: "CENTER", leftBorder:'THIN', rightBorder:'THIN',
        topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "dateDataBold", format: 'm/d/yy', parent: 'left-bold-border')
createStyle(name: "dateData", format: 'm/d/yy', parent: 'center-border')
createStyle(name: 'numberData', format: '#,##0.00', parent: 'center-border')

class Formula {
    String formula
    Formula(){}
    Formula(String formula) {
        this.formula = formula
    }

    static Formula getSumFormulaByRow (def start, def end) {
        return new Formula('SUM(' + start + ':' + end + ')')
    }
    static Formula getSumFormulaByCell(String... index) {
        def formula = ''
        for (int i=0; i<index.size(); i++) {
            if(i == 0) {
                formula += index[i]
            } else {
                formula += ',' + index[i]
            }
        }
        return new Formula('SUM(' + formula + ')')
    }
}

def printHead(AirTicketsTemplateReportParameters airTicketParams) {

    def getOrganizationName = { EntityReference<Organization> erO ->
        EntityContainer<Organization> ecO = EntityStorage.get().resolve(erO)
        Organization org = ecO?.entity
        return org?.fullName?.toString(LocaleHelper.RU_LOCALE)
    }

    def formatDateToString = { Date date ->
        SimpleDateFormat sdf = new SimpleDateFormat('dd.MM.yyyy')
        return sdf.format(date).toString()
    }

    def orgRef = airTicketParams.agency
    def periodBegin = airTicketParams.periodBegin
    def periodEnd = airTicketParams.periodEnd
    def blankSerialNum = parameters['blank_serial_number']
    rowHeight(45)
    nextRow()
    rowHeight(15)
    columnWidth(5)
    nextColumn()
    text('Реестр продажи авиаперевозок ' + getOrganizationName(orgRef), 'center-bold', 12, 1)
    nextRow()
    rowHeight(45)
    nextColumn()
    text('за период с ' + formatDateToString(periodBegin) + ' по ' + formatDateToString(periodEnd)
            + '\n' + 'авиакомпания "ЯК" на бланках ' + blankSerialNum + '\n' + 'ВВЛ', 'center', 12, 1)
    nextRow()
    rowHeight(15)
    nextRow()
}

def printColumnHeader(def str, def width) {
    columnWidth(width)
    text(str, 'center-bold-border')
    nextColumn()
}

def printTitle() {
    rowHeight(30)
    nextColumn()
    columnWidth(5)
    text('№ п/п', 'center-border')
    nextColumn()
    printColumnHeader('№ авиабилета', 15)
    printColumnHeader('Дата продажи', 15)
    printColumnHeader('Маршрут', 15)
    printColumnHeader('Вид тарифа', 15)
    printColumnHeader('Тариф', 10)
    printColumnHeader('Такса', 8)
    printColumnHeader('Такса', 8)
    printColumnHeader('Итого получено', 10)
    printColumnHeader('% ком', 8)
    printColumnHeader('Комиссия агента', 15)
    printColumnHeader('Причитается перевозчику',15)
    nextRow()
    rowHeight(15)
    nextColumn()
    text('Размер вознаграждения Агента 0%', 'left-bold-border', 12, 1)
    nextRow()
}

def cellFill(Object value) {
    if (value != null) {
        if (value instanceof Number) {
            number(value, 'numberData')
        } else if (value instanceof Date) {
            date(value,'dateData')
        } else if (value instanceof Formula){
            formula(value.formula,'numberData')
        } else {
            text(value, 'center-border')
        }
    } else {
        text('', 'center-border')
    }
}

def printSumRow(def rowName, def rowShift, int ind) {
    nextColumn()
    text(rowName, 'left-bold-border', 5, 1)
    5.times { nextColumn() }
    if (ind > 0) {
        4.times {
            cellFill(Formula.getSumFormulaByRow(cellIndex(-ind + rowShift, 0), cellIndex(-1 + rowShift, 0)))
            nextColumn()
        }
    } else {
        4.times {
            cellFill('')
            nextColumn()
        }
    }
    nextColumn()
    if (ind > 0) {
        2.times {
            cellFill(Formula.getSumFormulaByRow(cellIndex(-ind + rowShift, 0), cellIndex(-1 + rowShift, 0)))
            nextColumn()
        }
    } else {
        2.times {
            cellFill('')
            nextColumn()
        }
    }
    nextRow()
}

def printTickets() {

    def getYRTax = { AirTicketsTemplateReportTicket ticket ->
        BigDecimal result = BigDecimal.ZERO
        ticket.taxes.each {Tax tax ->
            if(TextUtil.isSame(tax.code, 'YR')) {
                 result = MiscUtil.sum(result, tax.equivalentAmount)
            }
        }
        return result
    }

    def getOtherTax = { AirTicketsTemplateReportTicket ticket ->
        BigDecimal result = BigDecimal.ZERO
        ticket.taxes.each {Tax tax ->
            if(!TextUtil.isSame(tax.code, 'YR')) {
                 result = MiscUtil.sum(result, tax.equivalentAmount)
            }
        }
        return result
    }

    int index = 0
    allTickets.each { AirTicketsTemplateReportTicket ticket ->
        nextColumn()
        number(++index, 'center-border')
        nextColumn()
        cellFill(ticket.ticketNumber)
        nextColumn()
        cellFill(ticket.issueDate)
        nextColumn()
        cellFill(ticket.routeLine)
        nextColumn()
        cellFill(ticket.fareBasisLine)
        nextColumn()
        cellFill(ticket.equivalentFare)
        nextColumn()
        cellFill(getOtherTax(ticket))
        nextColumn()
        BigDecimal yrTax = getYRTax(ticket)
        cellFill(yrTax)
        nextColumn()
        BigDecimal sum = MiscUtil.sum(ticket.equivalentFare, yrTax)
        cellFill(sum)
        nextColumn()
        cellFill(ticket.vendorCommissionRate)
        nextColumn()
        cellFill(ticket.vendorCommissionValue)
        nextColumn()
        BigDecimal result = MiscUtil.sub(sum, ticket.vendorCommissionValue)
        cellFill(result)
        nextRow()
    }
    printSumRow('Итог по вознаграждению Агента 0%:', 0, index)
    printSumRow('Общий итог:', -1, index)
}

def printEnd() {
    nextRow()
    nextColumn()
    text('М.П.', 'left', 5, 1)
    2.times {nextRow()}
    nextColumn()
    text('Отчет составил: _______________ (' + parameters['report_author_name'] + ')', 'left', 5, 1)
}

page{'Реестр продажи'} {
    AirTicketsTemplateReportParameters airTicketParams = parameters.params
    printHead(airTicketParams)
    printTitle()
    printTickets()
    printEnd()
}