import com.gridnine.xtrip.common.l10n.model.LocaleHelper
import com.gridnine.xtrip.common.model.EntityReference
import com.gridnine.xtrip.common.model.booking.TransportationType
import com.gridnine.xtrip.common.model.dict.AddressType
import com.gridnine.xtrip.common.model.dict.CodeSystem
import com.gridnine.xtrip.common.model.entity.EntityStorage
import com.gridnine.xtrip.common.model.helpers.DictHelper
import com.gridnine.xtrip.common.model.helpers.ProfileHelper
import com.gridnine.xtrip.common.model.profile.Address
import com.gridnine.xtrip.common.model.profile.Organization
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: "center-center", h_alignment: "CENTER", v_alignment: "CENTER")
createStyle(name: "center-center-bold", h_alignment: "CENTER", v_alignment: "CENTER", fontBold : true)
createStyle(name: "center-center-bold-italic", h_alignment: "CENTER", v_alignment: "CENTER", fontBold : true, fontItalic : 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: "center-center-bold-border", h_alignment: "CENTER", v_alignment: "CENTER", fontBold : true, leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', foreground : "GREY_40_PERCENT", 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: "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: "center-center-border-number", format: '0.00', h_alignment: "CENTER", v_alignment: "CENTER", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "center-center-border-number0", format: '0.0', h_alignment: "CENTER", v_alignment: "CENTER", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "center-center-bold-border-number", format: '0.00', h_alignment: "CENTER", v_alignment: "CENTER", fontBold : true, leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)

def getPeriod() {
    StringBuilder stringBuilder = new StringBuilder();
    Calendar calendar = Calendar.getInstance();
    SimpleDateFormat sdfBegin = new SimpleDateFormat("dd.MM.yyyy")
    SimpleDateFormat sdfEnd = new SimpleDateFormat("dd.MM.yyyy")

    Date periodBeginParameter = parameters['key-report-params']?.periodBegin
    Date periodEndParameter = parameters['key-report-params']?.periodEnd

    Integer yearBegin = MiscUtil.getYear(periodBeginParameter)
    Integer yearEnd = MiscUtil.getYear(periodEndParameter)

    Integer monthBegin = null
    if (periodBeginParameter) {
        calendar.setTime(periodBeginParameter)
        monthBegin = calendar.get(Calendar.MONTH)
    }
    Integer monthEnd = null
    if (periodEndParameter) {
        calendar.setTime(periodEndParameter)
        monthEnd = calendar.get(Calendar.MONTH)
    }

    if (yearBegin == yearEnd) {
        sdfBegin = new SimpleDateFormat("dd.MM")
        if (monthBegin == monthEnd) {
            sdfBegin = new SimpleDateFormat("dd")
        }
    }
    stringBuilder.append(periodBeginParameter ? sdfBegin.format(periodBeginParameter) + " - " : "")
    stringBuilder.append(periodEndParameter ? sdfEnd.format(periodEndParameter) : "")
    return stringBuilder.toString()
}

def printTitle() {
    EntityReference<Organization> agencyParameter = parameters['key-report-params']?.agency
    Organization organization = EntityStorage.get().resolve(agencyParameter)?.entity
    Address address = ProfileHelper.filterAddresses(organization?.getAddresses(), AddressType.LEGAL);

    rowHeight(15)
    nextColumn()

    text("Реестр продажи авиабилетов АО «Авиакомпания SCAT»", "left-bold", 4, 1)

    nextRow(); nextRow();
    nextColumn(); nextColumn()

    text("АО «Авиакомпания SCAT»", "center-center-bold", 2, 1)

    nextRow(); nextColumn();
    text("Агент:", "center-center-bold")

    nextColumn()
    text(parameters['AGENCY_NAME'], "center-center-bold", 2, 1)

    nextRow(); nextColumn();
    text("На дату:", "center-center-bold")

    nextColumn();
    text(getPeriod(), "center-center-bold", 2, 1)

    nextRow(); nextColumn();
    text("Страна", "center-center-bold")

    nextColumn();
    text(address?.getCountry() ? address.getCountry().toString(LocaleHelper.RU_LOCALE) : "", "center-center-bold-italic", 2, 1)

    nextRow(); nextColumn();
    text("Город", "center-center-bold")

    nextColumn();
    text(address?.getCity() ? address.getCity().toString(LocaleHelper.RU_LOCALE) : "", "center-center-bold-italic", 2, 1)
}

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

    text("№", "center-center-bold-border")
    nextColumn();text("Билет")
    nextColumn();text("ФИО пассажира")
    nextColumn();text("Дата\nпродажи")
    nextColumn();text("Дата\nвылета")
    nextColumn();text("Номер\nрейса")
    nextColumn();text("Маршрут")
    nextColumn();text("Внешние\nили внутренние\nвоздушные линии")
    nextColumn();text("Вид скидок")
    nextColumn();text("Вид тарифа")
    nextColumn();text("Тариф")
    nextColumn();text("Сумма сборов")
    nextColumn();text("Штраф")
    nextColumn();text("Итого\nпо перевозным\nдокументам")
    nextColumn();text("% комиссии")
    nextColumn();text("Сумма\nкомиссии")
    nextColumn();text("Выручка\nПеревозчика\nза минусом\nкомиссионных")
    nextColumn();text("Примечание")
}

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

    tickets { AirTicketsTemplateReportTicket ticket ->
        i++

        nextRow(); rowHeight(15)

        //"№"
        number(i, "center-center-border")

        //Билет
        nextColumn()
        text((ticket.validatingCarrierNumber ? ticket.validatingCarrierNumber + " " : "") +
                (ticket.ticketNumber ? ticket.ticketNumber : ""))

        //ФИО пассажира
        nextColumn()
        text(ticket.travellerName ? ticket.travellerName : "")

        //Дата продажи
        nextColumn()
        text(ticket.issueDate ? sdf.format(ticket.issueDate) : "")

        //Дата вылета
        nextColumn()
        text(ticket.departureDate ? sdf.format(ticket.departureDate) : "")

        //Номер рейса
        nextColumn()
        text(TextUtil.join(", ", new LinkedHashSet(ticket.flightNumbers)))

        //Маршрут
        nextColumn()
        text(ticket.routeLine)

        //Внешние или внутренние воздушные линии
        nextColumn()
        text(ticket.transportationType == TransportationType.INTERNATIONAL ? "Внешние" : "Внутренние")

        //Вид скидок
        nextColumn()
        text(ticket.travellerType ?
                DictHelper.getCodeVariant((ticket.travellerType), CodeSystem.IATA, CodeSystem.CRT) : "")

        //Вид тарифа
        nextColumn()
        text(ticket.tariffCodes)
        //text(ticket.tariffType.toString(LocaleHelper.RU_LOCALE))

        //Тариф
        nextColumn()
        number(ticket.equivalentFare ? ticket.equivalentFare : BigDecimal.ZERO, "center-center-border-number")

        //Сумма сборов
        nextColumn()
        number(ticket.taxesSum ? ticket.taxesSum : BigDecimal.ZERO, "center-center-border-number")

        //Штраф
        nextColumn()
        number(ticket.penalty ? ticket.penalty : BigDecimal.ZERO, "center-center-border-number")

        //Итого по перевозным документам
        nextColumn()
        formula("SUM(${cellIndex(0, -1)}:${cellIndex(0, -3)})", "center-center-border-number")

        //% комиссии
        nextColumn()
        number(ticket.vendorCommissionRate ? ticket.vendorCommissionRate : BigDecimal.ZERO,
                "center-center-border-number0")

        //Сумма комиссии
        nextColumn()
        number(ticket.vendorCommissionValue ? ticket.vendorCommissionValue : BigDecimal.ZERO,
                "center-center-border-number")

        //Выручка Перевозчика за минусом комиссионных
        nextColumn()
        formula("${cellIndex(0, -3)}-${cellIndex(0, -1)}", "center-center-border-number")

        //Примечание
        nextColumn()
        text("")
    }

    nextRow()
    text("Итого по реестру:", "left-center-bold-border", 10, 1)

    10.times {
        nextColumn()
        text("", "left-center-bold-border")
    }
    //Итого - тариф
    if (count() > 0) {
        formula("SUM(${cellIndex(-count(), 0)}:${cellIndex(-1, 0)})", "center-center-bold-border-number")
    } else {
        number(BigDecimal.ZERO, "center-center-bold-border-number")
    }

    //Итого - Сумма сборов
    nextColumn()
    if (count() > 0) {
        formula("SUM(${cellIndex(-count(), 0)}:${cellIndex(-1, 0)})", "center-center-bold-border-number")
    } else {
        number(BigDecimal.ZERO, "center-center-bold-border-number")
    }

    //Итого - Штраф
    nextColumn()
    if (count() > 0) {
        formula("SUM(${cellIndex(-count(), 0)}:${cellIndex(-1, 0)})", "center-center-bold-border-number")
    } else {
        number(BigDecimal.ZERO, "center-center-bold-border-number")
    }

    //Итого - Итого по перевозным документам
    nextColumn()
    if (count() > 0) {
        formula("SUM(${cellIndex(-count(), 0)}:${cellIndex(-1, 0)})", "center-center-bold-border-number")
    } else {
        number(BigDecimal.ZERO, "center-center-bold-border-number")
    }

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

    //Итого - Сумма комиссии
    nextColumn()
    if (count() > 0) {
        formula("SUM(${cellIndex(-count(), 0)}:${cellIndex(-1, 0)})", "center-center-bold-border-number")
    } else {
        number(BigDecimal.ZERO, "center-center-bold-border-number")
    }

    //Итого - Выручка Перевозчика за минусом комиссионных
    nextColumn()
    if (count() > 0) {
        formula("SUM(${cellIndex(-count(), 0)}:${cellIndex(-1, 0)})", "center-center-bold-border-number")
    } else {
        number(BigDecimal.ZERO, "center-center-bold-border-number")
    }

    nextColumn()
    text("", "left-center-bold-border")
}

def setAutoWidth() {
    nextRow()
    rowAutoHeight()

    columnAutoWidth()
    18.times {
        nextColumn()
        columnAutoWidth()
    }
}

page{"ПРОДАЖА " + getPeriod()} {
    printTitle()
    printHeader()
    printTickets()
    setAutoWidth()
}
