package com.braintreeocc.controllers;

import com.braintree.enums.BraintreePageType;
import com.braintree.facade.impl.DefaultBrainTreeCheckoutFacade;
import com.braintree.facade.BraintreeConfigurationFacade;
import com.braintree.hybris.data.BraintreeCheckoutData;
import com.braintree.hybris.data.PayPalButtonStyleData;
import com.braintree.hybris.data.ws.BraintreeAssetsWsDTO;
import com.braintree.hybris.data.ws.BraintreeButtonStyleWsDTO;
import com.braintreeocc.validators.BraintreeButtonTypeValidator;
import com.braintree.hybris.data.BraintreeButtonStyleData;
import com.braintree.hybris.data.ws.PayPalCheckoutWsDTO;
import com.braintree.hybris.data.GooglePayButtonStyleData;
import com.braintree.hybris.data.BraintreePluginConfigurationData;
import com.braintree.hybris.data.ws.BraintreePluginConfigurationWsDTO;
import de.hybris.platform.webservicescommons.swagger.ApiBaseSiteIdParam;
import io.swagger.annotations.Api;
import com.braintree.facade.BrainTreeStylesConfigurationFacade;
import com.braintree.hybris.data.ApplePayButtonStyleData;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import javax.annotation.Resource;

import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.Optional;

@Controller
@RequestMapping(value = "/{baseSiteId}")
@Api(tags = "Braintree Payment")
public class BraintreePaymentController extends BraintreeBaseController {

    @Resource(name = "braintreeButtonTypeValidator")
    private BraintreeButtonTypeValidator buttonTypeValidator;

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

    @Resource
    private BrainTreeStylesConfigurationFacade brainTreeStylesConfigurationFacade;
    @Resource
    private BraintreeConfigurationFacade braintreeConfigurationFacade;

    @GetMapping("/users/{userId}/braintree/payment")
    @ResponseStatus(value = HttpStatus.OK)
    @ResponseBody
    @ApiBaseSiteIdParam
    @ApiOperation(value = " Get the Braintree data for client-side payment initialization",
        notes = "Get a data for all payment methods")
    public PayPalCheckoutWsDTO getPaymentData(
        @ApiParam(value = "Payment method identifier.", allowableValues = "paypal, googlepay, venmo, applepay," +
            " localpayments, creditcard, configData, full", required = true) @RequestParam final String paymentMethod,
        @ApiParam(value = "Page type", defaultValue = "MARK")
        @RequestParam(defaultValue = "MARK", required = false) final String pageType) {
        final BraintreePageType braintreePageType = BraintreePageType.valueOf(pageType);
        final BraintreeCheckoutData braintreeCheckoutData = brainTreeCheckoutFacade.getBraintreeCheckoutData(braintreePageType);
        return getDataMapper().map(braintreeCheckoutData, PayPalCheckoutWsDTO.class, paymentMethod);
    }

    @GetMapping("/users/{userId}/braintree/config")
    @ResponseStatus(value = HttpStatus.OK)
    @ResponseBody
    @ApiBaseSiteIdParam
    @ApiOperation(value = "Get the Plugin Configuration data for client-side payment initialization",
            notes = "Get a data for all configurations")
    public BraintreePluginConfigurationWsDTO getConfigurationData() {
        final BraintreePluginConfigurationData pluginConfigurationData = braintreeConfigurationFacade.getBraintreePluginConfigurationData();
        return getDataMapper().map(pluginConfigurationData, BraintreePluginConfigurationWsDTO.class);
    }

    @GetMapping("/users/{userId}/braintree/payment/button")
    @ResponseStatus(value = HttpStatus.OK)
    @ResponseBody
    @ApiBaseSiteIdParam
    @ApiOperation(value = " Get the PayPal Smart Button style data.")
    public BraintreeButtonStyleWsDTO getButtonStyle(
        @ApiParam(value = "Button type identifier.", allowableValues = "account, minicart, cart, mark",
            required = true) @RequestParam final String pageType) {
        validate(pageType, pageType, buttonTypeValidator);

        BraintreePageType upperCasedPageType = BraintreePageType.valueOf(pageType.toUpperCase());
        Optional<PayPalButtonStyleData> payPalButtonStyleData =
                brainTreeStylesConfigurationFacade.getPayPalStyleConfiguration(upperCasedPageType);
        Optional<GooglePayButtonStyleData> googlePayButtonStyleData =
                brainTreeStylesConfigurationFacade.getGooglePayStyleConfiguration(upperCasedPageType);
        Optional<ApplePayButtonStyleData> applePayButtonStyleData =
                brainTreeStylesConfigurationFacade.getApplePayStyleConfigurationFor(pageType.equals(BraintreePageType.ACCOUNT.name()) ? BraintreePageType.MARK : upperCasedPageType);

        BraintreeButtonStyleData braintreeButtonStyle = new BraintreeButtonStyleData();
        payPalButtonStyleData.ifPresent(braintreeButtonStyle::setPayPalButtonStyle);
        googlePayButtonStyleData.ifPresent(braintreeButtonStyle::setGooglePayButtonStyle);
        applePayButtonStyleData.ifPresent(braintreeButtonStyle::setApplePayButtonStyle);

        return getDataMapper().map(braintreeButtonStyle, BraintreeButtonStyleWsDTO.class);
    }

    @GetMapping("/braintree/payment/assets")
    @ResponseStatus(value = HttpStatus.OK)
    @ResponseBody
    @ApiBaseSiteIdParam
    @ApiOperation(value = " Get assets for checkout.")
    public BraintreeAssetsWsDTO getAssets() {
        return getDataMapper().map(brainTreeCheckoutFacade.getBraintreeAssets(), BraintreeAssetsWsDTO.class);
    }
}
