import com.gridnine.xtrip.common.model.profile.PersonIndex
import com.gridnine.xtrip.common.model.profile.Person
import com.gridnine.xtrip.common.model.entity.EntityStorage
import com.gridnine.xtrip.common.l10n.model.L10nStringHelper
import com.gridnine.xtrip.common.util.LocaleUtil
import com.gridnine.xtrip.common.l10n.model.L10nString
import com.google.common.base.Joiner
import com.gridnine.xtrip.common.model.profile.Communication
import java.util.Collection
import com.gridnine.xtrip.common.model.dict.CommunicationType
import com.gridnine.xtrip.common.model.profile.Passport
import com.gridnine.xtrip.common.model.dict.PassportType
import com.gridnine.xtrip.common.util.TextUtil
import com.gridnine.xtrip.common.model.profile.PersonCostCode
import java.util.List

import java.util.Date

import com.gridnine.xtrip.common.model.helpers.ProfileHelper
import groovy.transform.Field
import java.text.SimpleDateFormat
import com.gridnine.xtrip.common.model.profile.CostCodeType

@Field SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy")
@Field Joiner commaJoiner = Joiner.on(", ")

createStyle(name: 'header', wrapText: true, fontBold: true,  h_alignment: 'CENTER', v_alignment: 'CENTER', leftBorder:'MEDIUM', rightBorder:'MEDIUM', topBorder:'MEDIUM', bottomBorder:'MEDIUM', foreground: 'GREY_25_PERCENT')
createStyle(name: 'data',fontBold: false,  h_alignment: 'LEFT', v_alignment: 'CENTER', leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN')
createStyle(name: 'textData', parent: 'data')
createStyle(name: 'numberData', parent: 'data')

class Item {
    PersonIndex index
    Person person
    Passport internalPassport, foreignPassport, anyPassport
}

def printHeader() {    
    int coef = 1

    nextRow()
    rowHeight(30, false)
    text("Фамилия", "header")
    columnWidth(20 * coef)
    
    nextColumn()
    text("Имя", "header")
    columnWidth(15 * coef)
    
    nextColumn()
    text("Отчество", "header")
    columnWidth(20 * coef)
    
    nextColumn()
    text("Табельный номер", "header")
    columnWidth(11 * coef)
    
    nextColumn()
    text("Дата рождения", "header")
    columnWidth(13 * coef)
    
    nextColumn()
    text("Код организационной единицы", "header")
    columnWidth(10 * coef)

    nextColumn()
    text("Адрес эл. почты", "header")
    columnWidth(33 * coef)
    
    nextColumn()
    text("Active", "header")
    columnWidth(6 * coef)
    
    nextColumn()
    text("Телефон мобильный", "header")
    columnWidth(20 * coef)

    nextColumn()
    text("Документ, удостоверяющий личность (ДОК)", "header")
    columnWidth(20 * coef)
    
    nextColumn()
    text("ДОК Серия", "header")
    columnWidth(6 * coef)
    
    nextColumn()
    text("ДОК Номер", "header")
    columnWidth(12 * coef)
    
    nextColumn()
    text("ДОК Выдан", "header")
    columnWidth(13 * coef)

    nextColumn()
    text("ДОК Дата Выдачи", "header")
    columnWidth(13 * coef)
    
    nextColumn()
    text("Загранпаспорт (ЗП) серия", "header")
    columnWidth(9 * coef)
    
    nextColumn()
    text("ЗП Номер", "header")
    columnWidth(15 * coef)
    
    nextColumn()
    text("ЗП Выдан", "header")
    columnWidth(20 * coef)
    
    nextColumn()
    text("ЗП Дата Выдачи", "header")
    columnWidth(13 * coef)
    
    nextColumn()
    text("ЗП Срок", "header")
    columnWidth(13 * coef)

    nextColumn()
    text("Англ Фамилия", "header")
    columnWidth(20 * coef)
    
    nextColumn()
    text("Англ Имя", "header")
    columnWidth(15 * coef)
    
    nextColumn()
    text("Место рождения", "header")
    columnWidth(20 * coef)
}

String getRuString(L10nString l10nString) {
    if (l10nString == null) {
        return null
    }
    return L10nStringHelper.getValue(l10nString, LocaleUtil.LOCALE_RU, false)
}

String getDate(Date date) {
    if (date == null) {
        return null
    }
    return dateFormat.format(date)
}

String getEmail(Item item) {
    if (item.index.emails == null || item.index.emails.empty) {
        return null
    }
    return item.index.emails.iterator().next()
}

String getPhone(Item item) {
    Collection<Communication> phoneComminications = ProfileHelper.getPhoneCommunications(item.person.communications)
    if (phoneComminications == null || phoneComminications.empty) {
        return null
    }
    Communication resultCommunication = null
    for (Communication communication : phoneComminications) {
        if (communication.type == CommunicationType.MOBILE) {
            resultCommunication = communication
            break
        }
    }
    if (resultCommunication == null) {
        return null
    }
    return ProfileHelper.buildFullPhoneNumber(resultCommunication)
}

String getPassportType(Passport passport) {
    if (passport == null) {
        return null
    }
    if (passport.type == PassportType.INTERNAL) {
        return "Внутренний паспорт"
    }
    if (passport.type == PassportType.PASSPORT) {
        return "Национальный паспорт"
    }
}

String getPassportNumber(Passport passport) {
    if (passport == null) {
        return null
    }
    return passport.number
}

String getPassportIssueOrganization(Passport passport) {
    if (passport == null) {
        return null
    }
    return passport.issueOrganization
}

String getPassportIssueDate(Passport passport) {
    if (passport == null) {
        return null
    }
    return getDate(passport.issued)
}

String getPassportExpiredDate(Passport passport) {
    if (passport == null) {
        return null
    }
    return getDate(passport.expired)
}

String getPlaceOfBirth(Item item) {
    if (item.internalPassport != null && TextUtil.isBlank(item.internalPassport.birthPlace)) {
        return item.internalPassport.birthPlace
    }
    if (item.foreignPassport != null && TextUtil.isBlank(item.foreignPassport.birthPlace)) {
        return item.foreignPassport.birthPlace
    }
    for (Passport passport : item.person.passports) {
        if (!TextUtil.isBlank(passport.birthPlace)) {
            return passport.birthPlace
        }
    }
    return null
}

String getOrganizationUnitCode(Item item) {
    List<PersonCostCode> costCodes = item.person.costCodes
    for (PersonCostCode personCostCode : costCodes) {
        if (personCostCode?.costCodeProperties?.type == CostCodeType.COST_CODE_4) {
            return personCostCode.value
        }
    }
}

String getBirthday(Item item) {
    Date birthday = null
    if (item.internalPassport != null && item.internalPassport.birthday != null) {
        birthday = item.internalPassport.birthday
    } else if (item.foreignPassport != null && item.foreignPassport.birthday != null) {
        birthday = item.foreignPassport.birthday
    } else {
        for (Passport passport : item.person.passports) {
            if (passport.birthday != null) {
                birthday = passport.birthday
            }
        }
    }
    return getDate(birthday)
}

def printItem(Item item) {
    nextRow()
    text(getRuString(item.person.lastName), "textData")
    
    nextColumn()
    text(getRuString(item.person.firstName), "textData")
    
    nextColumn()
    text(getRuString(item.person.middleName), "textData")
    
    nextColumn()
    text("", "textData")
    
    nextColumn()
    text(getBirthday(item), "textData")
    
    
    nextColumn()
    text(getOrganizationUnitCode(item), "textData")
    
    nextColumn()
    text(getEmail(item), "textData")
    
    nextColumn()
    text("", "textData")
    
    
    nextColumn()
    text(getPhone(item), "textData")
    
    nextColumn()
    text(getPassportType(item.internalPassport), "textData")
    
    nextColumn()
    text("", "textData")
    
    nextColumn()
    text(getPassportNumber(item.internalPassport), "textData")
    
    nextColumn()
    text(getPassportIssueOrganization(item.internalPassport), "textData")
    
    nextColumn()
    text(getPassportIssueDate(item.internalPassport), "textData")
    
    nextColumn()
    text("", "textData")

    nextColumn()
    text(getPassportNumber(item.foreignPassport), "textData")
    
    nextColumn()
    text(getPassportIssueOrganization(item.foreignPassport), "textData")
    
    nextColumn()
    text(getPassportIssueDate(item.foreignPassport), "textData")
    
    nextColumn()
    text(getPassportExpiredDate(item.foreignPassport), "textData")
    
    nextColumn()
    text(item.index.englishLastName, "textData")
    
    nextColumn()
    text(item.index.englishFirstName, "textData")
    
    nextColumn()
    text(getPlaceOfBirth(item), "textData")
}

Item getItem(PersonIndex index) {
    Item result = new Item()
    result.index = index
    result.person = EntityStorage.get().resolve(index.source)?.entity
    if (result.person == null) {
        return null
    }
    boolean hasInternalPassport = false
    for (Passport passport : result.person.passports) {
        if (passport.type == PassportType.PASSPORT) {
            if (result.internalPassport == null) {
                result.internalPassport = passport
            }
        } else if (passport.type == PassportType.INTERNAL) {
            if (!hasInternalPassport) {
                hasInternalPassport = true
                result.internalPassport = passport
            }
        } else if (passport.type == PassportType.FOREIGN) {
            if (result.foreignPassport == null) {
                result.foreignPassport = passport
            }
        }
    }
    return result
}

////////////////////////////////////////

printHeader()

tickets { PersonIndex index ->
    Item item = getItem(index)
    if (item == null) {
        return
    }
    printItem(item)
}