import com.gridnine.xtrip.common.model.EntityReference
import com.gridnine.xtrip.common.model.entity.EntityStorage
import com.gridnine.xtrip.common.model.profile.Address
import com.gridnine.xtrip.common.model.profile.SalesPoint
import com.gridnine.xtrip.common.reports.model.AirTicketsTemplateReportParameters
import com.gridnine.xtrip.common.reports.model.AirTicketsTemplateReportTicket
import com.gridnine.xtrip.common.util.CollectionUtil
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 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 printHead(AirTicketsTemplateReportParameters airTicketParams) {
    rowHeight(15)
    text('Наименование/ код Агента:', 'center-bold', 3, 1)
    4.times {nextColumn()}
    text(airTicketParams?.agency?.caption + '/' + parameters['agency_code'], 'center-bold', 3, 1)
    nextRow()
    rowHeight(15)
    nextColumn()
    text('Реестр оформленных перевозочных документов по ВПД МВД', 'center', 12, 1)
    nextRow()
    rowHeight(15)
    nextColumn()
    SimpleDateFormat sdf = new SimpleDateFormat('dd.MM.yyyy')
    text('За период с ' + sdf.format(airTicketParams.periodBegin)
            + ' по ' + sdf.format(airTicketParams.periodEnd), 'center', 12, 1)
    nextRow()
}

def printEmptyBorderedCell() {
    text('', 'left-bold-border')
    nextColumn()
}

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

def printColumnHeaderBold(def num) {
    number(num, 'center-bold-border')
    nextColumn()
}

def printTitle() {
    rowHeight(70)
    printColumnHeader('№ п/п', 5)
    printColumnHeader('3-х значный цифровой код', 8)
    printColumnHeader('№ ВПД', 15)
    printColumnHeader('№ авиабилета', 15)
    printColumnHeader('Пункт оформления авиабилета, контрольный номер', 15)
    printColumnHeader('Вид тарифа', 15)
    printColumnHeader('Маршрут следования', 18)
    printColumnHeader('Дата продажи', 12)
    printColumnHeader('Дата вылета', 12)
    printColumnHeader('Номер рейса', 10)
    printColumnHeader('Тариф', 12)
    printColumnHeader('Тариф с учетом скидки', 12)
    printColumnHeader('Сборы включенные в авиабилет', 15)
    printColumnHeader('Итого', 12)
    nextRow()
    rowHeight(15)
    for (int i = 1; i < 15; i++) {
        printColumnHeaderBold(i)
    }
    nextRow()
}

def printTickets() {

    def getSalesPointAddress = { EntityReference<SalesPoint> ref ->
        SalesPoint salesPoint = EntityStorage.get().resolve(ref)?.entity
        List<Address> addresses = salesPoint?.addresses
        String result = ''
        if(CollectionUtil.isNotEmpty(addresses)) {
            result = addresses.get(0)?.city?.caption
        }
        return result
    }

    int index = 0
    rowHeight(30)
    allTickets.each { AirTicketsTemplateReportTicket ticket ->
        number(++index, 'center-border')
        nextColumn()
        cellFill('')
        nextColumn()
        cellFill(ticket.militaryClaimNumber)
        nextColumn()
        cellFill(ticket.validatingCarrierNumber + ' ' + ticket.ticketNumber)
        nextColumn()
        cellFill(getSalesPointAddress(ticket.salesPoint) + ", " + TextUtil.nonNullStr(ticket.validator))
        nextColumn()
        cellFill(ticket.fareBasisLine)
        nextColumn()
        cellFill(ticket.routeLine)
        nextColumn()
        cellFill(ticket.issueDate)
        nextColumn()
        cellFill(ticket.departureDate)
        nextColumn()
        cellFill(CollectionUtil.collectionToString(ticket.flightNumbers, ' ', true))
        nextColumn()
        cellFill(ticket.equivalentFare)
        nextColumn()
        cellFill(ticket.equivalentFare)
        nextColumn()
        cellFill(ticket.taxesSum)
        nextColumn()
        BigDecimal sum = MiscUtil.sum(ticket.equivalentFare, ticket.taxesSum)
        cellFill(sum)
        nextRow()
    }
    2.times {printEmptyBorderedCell()}
    text('Итого продажа:', 'left-bold-border', 7, 1)
    7.times {nextColumn()}
    printEmptyBorderedCell()
    4.times {
        if (index > 0) {
            cellFill(Formula.getSumFormulaByRow(cellIndex(-index, 0), cellIndex(-1, 0)))
        } else {
            cellFill(BigDecimal.ZERO)
        }
        nextColumn()
    }
    nextRow()
    nextColumn()
    text('ИТОГО ВОИНСКИХ ПЕРЕВОЗОЧНЫХ ДОКУМЕНТОВ ' + index + ' ШТ.', 'center', 7, 1)
    nextRow()
}

def printEnd() {
    2.times {nextRow()}
    5.times {nextColumn()}
    text('Генеральный директор', 'center', 3, 1)
    3.times {nextColumn()}
    text(parameters['ceo_name'], 'center', 3, 1)
    nextRow()
    5.times {nextColumn()}
    text('Главных бухгалтер', 'center', 3, 1)
    3.times {nextColumn()}
    text(parameters['chief_accountant_name'], 'center', 3, 1)
}

page{'Реестр по ВПД МВД'} {
    AirTicketsTemplateReportParameters airTicketParams = parameters.params
    printHead(airTicketParams)
    printTitle()
    printTickets()
    printEnd()
}