import com.gridnine.xtrip.common.l10n.model.LocaleHelper
import com.gridnine.xtrip.common.l10n.model.PersonalLocalizableNameUtil
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.Person
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: "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() {
    rowHeight(15)
    text("Реестр продажи авиаперевозок " + parameters['AGENCY_NAME'], "center-bold", 12, 1)

    SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy")
    def periodBeginParameter = parameters['key-report-params']?.periodBegin
    def periodEndParameter = parameters['key-report-params']?.periodEnd

    nextRow()
    text("за период с " +
            (periodBeginParameter ? sdf.format(periodBeginParameter) : "") +
            " по " +
            (periodEndParameter ? sdf.format(periodEndParameter) : ""),
            "center", 12, 1)

    nextRow()
    text("авиакомпания \"У6\"", "center", 12, 1)

    nextRow()
    text("КР МВД[ВН]", "center", 12, 1)

    nextRow()
    text(parameters['title'], "center", 12, 1)
}

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

    text("№" + "\n" + "п/п", "center-center-border")
    nextColumn();text("№ авиабилета", "center-center-border")
    nextColumn();text("Дата продажи", "center-center-border")
    nextColumn();text("Маршрут", "center-center-border")
    nextColumn();text("Вид" + "\n" + "тарифа", "center-center-border")
    nextColumn();text("Тариф", "center-center-border")
    nextColumn();text("Такса", "center-center-border")
    nextColumn();text("Такса", "center-center-border")
    nextColumn();text("Итого" + "\n" + "получено", "center-center-border")
    nextColumn();text("%" + "\n" + "ком", "center-center-border")
    nextColumn();text("Комиссия" + "\n" + "агента", "center-center-border")
    nextColumn();text("Причитается" + "\n" + "перевозчику", "center-center-border")
}

def printTickets() {
    Map<BigDecimal, List<AirTicketsTemplateReportTicket>> ticketsByCommissionRate = collectTicketsByCommission()

    List<Integer> sumsRowIndexes = new ArrayList<>()

    ticketsByCommissionRate.each {
        printBatch(it.value, it.key, sumsRowIndexes)
    }

    printTotal(sumsRowIndexes)
}

def collectTicketsByCommission() {
    Map<BigDecimal, List<AirTicketsTemplateReportTicket>> result = new TreeMap<>()

    tickets { AirTicketsTemplateReportTicket ticket ->
        BigDecimal commissionRate = MiscUtil.nonNull(ticket.vendorCommissionRate)

        List<AirTicketsTemplateReportTicket> ticketList = null
        result.each {
            if (MiscUtil.equals(it.key, commissionRate)) {
                ticketList = it.value
            }
        }
        if (!ticketList) {
            ticketList = new ArrayList<>()
            result.put(commissionRate, ticketList)
        }

        ticketList.add(ticket)
    }

    return result
}

def printBatch(List<AirTicketsTemplateReportTicket> ticketList,
               BigDecimal commissionRate, Collection<Integer> sumsRowIndexes) {
    nextRow(); rowHeight(15)
    text("Размер вознаграждения Агента "  + commissionRate.stripTrailingZeros() + " %", "left-bold-border", 12, 1)

    SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy")

    ticketList.eachWithIndex { AirTicketsTemplateReportTicket ticket, int i ->
        nextRow()

        number(i + 1, "center-border")

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

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

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

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

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

        nextColumn()
        number(taxes(ticket, true))

        nextColumn()
        number(taxes(ticket, false))

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

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

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

        nextColumn()
        formula("${cellIndex(0, -3)}-${cellIndex(0, -1)}")
    }

    nextRow()
    text("Итог по вознаграждению Агента "  + commissionRate.stripTrailingZeros() + " % :", "left-bold-border", 5, 1)

    5.times {
        nextColumn()
    }

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

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

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

    sumsRowIndexes.add(getRowIndex() + 1)
}

def printTotal(Collection<Integer> sumsRowIndexes) {
    nextRow(); rowHeight(30)
    text("Общий итог:", "left-bold-border", 5, 1)

    5.times {
        nextColumn()
    }

    4.times {
        printColumnTotal(sumsRowIndexes)
    }

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

    2.times {
        printColumnTotal(sumsRowIndexes)
    }
}

def printColumnTotal(Collection<Integer> sumsRowIndexes) {
    if (sumsRowIndexes.empty) {
        number(BigDecimal.ZERO, "center-border-number")
    } else {
        String columnName = getColumnName()
        StringBuilder sumFormula = new StringBuilder()

        sumsRowIndexes.each {
            if (sumFormula.length() > 0) {
                sumFormula.append("+")
            }
            sumFormula.append(columnName).append(it)
        }
        formula(sumFormula.toString(), "center-border-number")
    }

    nextColumn()
}

def taxes(AirTicketsTemplateReportTicket ticket, boolean onlyYqTax) {
    BigDecimal result = BigDecimal.ZERO

    ticket.taxes.each {
        if (onlyYqTax == "YQ".equalsIgnoreCase(it.code)) {
            result = MiscUtil.sum(result, it.equivalentAmount)
        }
    }

    return result
}

def printAuthor() {
    EntityReference<Person> authorRef = (EntityReference<Person>) parameters['report_author']
    EntityContainer<Person> authorCont = EntityStorage.get().resolve(authorRef)

    String authorName =
            authorCont ? PersonalLocalizableNameUtil.buildFullName(
                    authorCont.entity, true, LocaleHelper.RU_LOCALE, false) : "___________"

    nextRow(); rowHeight(60)
    text("М.П." + "\n" + "\n" +
            "Отчет составил:  ____________________ (" + authorName + ")", "left", 7, 1)

}

def setAutoWidth() {
    nextRow()
    rowHeight(15)

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

page{parameters['title']} {
    printHead()
    printHeader()
    printTickets()
    printAuthor()
    setAutoWidth()
}