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.entity.EntityStorage
import com.gridnine.xtrip.common.model.profile.Organization
import com.gridnine.xtrip.common.model.system.PaymentType
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: "left-bold-italic-underline", h_alignment: "LEFT", fontBold : true, fontUnderline : "SINGLE", fontItalic : true)
createStyle(name: "right-bold-italic-underline", h_alignment: "RIGHT", fontBold : true, fontUnderline : "SINGLE", fontItalic : true)
createStyle(name: "center-bold", h_alignment: "CENTER", fontBold : true)
createStyle(name: "center-center-bold", h_alignment: "CENTER", v_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: "left-center-bold-border", h_alignment: "LEFT", v_alignment: "CENTER", 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, fontUnderline : "NONE", fontItalic : false)
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: "center-center-border", h_alignment: "CENTER", v_alignment: "CENTER", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "center-border-number", format: '#,##0.00', h_alignment: "CENTER", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "left-border-number", format: '#,##0.00', h_alignment: "LEFT", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "right-border-number", format: '#,##0.00', h_alignment: "RIGHT", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "right-bold-border-number", format: '#,##0.00', fontBold : true, h_alignment: "RIGHT", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "center-bold-border-number", format: '#,##0.00', h_alignment: "CENTER", fontBold : true, leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "center-center-border-number", format: '#,##0.00', h_alignment: "CENTER", v_alignment: "CENTER", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)

def printHead(AirTicketsTemplateReportParameters airTicketParams) {
    def getOrganizationName = { EntityReference<Organization> orgRef ->
        EntityContainer<Organization> orgCont = EntityStorage.get().resolve(orgRef)
        Organization org = orgCont?.entity
        return org?.fullName?.toString(LocaleHelper.RU_LOCALE)
    }

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

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

def printHeader() {
    nextRow(); nextRow(); rowHeight(15)

    nextColumn(); text("№ п/п", "center-bold-border")
    nextColumn(); text("№ БСО", "center-bold-border")
    nextColumn(); text("Тип док", "center-bold-border")
    nextColumn(); text("ФО", "center-bold-border")
    nextColumn(); text("Код АК", "center-bold-border")
    nextColumn(); text("Рейс", "center-bold-border")
    nextColumn(); text("Дата вылета", "center-bold-border")
    nextColumn(); text("Участок трансфера", "center-bold-border")
    nextColumn(); text("Код тарифа", "center-bold-border")
    nextColumn(); text("Тариф", "center-bold-border")
    nextColumn(); text("Такса РУ", "center-bold-border")
    nextColumn(); text("Топл. сбор", "center-bold-border")
    nextColumn(); text("Такса ТКП", "center-bold-border")
    nextColumn(); text("АГС", "center-bold-border")
    nextColumn(); text("Штраф", "center-bold-border")
    nextColumn(); text("Прочие сборы", "center-bold-border")
    nextColumn(); text("% ком", "center-bold-border")
    nextColumn(); text("Комиссия", "center-bold-border")
    nextColumn(); text("Взаиморасчет", "center-bold-border")
    nextColumn(); text("К билету", "center-bold-border")
    nextColumn(); text("К Б", "center-bold-border")
}

def printTickets() {
    def paymentTypes = { AirTicketsTemplateReportTicket ticket ->
        Set<String> paymentTypes = new LinkedHashSet<>()

        ticket.paymentTypes.each {
            if (it && it != PaymentType.TICKET) {
                paymentTypes.add(it.toString(LocaleHelper.RU_LOCALE))
            }
        }

        return TextUtil.join(", ", paymentTypes)
    }

    def taxAmount = { AirTicketsTemplateReportTicket ticket, String taxCode ->
        BigDecimal result = null

        ticket.getTaxes().each {
            if (TextUtil.isSame(taxCode, it.code, true)) {
                result = MiscUtil.sum(result, it.equivalentAmount)
            }
        }

        return result
    }

    def getOtherTax = { AirTicketsTemplateReportTicket ticket, String[] taxCode ->
        BigDecimal result = null
        ticket.getTaxes().each {
            if (!taxCode.contains(it.code)) {
                result = MiscUtil.sum(result, it.equivalentAmount)
            }
        }

        return result
    }

    SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy")
    int i = 0

    String[] exclude = ["RU", "YQ", "YR", "ZZ"]

    tickets { AirTicketsTemplateReportTicket ticket ->
        nextRow(); rowHeight(15)

        nextColumn(); text(String.valueOf(++i), "center-center-border")

        nextColumn()
        text((ticket.validatingCarrierNumber ? ticket.validatingCarrierNumber + " " : "") +
                (ticket.ticketNumber ? ticket.ticketNumber : ""))


        nextColumn()
        text("") // todo decide what to write

        nextColumn()
        text(paymentTypes(ticket))

        nextColumn()
        text("ЯК")

        nextColumn()
        text(TextUtil.join("/", new LinkedHashSet(ticket.flightNumbers)))

        nextColumn()
        text(ticket.departureDate ? sdf.format(ticket.departureDate) : "")

        nextColumn()
        text(ticket.crtRouteLine ? ticket.crtRouteLine : "")

        nextColumn()
        text(ticket.fareBasisLine ? ticket.fareBasisLine : "")

        nextColumn()
        number(ticket.equivalentFare ? ticket.equivalentFare : BigDecimal.ZERO, "center-center-border-number")

        nextColumn()
        number(taxAmount(ticket, "RU"))

        nextColumn()
        number(MiscUtil.sum(taxAmount(ticket, "YQ"), taxAmount(ticket, "YR")))

        nextColumn()
        number(taxAmount(ticket, "ZZ"))

        nextColumn()
        number(null) // todo decide what to write

        nextColumn()
        number(ticket.penalty)

        nextColumn()
        number(getOtherTax(ticket, exclude))

        nextColumn()
        number(ticket.vendorCommissionRate)

        nextColumn()
        number(ticket.vendorCommissionValue)

        nextColumn()
        number(MiscUtil.sub(
                ticket.price,
                ticket.vendorCommissionValue))

        nextColumn()
        text("", "center-center-border")

        nextColumn()
        text("") // todo decide what to write
    }

    nextRow(); nextColumn()

    text("Всего по Переоформление авиаперевозки:", "left-center-bold-border", 9, 1)
    8.times {
        nextColumn(); text("")
    }

    7.times {
        nextColumn()
        if (i > 0) {
            formula("SUM(${cellIndex(-i, 0)}:${cellIndex(-1, 0)})", "center-center-border-number")
        } else {
            number(BigDecimal.ZERO, "center-center-border-number")
        }
    }

    nextColumn(); text("")

    2.times {
        nextColumn()
        if (i > 0) {
            formula("SUM(${cellIndex(-i, 0)}:${cellIndex(-1, 0)})", "center-center-border-number")
        } else {
            number(BigDecimal.ZERO, "center-center-border-number")
        }
    }

    nextColumn(); text("")
    nextColumn(); text("")
}

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

def setAutoWidth() {
    nextRow(); rowHeight(15); columnWidth(5)

    20.times {
        nextColumn()
        columnAutoWidth(true)
    }
}

page{"Реестр обмена"} {
    AirTicketsTemplateReportParameters airTicketParams = parameters.params
    printHead(airTicketParams)
    printHeader()
    printTickets()
    printEnd()
    setAutoWidth()
}