import com.gridnine.xtrip.common.l10n.model.LocaleHelper
import com.gridnine.xtrip.common.model.EntityReference
import com.gridnine.xtrip.common.model.dict.DictionaryCache
import com.gridnine.xtrip.common.model.dict.DictionaryReference
import com.gridnine.xtrip.common.model.dict.GeoLocation
import com.gridnine.xtrip.common.model.dict.LocationType
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.AirTicketsTemplateReportTicket
import com.gridnine.xtrip.common.util.TextUtil

import java.text.DateFormatSymbols
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 printTitle() {
    rowHeight(15)
    nextRow(); nextColumn(); nextColumn()
    text("Реестр оформленных проездных и перевозочных документов по ВПД " +
         parameters['passengerStatus'] +
         " а/к \"Уральские авиалинии\"", "left", 6, 1)

    DateFormatSymbols dfs = new DateFormatSymbols(LocaleHelper.RU_LOCALE)
    String[] months = ["января", "февраля", "марта", "апреля",
                       "мая", "июня", "июля", "августа",
                       "сентября", "октября", "ноября", "декабря"]
    dfs.setMonths(months)
    SimpleDateFormat sdf = new SimpleDateFormat("dd MMMM yyyy г.", dfs);

    nextRow(); nextColumn(); nextColumn()

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

    text("За период с " +
        (periodBeginParameter ? sdf.format(periodBeginParameter) : "") +
        " по " +
        (periodEndParameter ? sdf.format(periodEndParameter) : ""),
        "left", 6, 1)
}

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

    text("№" + "\n" + "п/п", "center-border", 1, 2)
    nextColumn(); text("3-х значный" + "\n" + "цифровой" + "\n" + "код", "center-border", 1, 2)
    nextColumn(); text("№ ВПД", "center-border", 1, 2)
    nextColumn(); text("№ авиабилета", "center-border", 1, 2)
    nextColumn(); text("Пункт оформления" + "\n" + "авиабилета," + "\n" + "контрольный номер", "center-border", 1, 2)
    nextColumn(); text("Вид тарифа", "center-border", 1, 2)
    nextColumn(); text("Маршрут следования", "center-border", 1, 2)
    nextColumn(); text("Дата" + "\n" + "продажи" + "\n" + "авиабилета", "center-border", 1, 2)
    nextColumn(); text("Дата" + "\n" + "вылета", "center-border", 1, 2)
    nextColumn(); text("Номер" + "\n" + "рейса", "center-border", 1, 2)
    nextColumn(); text("Стоимость перевозной платы, руб.", "center-border", 3, 1)
    nextColumn(); nextColumn()
    nextColumn(); text("Сбор за" + "\n" + "оформление" + "\n" + "(руб)", "center-border", 1, 2)
    nextColumn(); text("Итого," + "\n" + "руб", "center-border", 1, 2)

    nextRow(); rowHeight(45)
    9.times {
        nextColumn()
    }
    nextColumn(); text("Тариф", "center-border")
    nextColumn(); text("Тариф" + "\n" + "с учетом" + "\n" + "скидки", "center-border")
    nextColumn(); text("Сборы," + "\n" + "включенные в" + "\n" + "авиабилет", "center-border")

    nextRow(); rowHeight(15)

    int i = 0
    15.times {
        i++
        text(String.valueOf(i), "center-bold-border")
        nextColumn()
    }
}

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

    int mtdCount = 0
    Set<String> mtdNumbers = new HashSet<>()

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

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

        nextColumn()
        text("")

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

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

        nextColumn()
        text(salesPointCity(ticket.salesPoint) + ", " + TextUtil.nonNullStr(ticket.validator))

        nextColumn()
        text(ticket.fareBasisLine != null ? ticket.fareBasisLine : "")

        nextColumn()
        text(route(ticket))

        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()
        number(ticket.equivalentFare ? ticket.equivalentFare : BigDecimal.ZERO, "center-center-border-number")

        nextColumn()
        number(ticket.equivalentFare ? ticket.equivalentFare : BigDecimal.ZERO)

        nextColumn()
        number(ticket.taxesSum ? ticket.taxesSum : BigDecimal.ZERO)

        nextColumn()
        number(ticket.clientFeeValue ? ticket.clientFeeValue : BigDecimal.ZERO)

        nextColumn()
        number(ticket.price ? ticket.price : BigDecimal.ZERO)

        if (TextUtil.isBlank(ticket.militaryClaimNumber) || mtdNumbers.add(ticket.militaryClaimNumber)) {
            mtdCount++
        }
    }

    nextRow()
    2.times {
        text(""); nextColumn()
    }

    text("Итого:", "left-center-bold-border")

    12.times {
        text(""); nextColumn()
    }

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

    nextRow(); nextRow(); nextColumn()

    text("ВПД " + mtdCount + " шт.", "left")
}

def route(AirTicketsTemplateReportTicket ticket) {
    StringBuilder sb = new StringBuilder()

    ticket.segmentTariffs.each {
        it.segments.each {
            String depLocation = locName(it.departureLocation)
            if (sb.toString().endsWith(depLocation)) {
                sb.append("-")
            } else {
                if (sb.length() > 0) {
                    sb.append("-")
                }
                sb.append(depLocation).append("-");
            }
            sb.append(locName(it.arrivalLocation))
        }
    }

    return sb.toString()
}

def locName(DictionaryReference<GeoLocation> reference) {
    if (reference == null) {
        return ""
    }

    GeoLocation location = DictionaryCache.get().resolveReference(reference)
    if (location == null) {
        return reference.toString()
    }

    if (location.type != LocationType.CITY && location.parent != null) {
        return locName(location.parent)
    }

    return location.toString(LocaleHelper.RU_LOCALE)
}

def salesPointCity(EntityReference<SalesPoint> spReference) {
    if (spReference == null) {
        return ""
    }

    SalesPoint salesPoint = EntityStorage.get().resolve(spReference)?.getEntity()
    if (salesPoint == null) {
        return ""
    }

    for (Address address: salesPoint.getAddresses()) {
        DictionaryReference<GeoLocation> cityReference = address.getCity()
        if (cityReference != null) {
            return cityReference.toString(LocaleHelper.RU_LOCALE).toUpperCase()
        }
    }

    return ""
}

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

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

page{"Реестр " + parameters['passengerStatus']} {
    printTitle()
    printHeader()
    printTickets()
    setAutoWidth()
}