import com.gridnine.xtrip.common.l10n.model.LocaleHelper
import com.gridnine.xtrip.common.model.EntityReference
import com.gridnine.xtrip.common.model.booking.ProductStatus
import com.gridnine.xtrip.common.model.dict.ContractType
import com.gridnine.xtrip.common.model.entity.EntityStorage
import com.gridnine.xtrip.common.model.helpers.PersonalLocalizableNameFormatter
import com.gridnine.xtrip.common.model.helpers.ProfileHelper
import com.gridnine.xtrip.common.model.profile.Contract
import com.gridnine.xtrip.common.model.profile.Organization
import com.gridnine.xtrip.common.model.profile.Person
import com.gridnine.xtrip.common.reports.model.AirTicketsTemplateReportTicket

import java.text.SimpleDateFormat

if (parameters['isVatRegistries'] != parameters['vatRegistries']) {
    return
}

// Styles
createStyle(name: 'title', h_alignment: 'CENTER', v_alignment: 'CENTER')
createStyle(name: 'titleH1', fontHeight: 14, parent: 'title')
createStyle(name: 'titleH2', fontHeight: 9, parent: 'title')
createStyle(name: 'titleH3', fontHeight: 9, parent: 'title')
createStyle(name: 'header', h_alignment: 'CENTER', v_alignment: 'CENTER', fontHeight: 9)
createStyle(name: 'columnHeader', parent: 'header', fontBold: true)
createStyle(name: 'rowHeader', parent: 'header')
createStyle(name: 'data', h_alignment: 'CENTER', v_alignment: 'CENTER', fontHeight: 9)
createStyle(name: 'dataText', parent: 'data')
createStyle(name: 'dataText8', parent: 'data', fontHeight: 8)
createStyle(name: 'dataDate', format: 'm/d/yy', parent: 'data')
createStyle(name: 'dataNumber', h_alignment: 'RIGHT', format: '#,##0.00', parent: 'data')
createStyle(name: 'wrap', wrapText: true)
createStyle(name: 'ahl', h_alignment: 'LEFT')
createStyle(name: 'ahc', h_alignment: 'CENTER')
createStyle(name: 'ahr', h_alignment: 'RIGHT')
createStyle(name: 'avt', v_alignment: 'TOP')
createStyle(name: 'avc', v_alignment: 'CENTER')
createStyle(name: 'avb', v_alignment: 'BOTTOM')
createStyle(name: 'aac', h_alignment: 'CENTER', v_alignment: 'CENTER')
createStyle(name: 'bold', fontBold: true)
createStyle(name: 'italic', fontItalic: true)
createStyle(name: 'bt', topBorder: 'THIN')
createStyle(name: 'bl', leftBorder: 'THIN')
createStyle(name: 'bb', bottomBorder: 'THIN')
createStyle(name: 'br', rightBorder: 'THIN')
createStyle(name: 'ba', topBorder: 'THIN', leftBorder: 'THIN', bottomBorder: 'THIN', rightBorder: 'THIN')
createStyle(name: 'green', foreground: 'LIGHT_GREEN')
createStyle(name: 'yellow', foreground: 'YELLOW')
createStyle(name: 'purple', foreground: 'CORAL')
createStyle(name: 'locked', locked: true)

// Properties
Date periodBeginParameter = parameters['key-report-params']?.periodBegin
Date periodEndParameter = parameters['key-report-params']?.periodEnd
EntityReference<Organization> supplierParameter = parameters['key-report-params']?.supplier
EntityReference<Organization> agencyParameter = parameters['key-report-params']?.agency

//Closures
def cellFill(Object value, String style, int x, int y) {
    if (value != null) {
        if (value instanceof Number) {
            number(value, style, x, y)
        } else if (value instanceof Date) {
            date(value, style, x, y)
        } else if (value instanceof Formula){
            formula(value.formula, style, x, y)
        } else {
            text(value, style, x, y)
        }
    } else {
        text('', style, x, y)
    }
}

def cellFill(Object value, String style) {
    if (value != null) {
        if (value instanceof Number) {
            number(value, style)
        } else if (value instanceof Date) {
            date(value, style)
        } else if (value instanceof Formula){
            formula(value.formula, style)
        } else {
            text(value, style)
        }
    } else {
        text('', style)
    }
}

def period = {
    def format = new SimpleDateFormat('dd.MM.yyyy')
    return String.format('%s - %s', periodBeginParameter != null ? format.format(periodBeginParameter) : '?', periodEndParameter != null ? format.format(periodEndParameter) : '?')
}

def agencyName = {
    Organization organization = EntityStorage.get().resolve(agencyParameter)?.entity
    return organization ? ProfileHelper.getFullName(organization, LocaleHelper.getLocale('ru', 'RU'), false) : 'Не указано'
}

def contractDate = {
    List<EntityReference<Contract>> contracts = ProfileHelper.getContracts(supplierParameter, supplierParameter, agencyParameter, ContractType.VENDOR, periodBeginParameter, periodEndParameter)
    def contractCustomerInfo = contracts.size() > 0 ? ProfileHelper.getContractCustomerInfo(contracts.get(0), agencyParameter) : null
    def format = new SimpleDateFormat('dd.MM.yyyy')
    return contractCustomerInfo != null && contractCustomerInfo.issueDate != null ? format.format(contractCustomerInfo.issueDate) : '?'
}

def contractNumber = {
    List<EntityReference<Contract>> contracts = ProfileHelper.getContracts(supplierParameter, supplierParameter, agencyParameter, ContractType.VENDOR, periodBeginParameter, periodEndParameter)
    def contractCustomerInfo = contracts.size() > 0 ? ProfileHelper.getContractCustomerInfo(contracts.get(0), agencyParameter) : null
    return contractCustomerInfo ? contractCustomerInfo.number : '?'
}

def ignoreZeroNumber = { BigDecimal number1 ->
    return number1 == BigDecimal.ZERO || number1 == null || number1 == 0 ? '' : number1
}

def directorName = {
    Person person = EntityStorage.get().resolve(requestedParameter('director'))?.entity
    PersonalLocalizableNameFormatter format = new PersonalLocalizableNameFormatter(PersonalLocalizableNameFormatter.SIMPLE)
    return person ? format.format(person, LocaleHelper.getLocale('ru', 'RU'), false) : '?'
}

def responsibleName = {
    Person person = EntityStorage.get().resolve(requestedParameter('responsible'))?.entity
    PersonalLocalizableNameFormatter format = new PersonalLocalizableNameFormatter(PersonalLocalizableNameFormatter.SIMPLE)
    return person ? format.format(person, LocaleHelper.getLocale('ru', 'RU'), false) : '?'
}

page{parameters['name']} {
    // Set fix width for amount of sheets
    fitWidth(1)

    // Set portrait mode
    landscape(false)

    // Set narrow margins
    margin(0.25, 0.25, 0.25, 0.25)

    // Set scale
    scale(70)

    // Set preserve mode
    preserve(false)

// Report header
    nextColumn();cellFill('АГЕНТ: ' + agencyName(), 'titleH1|italic|ahl|bold', 8, 1)
    nextRow()
    nextColumn();cellFill('ДОГОВОР №' + contractNumber() + ' от ' + contractDate() , 'titleH1|italic|ahl|bold', 8, 1)
    nextRow()
    nextColumn();cellFill('РЕЕСТР ' + parameters['name'], 'titleH1|italic|ahl|bold', 8, 1)
    nextRow()
    columnWidth(5); nextColumn(); columnWidth(15); nextColumn(); columnWidth(10); nextColumn(); columnWidth(15); nextColumn()
    columnWidth(12); nextColumn(); columnWidth(12); nextColumn(); columnWidth(13); nextColumn(); columnWidth(13); nextColumn()
    columnWidth(13)

    nextRow()
    nextColumn();cellFill('СВЕРХНОРМАТИВНЫЙ БАГАЖ, ПРИНЯТЫЙ К ПЕРЕВОЗКЕ за ' + period(), 'titleH1|italic|ahl|bold', 8, 1)
    2.times { nextRow() }

// Table header
    cellFill('№ п/п', 'columnHeader|wrap|ba', 1, 3);nextColumn()
    cellFill('Серийный номер багажной квитанции', 'columnHeader|wrap|ba', 1, 3);nextColumn()
    cellFill('Дата', 'columnHeader|wrap|ba', 1, 3);nextColumn()
    cellFill('Рейс', 'columnHeader|wrap|ba', 1, 3);nextColumn()
    cellFill('Участок перевозки', 'columnHeader|wrap|ba', 1, 3);nextColumn()
    cellFill('Вес', 'columnHeader|wrap|ba', 1, 3);nextColumn()
    cellFill('Тариф за кг', 'columnHeader|wrap|ba', 1, 3);nextColumn()
    cellFill('Сумма к оплате', 'columnHeader|wrap|ba', 1, 3);nextColumn()
    cellFill('Комиссия', 'columnHeader|wrap|ba', 1, 3);nextColumn()
    3.times { nextRow() }

// Table
    int rowCounter = 0
    allTickets.each { AirTicketsTemplateReportTicket ticket ->
        ++rowCounter
        cellFill(rowCounter, 'data|ahr|ba'); nextColumn()
        cellFill(ticket.ticketNumber, 'dataText|ahl|ba');nextColumn()
        if (ProductStatus.VOID != ticket.status) {
            cellFill(ticket.issueDate, 'dataDate|ahl|ba');nextColumn()
            cellFill(ticket.tariffCodes, 'dataText|ahl|ba');nextColumn()
            cellFill(ticket.routeLine, 'dataText|ahl|ba');nextColumn()
            cellFill(ticket.luggageWeight, 'data|ahr|ba'); nextColumn()
            cellFill(((ticket.luggageWeight?:0 > 0) && (ticket.equivalentFare != null)) ?
                       ticket.equivalentFare.toDouble() / ticket.luggageWeight :
                       null, 'data|ahr|ba'); nextColumn()
            cellFill(ignoreZeroNumber(ticket.equivalentFare), 'dataNumber|ahr|ba'); nextColumn()
            if (ticket.vendorCommissionRate != null && ticket.vendorCommissionValue != null) {
                cellFill(ignoreZeroNumber(ticket.vendorCommissionValue), 'dataNumber|ahl|ba');nextColumn()
            }
        } else {
            7.times { cellFill(null, 'ba'); nextColumn() }
        }
        nextRow()
    }
// Total
    cellFill('Итого', 'dataText|ahl|ba|bold', 2, 1);nextColumn()
    6.times { cellFill(null, 'ba');nextColumn() }
    if (rowCounter != 0) {
        2.times {cellFill(new Formula("SUM(${cellIndex(-rowCounter, 0)}:${cellIndex(-1, 0)})"), 'dataNumber|bold|ahr|ba');nextColumn() }
    } else {
        2.times { cellFill(null, 'ba');nextColumn() }
    }
    2.times { nextRow() }


// Footer
    cellFill('Руководитель:', 'dataText|ahl', 2, 1)
    2.times { nextColumn() }
    cellFill(directorName(), 'dataText|ahl')
    2.times { nextRow() }
    cellFill('Гл. бухгалтер:', 'dataText|ahl',2 ,1)
    2.times { nextColumn() }
    cellFill(responsibleName(), 'dataText|ahl')
    2.times { nextRow() }
    cellFill('Печать:', 'dataText|ahl', 2, 1)
}

class Formula {
    String formula
    Formula(){}
    Formula(String formula) {
        this.formula = formula
    }

    static Formula getSumFormulaByRow (String start, String 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 + ')')
    }
}