package com.banesco.module.payment_instruction_request.domain.model;

import com.banesco.module.arrangement.domain.model.Arrangement;
import com.banesco.module.arrangement.domain.model.ArrangementInvolvement;
import com.banesco.module.arrangement.domain.model.ArrangementInvolvementType;
import com.banesco.module.banking_product.domain.model.BankingProduct;
import com.banesco.module.party.domain.model.PartyIdentificationType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Getter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
@RegisterForReflection
public class PaymentArrangement {
    private List<Arrangement> arrangement; // telefonoOrigen, identificacionOrigen, telefonoDestino, identificacionDestino
    private BankingProduct bankingProduct; // codigoBancoDestino
    private BigDecimal paymentAmount; // montoTransaccion
    private String paymentPurpose; // concept
    private List<PaymentDateTime> paymentDate; // fechaHoraEfectiva

    @JsonIgnore
    public String getRecipientId() {
        Optional<ArrangementInvolvement> arrangementInvolvement = arrangement
            .get(0)
            .getArrangementInvolvement()
            .stream().filter(item ->
                item.getArrangementInvolvementType() == ArrangementInvolvementType.PARTY_IS_OBLIGEE_IN_ARRANGEMENT
            )
            .findFirst();

        return arrangementInvolvement
            .flatMap(involvement ->
                involvement
                    .getPartyReference()
                    .getPartyIdentification()
                    .stream()
                    .filter(item ->
                        item.getPartyIdentificationType() == PartyIdentificationType.IDENTITY_CARD_NUMBER
                    )
                    .findFirst()
                    .map(identification ->
                        identification
                            .getPartyIdentification()
                            .getIdentifierValue()
                    )
            ).orElse(null);
    }

    @JsonIgnore
    public String getRecipientPhone() {
        Optional<ArrangementInvolvement> arrangementInvolvement = arrangement
            .get(0)
            .getArrangementInvolvement()
            .stream().filter(item ->
                item.getArrangementInvolvementType() == ArrangementInvolvementType.PARTY_IS_OBLIGEE_IN_ARRANGEMENT
            )
            .findFirst();

        return arrangementInvolvement
            .flatMap(involvement ->
                involvement
                    .getPartyReference()
                    .getPartyIdentification()
                    .stream()
                    .filter(item ->
                        item.getPartyIdentificationType() == PartyIdentificationType.TELEPHONE_NUMBER
                    )
                    .findFirst()
                    .map(identification ->
                        identification
                            .getPartyIdentification()
                            .getIdentifierValue()
                    )
            ).orElse(null);
    }

    @JsonIgnore
    public String getApplicantId() {
        Optional<ArrangementInvolvement> arrangementInvolvement = arrangement
            .get(0)
            .getArrangementInvolvement()
            .stream().filter(item ->
                item.getArrangementInvolvementType() == ArrangementInvolvementType.PARTY_IS_OBLIGOR_IN_ARRANGEMENT
            )
            .findFirst();

        return arrangementInvolvement
            .flatMap(involvement ->
                involvement
                    .getPartyReference()
                    .getPartyIdentification()
                    .stream()
                    .filter(item ->
                        item.getPartyIdentificationType() == PartyIdentificationType.IDENTITY_CARD_NUMBER
                    )
                    .findFirst()
                    .map(identification ->
                        identification
                            .getPartyIdentification()
                            .getIdentifierValue()
                    )
            ).orElse(null);
    }

    @JsonIgnore
    public String getApplicantPhone() {
        Optional<ArrangementInvolvement> arrangementInvolvement = arrangement
            .get(0)
            .getArrangementInvolvement()
            .stream().filter(item ->
                item.getArrangementInvolvementType() == ArrangementInvolvementType.PARTY_IS_OBLIGOR_IN_ARRANGEMENT
            )
            .findFirst();

        return arrangementInvolvement
            .flatMap(involvement ->
                involvement
                    .getPartyReference()
                    .getPartyIdentification()
                    .stream()
                    .filter(item ->
                        item.getPartyIdentificationType() == PartyIdentificationType.TELEPHONE_NUMBER
                    )
                    .findFirst()
                    .map(identification ->
                        identification
                            .getPartyIdentification()
                            .getIdentifierValue()
                    )
            ).orElse(null);
    }

    @JsonIgnore
    public String getBankCode() {
        if(Objects.isNull(bankingProduct)) {
            return null;
        }

        return bankingProduct
            .getProductName();
    }

    @JsonIgnore
    public BigDecimal getAmount() {
        return paymentAmount;
    }

    @JsonIgnore
    public String getPurpose() {
        return paymentPurpose;
    }

    @JsonIgnore
    public String getEffectiveDate() {
        if(Objects.isNull(paymentDate) || paymentDate.isEmpty()) {
            return null;
        }

        return paymentDate
            .stream().filter(item ->
                item.getDateType() == PaymentDateTimeType.EFFECTIVITY_DATE
            )
            .findFirst()
            .map(PaymentDateTime::getDate)
            .orElse(null);
    }
}
