package com.braintree.controllers.pages;

import static com.braintree.controllers.Braintreeb2baddonControllerConstants.BRAINTREE_EMPTY_BILLING_ADDRESS_ON_CARD_MESSAGE;
import static com.braintree.controllers.Braintreeb2baddonControllerConstants.BRAINTREE_CVV_VERIFICATION_ERROR;
import static de.hybris.platform.util.localization.Localization.getLocalizedString;

import com.braintree.exceptions.BrainTreeCVVVerificationException;
import com.braintree.exceptions.BrainTreeCardVerifyException;
import com.braintree.facade.impl.DefaultBrainTreeCheckoutFacade;
import com.braintree.facade.impl.DefaultBrainTreePaymentFacade;
import de.hybris.platform.acceleratorstorefrontcommons.annotations.RequireHardLogIn;
import de.hybris.platform.acceleratorstorefrontcommons.checkout.steps.CheckoutStep;
import de.hybris.platform.acceleratorstorefrontcommons.controllers.pages.checkout.steps.AbstractCheckoutStepController;
import de.hybris.platform.acceleratorstorefrontcommons.controllers.util.GlobalMessages;
import de.hybris.platform.cms2.exceptions.CMSItemNotFoundException;
import de.hybris.platform.commerceservices.order.CommerceCartModificationException;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.Resource;


@Controller
@RequestMapping(value = "/checkout/multi/payment-method/braintree")
public class BrainTreePaymentMethodCheckoutStepController extends AbstractCheckoutStepController {

    private static final Logger LOG = Logger.getLogger(BrainTreePaymentMethodCheckoutStepController.class);

    private static final String PAYMENT_METHOD = "payment-method";
    private static final String REDIRECT_TO_SILENT_ORDER_PAGE = REDIRECT_PREFIX + "/checkout/multi/payment-method/add";

    @Resource(name = "brainTreeCheckoutFacade")
    private DefaultBrainTreeCheckoutFacade brainTreeCheckoutFacade;

    @Resource(name = "brainTreePaymentFacadeImpl")
    private DefaultBrainTreePaymentFacade brainTreePaymentFacade;

    @RequestMapping(value = "/choose-cc", method = RequestMethod.GET)
    @RequireHardLogIn
    public String doSelectPaymentMethod(@RequestParam("selectedPaymentMethodId") final String selectedPaymentMethodId,
        @RequestParam("selectedPaymentMethodNonce") final String selectedPaymentMethodNonce,
        @RequestParam(value = "selectedPaymentMethodCvvNonce", required = false) final String selectedPaymentMethodCvvNonce,
        @RequestParam(value = "is3dSecureFlow", defaultValue = "false") final boolean is3dSecureFlow,
        final RedirectAttributes redirectAttributes) {
        if (StringUtils.isNotBlank(selectedPaymentMethodId)) {
            if (StringUtils.isNotBlank(selectedPaymentMethodNonce)) {
                try {
                    brainTreePaymentFacade.verifyThreeDSForSelectedPayment(selectedPaymentMethodId, selectedPaymentMethodNonce);
                    brainTreeCheckoutFacade.setPaymentDetails(selectedPaymentMethodId, selectedPaymentMethodNonce,
                            selectedPaymentMethodCvvNonce, is3dSecureFlow);
                    if (brainTreePaymentFacade.isBillingAddressEmptyOnPaymentInfo(selectedPaymentMethodId)) {
                        GlobalMessages.addFlashMessage(redirectAttributes, GlobalMessages.INFO_MESSAGES_HOLDER,
                                getLocalizedString(BRAINTREE_EMPTY_BILLING_ADDRESS_ON_CARD_MESSAGE));
                    }
                } catch (BrainTreeCVVVerificationException exception) {
                    LOG.error(exception.getMessage(), exception);
                    String localizedErrorMessage = getLocalizedString(BRAINTREE_CVV_VERIFICATION_ERROR);
                    GlobalMessages.addFlashMessage(redirectAttributes, GlobalMessages.ERROR_MESSAGES_HOLDER, localizedErrorMessage);
                    return REDIRECT_TO_SILENT_ORDER_PAGE;
                } catch (Exception exception) {
                    LOG.error(exception.getMessage(), exception);
                    String error = "braintree.billing.general.error";
                    GlobalMessages.addFlashMessage(redirectAttributes, GlobalMessages.ERROR_MESSAGES_HOLDER,
                            getLocalizedString(error));
                    return REDIRECT_TO_SILENT_ORDER_PAGE;
                }
            } else {
                getCheckoutFacade().setPaymentDetails(selectedPaymentMethodId);
            }
        }
        return getCheckoutStep().nextStep();
    }

    protected CheckoutStep getCheckoutStep() {
        return getCheckoutStep(PAYMENT_METHOD);
    }

    @Override
    public String enterStep(Model model, RedirectAttributes redirectAttributes) throws CMSItemNotFoundException, CommerceCartModificationException {
        return null;
    }

    @Override
    public String back(RedirectAttributes redirectAttributes) {
        return null;
    }

    @Override
    public String next(RedirectAttributes redirectAttributes) {
        return null;
    }
}
