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.dict.GdsName
import com.gridnine.xtrip.common.model.entity.EntityStorage
import com.gridnine.xtrip.common.model.profile.Organization
import com.gridnine.xtrip.common.model.profile.Person
import com.gridnine.xtrip.common.reports.model.AirTicketsTemplateReportParameters
import com.gridnine.xtrip.common.reports.model.AirTicketsTemplateReportTicket
import com.gridnine.xtrip.common.util.MiscUtil

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', 9, 1)
    nextRow()
    rowHeight(45)
    nextColumn()
    text('за период с ' + formatDateToString(periodBegin) + ' по ' + formatDateToString(periodEnd)
            + '\n' + 'авиакомпания "ЯК" на бланках ' + blankSerialNum + '\n' + 'ВВЛ', 'center', 9, 1)
    nextRow()
    rowHeight(15)
    nextRow()
}

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

def printTitle() {
    rowHeight(45)
    nextColumn()
    columnWidth(5)
    text('№ п/п', 'center-border')
    nextColumn()
    printColumnHeader('Номер МСО', 15)
    printColumnHeader('№ кассира', 10)
    printColumnHeader('Дата операции', 15)
    printColumnHeader('Сумма МСО', 12)
    printColumnHeader('Добор до тарифа', 12)
    printColumnHeader('Сбор за бланк', 12)
    printColumnHeader('Комиссия', 12)
    printColumnHeader('Номер ссылочного БСО', 15)
    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 printTickets() {
    int index = 0
    rowHeight(30)
    allTickets.each {AirTicketsTemplateReportTicket ticket ->
        nextColumn()
        number(++index, 'center-border')
        nextColumn()
        cellFill(ticket.ticketNumber)
        nextColumn()
        String agentCode = null
        Person agent = EntityStorage.get().resolve(ticket.agent)?.getEntity()
        if (agent) {
            agent.getGdsReferences().each {
                if (it.gdsName == GdsName.SIRENA) {
                    agentCode = it.reference
                    return
                }
            }
        }
        cellFill(agentCode)
        nextColumn()
        cellFill(ticket.issueDate)
        nextColumn()
        cellFill(!MiscUtil.isZero(ticket.equivalentFare, true) ? ticket.equivalentFare : ticket.penalty)
        nextColumn()
        cellFill(BigDecimal.ZERO)
        nextColumn()
        cellFill(ticket.ruTaxAmount)
        nextColumn()
        cellFill(ticket.vendorCommissionValue)
        nextColumn()
        cellFill(ticket.relatedTicketNumber)
        nextRow()
    }
    nextColumn()
    text('Итого:', 'center-bold-border', 4, 1)
    4.times {nextColumn()}
    if (index > 0) {
        4.times {
            cellFill(Formula.getSumFormulaByRow(cellIndex(-index, 0), cellIndex(-1, 0)))
            nextColumn()
        }
    } else {
        4.times {
            cellFill('')
            nextColumn()
        }
    }
    cellFill('')
    nextRow()
}

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

page{'Реестр МСО'} {
    AirTicketsTemplateReportParameters airTicketParams = parameters.params
    printHead(airTicketParams)
    printTitle()
    printTickets()
    printEnd()
}