package com.braintree.populators;

import com.braintree.hybris.data.BrainTreeGraphQLCustomerData;
import com.braintree.hybris.data.graphql.commands.response.BrainTreeCustomer;
import com.braintree.hybris.data.graphql.commands.response.BrainTreeCustomerConnection;
import com.braintree.hybris.data.graphql.commands.response.BrainTreeCustomerConnectionEdge;
import com.braintree.hybris.data.graphql.commands.response.BraintreePaymentMethodData;
import com.braintree.hybris.data.graphql.commands.response.BrainTreePaymentMethodConnectionEdge;
import com.braintree.model.BrainTreePaymentInfoModel;
import com.braintree.model.BraintreeCustomerDetailsModel;
import de.hybris.platform.converters.Populator;
import de.hybris.platform.servicelayer.dto.converter.ConversionException;
import de.hybris.platform.servicelayer.dto.converter.Converter;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Populates BrainTreeGraphQLCustomerData from BrainTreeCustomerConnection.
 */
public class BraintreeGraphQLCustomerPopulator implements
        Populator<BrainTreeCustomerConnection, BrainTreeGraphQLCustomerData> {

    private Converter<BraintreePaymentMethodData, BrainTreePaymentInfoModel> graphQLPaymentMethodToModel;

    @Override
    public void populate(BrainTreeCustomerConnection source, BrainTreeGraphQLCustomerData target)
            throws ConversionException {

        target.setHasNextPage(source.getPageInfo().isHasNextPage());
        target.setEndCursor(source.getPageInfo().getEndCursor());

        List<BraintreeCustomerDetailsModel> customerList = new ArrayList<>();

        for (BrainTreeCustomerConnectionEdge edge : source.getEdges()) {
            BrainTreeCustomer customer = edge.getNode();
            if (customer != null) {
                BraintreeCustomerDetailsModel customerDetails = new BraintreeCustomerDetailsModel();
                customerDetails.setId(customer.getLegacyId());
                customerDetails.setGraphQLId(customer.getId());
                customerDetails.setCompany(customer.getCompany());
                customerDetails.setCreatedAt(customer.getCreatedAt().getTime());
                customerDetails.setEmail(customer.getEmail());
                customerDetails.setFirstName(customer.getFirstName());
                customerDetails.setLastName(customer.getLastName());
                customerDetails.setPhone(customer.getPhoneNumber());

                if (customer.getPaymentMethods() != null) {
                    List<BrainTreePaymentInfoModel> infoModels = customer.getPaymentMethods()
                            .getEdges()
                            .stream()
                            .map(BrainTreePaymentMethodConnectionEdge::getNode)
                            .map(graphQLPaymentMethodToModel::convert)
                            .collect(Collectors.toList());
                    customerDetails.setPaymentMethods(infoModels);
                }
                customerList.add(customerDetails);
            }
        }

        target.setCustomerList(customerList);
    }

    public void setGraphQLPaymentMethodToModel(
            Converter<BraintreePaymentMethodData, BrainTreePaymentInfoModel> graphQLPaymentMethodToModel) {
        this.graphQLPaymentMethodToModel = graphQLPaymentMethodToModel;
    }
}
