package com.braintree.populators;

import com.braintree.command.result.BrainTreePaymentDetailsResult;
import com.braintree.constants.BraintreeConstants;
import com.braintree.enums.BrainTreePaymentMethod;
import com.braintree.util.BrainTreeUtils;
import com.braintreegateway.AndroidPayCard;
import com.braintreegateway.CreditCard;
import com.braintreegateway.PayPalAccount;
import com.braintreegateway.PaymentMethod;
import com.braintreegateway.VenmoAccount;
import com.braintreegateway.VisaCheckoutCard;
import de.hybris.platform.converters.Populator;
import de.hybris.platform.servicelayer.dto.converter.ConversionException;
import org.apache.commons.lang.StringUtils;

import java.util.Optional;

/**
 * Populates BrainTreePaymentDetailsResult from PaymentMethod.
 */
public class BrainTreePaymentMethodToPaymentDetailsPopulator implements
        Populator<PaymentMethod, BrainTreePaymentDetailsResult> {

    @Override
    public void populate(PaymentMethod source, BrainTreePaymentDetailsResult target)
            throws ConversionException {

        PayPalAccount payPal;
        CreditCard card;
        VenmoAccount venmo;
        AndroidPayCard googlePay;
        VisaCheckoutCard src;

        if (source instanceof PayPalAccount) {
            payPal = (PayPalAccount) source;
            target.setPaymentProvider(BrainTreePaymentMethod.PAYPALACCOUNT.getCode());
            target.setPaymentMethodToken(payPal.getToken());
            target.setImageUrl(payPal.getImageUrl());
            target.setEmail(payPal.getEmail());
            target.setExpirationMonth(StringUtils.EMPTY);
            target.setCardType(StringUtils.EMPTY);
            target.setExpirationYear(StringUtils.EMPTY);
            target.setCardNumber(StringUtils.EMPTY);
            target.setCardholderName(StringUtils.EMPTY);
        } else if (source instanceof CreditCard) {
            card = (CreditCard) source;
            target.setPaymentProvider(BrainTreePaymentMethod.CREDITCARD.getCode());
            target.setPaymentMethodToken(card.getToken());
            target.setCardType(card.getCardType());
            target.setExpirationMonth(card.getExpirationMonth());
            target.setExpirationYear(card.getExpirationYear());
            target.setCardNumber(card.getMaskedNumber());
            target.setCardholderName(card.getCardholderName());
            target.setImageUrl(card.getImageUrl());
            Optional.ofNullable(card.getBillingAddress())
                    .map(BrainTreeUtils::convertRestBrainTreeAddress)
                    .ifPresent(target::setBillingAddress);
        } else if (source instanceof VenmoAccount) {
            venmo = (VenmoAccount) source;
            target.setPaymentProvider(BrainTreePaymentMethod.VENMOACCOUNT.getCode());
            target.setPaymentMethodToken(venmo.getToken());
            target.setImageUrl(venmo.getImageUrl());
            target.setCardType(StringUtils.EMPTY);
            target.setExpirationMonth(StringUtils.EMPTY);
            target.setExpirationYear(StringUtils.EMPTY);
            target.setCardNumber(StringUtils.EMPTY);
            target.setCardholderName(StringUtils.EMPTY);
        } else if (source instanceof AndroidPayCard) {
            googlePay = (AndroidPayCard) source;
            target.setPaymentProvider(BrainTreePaymentMethod.ANDROIDPAYCARD.getCode());
            target.setPaymentMethodToken(googlePay.getToken());
            target.setImageUrl(googlePay.getImageUrl());
            target.setCardType(googlePay.getSourceCardType());
            target.setExpirationMonth(googlePay.getExpirationMonth());
            target.setExpirationYear(googlePay.getExpirationYear());
            target.setCardNumber(String.format(BraintreeConstants.CARD_NUMBER_MASK, googlePay.getSourceCardLast4()));
        } else if (source instanceof VisaCheckoutCard) {
            src = (VisaCheckoutCard) source;
            target.setPaymentProvider(BrainTreePaymentMethod.VISACHECKOUTCARD.getCode());
            target.setPaymentMethodToken(src.getToken());
            target.setImageUrl(src.getImageUrl());
            target.setCardType(src.getCardType());
            target.setExpirationMonth(src.getExpirationMonth());
            target.setExpirationYear(src.getExpirationYear());
            target.setCardNumber(String.format(BraintreeConstants.CARD_NUMBER_MASK, src.getLast4()));
            target.setCardholderName(StringUtils.EMPTY);
        }

    }
}
