package com.braintree.customersupportbackoffice.renderers;

import com.braintree.customersupportbackoffice.constants.BraintreeCustomerSupportBackofficeConstants;
import com.braintree.customersupportbackoffice.facade.BraintreeCheckConnectionFacade;
import com.braintree.customersupportbackoffice.constants.BraintreeCustomerSupportBackofficeConstants.Constant;
import com.braintree.customersupportbackoffice.constants.BraintreeCustomerSupportBackofficeConstants.Style;
import com.braintree.customersupportbackoffice.constants.BraintreeCustomerSupportBackofficeConstants.Text;
import com.hybris.cockpitng.core.config.impl.jaxb.editorarea.AbstractPanel;
import com.hybris.cockpitng.dataaccess.facades.type.DataType;
import com.hybris.cockpitng.engine.WidgetInstanceManager;
import com.hybris.cockpitng.widgets.editorarea.renderer.impl.AbstractEditorAreaPanelRenderer;
import de.hybris.platform.core.model.BraintreePluginConfigurationModel;
import de.hybris.platform.servicelayer.model.ModelService;
import org.apache.commons.collections4.MapUtils;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Components;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.util.resource.Labels;
import org.zkoss.zul.Button;
import org.zkoss.zul.Div;
import org.zkoss.zul.Html;

import java.util.List;

public class BraintreeCheckConnectionRenderer extends AbstractEditorAreaPanelRenderer<BraintreePluginConfigurationModel> {

    private BraintreeCheckConnectionFacade checkConnectionFacade;
    private ModelService modelService;

    @Override
    public void render(Component component, AbstractPanel abstractPanel,
                       BraintreePluginConfigurationModel pluginConfiguration, DataType dataType,
                       WidgetInstanceManager widgetInstanceManager) {
        component.appendChild(getMainDiv(component, pluginConfiguration));
    }

    protected Div getMainDiv(Component component, BraintreePluginConfigurationModel pluginConfiguration) {
        Div div = getNewDiv();
        div.appendChild(getRefreshButton(component, pluginConfiguration));
        div.appendChild(getConnectWithBraintreeSetupDiv());
        div.appendChild(getPluginConfigurationCheckSetupDiv(pluginConfiguration));

        if (pluginConfiguration.getBraintreeConnectWithPayPalConfiguration().isEnable()) {
            div.appendChild(getPaypalConfigurationCheckDiv());
        }
        return div;
    }

    protected Div getRefreshButton(Component component,BraintreePluginConfigurationModel pluginConfiguration){
        Button button = getNewButton(getLabel(Text.REFRESH_BUTTON));
        button.addEventListener(Events.ON_CLICK, new EventListener<Event>()
        {
            @Override
            public void onEvent(final Event event) throws Exception
            {
                Components.removeAllChildren(component);
                modelService.refresh(pluginConfiguration);
                component.appendChild(getMainDiv(component, pluginConfiguration));
            }
        });
        Div div = getNewDiv();
        div.appendChild(button);
        div.setStyle(Style.REFRESH_BUTTON);
        return div;
    }

    protected Div getConnectWithBraintreeSetupDiv() {
        Div div = getNewDiv();
        div.setStyle(Style.BLOCK);
        div.appendChild(getNewHtml("1. " + getLabel(Text.ESSENTIAL_CONFIG_CHECK)));

        div.appendChild(getResultDiv(Text.BRAINTREE_MERCHANT_ID, checkConnectionFacade.isMerchantIDPresented() ? Text.SUCCESS : Text.FAIL));
        div.appendChild(getResultDiv(Text.BRAINTREE_PUBLICK_KEY, checkConnectionFacade.isPublicKeyPresented() ? Text.SUCCESS : Text.FAIL));
        div.appendChild(getResultDiv(Text.BRAINTREE_PRIVATE_KEY, checkConnectionFacade.isPrivateKeyPresented() ? Text.SUCCESS : Text.FAIL));
        div.appendChild(getResultDiv(Text.BRAINTREE_ENVIROMENT_TYPE, checkConnectionFacade.isEnvironmentPresented() ? Text.SUCCESS : Text.FAIL));

        if (checkConnectionFacade.canCheckConnectWithBraintree()) {
            div.appendChild(getResultDiv(Text.CONNECT_WITH_BRAINTREE, checkConnectionFacade.isBraintreePingPresented() ? Text.SUCCESS : Text.FAIL));
        }
        return div;
    }

    protected Div getPluginConfigurationCheckSetupDiv(BraintreePluginConfigurationModel conf) {
        Div div = getNewDiv();
        div.setStyle(Style.BLOCK);
        div.appendChild(getNewHtml("2. " + getLabel(Text.PLUGIN_CONFIGURATION_CHECK)));

        div.appendChild(getResultDiv(Text.CONFIGURATION_USAGE, null));
        getConfigurationUsageChildSetupDiv(conf, div);

        div.appendChild(getResultDiv(Text.GENERAL, null));
        div.appendChild(getChildResultDiv(Text.MERCHANT_ACCOUNT_ID, MapUtils.isEmpty(conf.getBraintreeGeneralConfiguration().getMerchantAccountId()) ? Text.FALSE : Text.TRUE ));

        div.appendChild(getResultDiv(Text.CONNECT_WITH_PAYPAL, null));
        div.appendChild(getChildResultDiv(Text.ENABLE, conf.getBraintreeConnectWithPayPalConfiguration().isEnable() ? Text.TRUE : Text.FALSE));

        div.appendChild(getResultDiv(Text.PAYPAL, conf.getBraintreePayPalConfiguration() != null ? Text.PRESENT : Text.ABSENT));
        if (conf.getBraintreePayPalConfiguration() != null) {
            div.appendChild(getChildResultDiv(Text.ENABLE, conf.getBraintreePayPalConfiguration().isPayPalEnabled() ? Text.TRUE : Text.FALSE));
        }

        div.appendChild(getResultDiv(Text.VENMO, conf.getBraintreeVenmoConfiguration() != null ? Text.PRESENT : Text.ABSENT));
        if (conf.getBraintreeVenmoConfiguration() != null) {
            div.appendChild(getChildResultDiv(Text.ENABLE, conf.getBraintreeVenmoConfiguration().isEnabled() ? Text.TRUE : Text.FALSE));
        }

        div.appendChild(getResultDiv(Text.LPM, conf.getBraintreeLocalPaymentsConfiguration() != null ? Text.PRESENT : Text.ABSENT));
        if (conf.getBraintreeLocalPaymentsConfiguration() != null) {
            div.appendChild(getChildResultDiv(Text.ENABLE, conf.getBraintreeLocalPaymentsConfiguration().isEnabled() ? Text.TRUE : Text.FALSE));
        }

        div.appendChild(getResultDiv(Text.HOSTED_FIELDS, conf.getBraintreeHostedFieldsConfiguration() != null ? Text.PRESENT : Text.ABSENT));
        if (conf.getBraintreeHostedFieldsConfiguration() != null) {
            div.appendChild(getChildResultDiv(Text.ENABLE, conf.getBraintreeHostedFieldsConfiguration().isEnabled() ? Text.TRUE : Text.FALSE));
        }

        div.appendChild(getResultDiv(Text.APPLE_PAY, conf.getBraintreeApplePayConfiguration() != null ? Text.PRESENT : Text.ABSENT));
        if (conf.getBraintreeApplePayConfiguration() != null) {
            div.appendChild(getChildResultDiv(Text.ENABLE, conf.getBraintreeApplePayConfiguration().isEnabled() ? Text.TRUE : Text.FALSE));
        }

        div.appendChild(getResultDiv(Text.GOOGLE_PAY, conf.getBraintreeGooglePayConfiguration() != null ? Text.PRESENT : Text.ABSENT));
        if (conf.getBraintreeGooglePayConfiguration() != null) {
            div.appendChild(getChildResultDiv(Text.ENABLE, conf.getBraintreeGooglePayConfiguration().isEnabled() ? Text.TRUE : Text.FALSE));
        }

        div.appendChild(getResultDiv(Text.SRC, conf.getBraintreeSRCConfiguration() != null ? Text.PRESENT : Text.ABSENT));
        if (conf.getBraintreeSRCConfiguration() != null) {
            div.appendChild(getChildResultDiv(Text.ENABLE, conf.getBraintreeSRCConfiguration().isEnabled() ? Text.TRUE : Text.FALSE));
        }

        div.appendChild(getResultDiv(Text.ACH, conf.getBraintreeACHConfiguration() != null ? Text.PRESENT : Text.ABSENT));
        if (conf.getBraintreeACHConfiguration() != null) {
            div.appendChild(getChildResultDiv(Text.ENABLE, conf.getBraintreeACHConfiguration().isEnabled() ? Text.TRUE : Text.FALSE));
        }

        return div;
    }

    protected Div getPaypalConfigurationCheckDiv() {
        Div div = getNewDiv();
        div.setStyle(Style.BLOCK);
        div.appendChild(getNewHtml("3. " + getLabel(Text.PAYPAL_CONFIGURATION_CHECK)));

        div.appendChild(getResultDiv(Text.PAYPAL_CLIENT_ID, checkConnectionFacade.isPayPalClientIdPresented() ? Text.SUCCESS : Text.FAIL));
        div.appendChild(getResultDiv(Text.PAYPAL_SECRET_KEY, checkConnectionFacade.isPayPalSecretKeyPresented() ? Text.SUCCESS : Text.FAIL));

        if (checkConnectionFacade.canCheckConnectWithPayPal()) {
            div.appendChild(getResultDiv(Text.CONNECT_WITH_PAYPAL, checkConnectionFacade.canEstablishConnectWithPayPal() ? Text.SUCCESS : Text.FAIL));
        }
        return div;
    }

    protected void getConfigurationUsageChildSetupDiv(BraintreePluginConfigurationModel conf, Div div) {
        List<String> baseStoreNames = checkConnectionFacade.getBaseStoreNames(conf);
        if (baseStoreNames.isEmpty()) {
            Div childResultDiv = getChildResultDiv(Text.NON_USE_THIS_CONFIGURATION, null);
            Div childValueDiv = (Div) childResultDiv.getChildren().stream().findFirst().get();
            childValueDiv.setStyle(Style.NON_USE_THIS_CONFIGURATION);
            div.appendChild(childResultDiv);
        } else {
            baseStoreNames.forEach(name -> div.appendChild(getBaseStoreNameDiv(name)));
        }
    }

    protected Div getBaseStoreNameDiv(String value) {
        Div valueDiv = getNewDiv();
        valueDiv.appendChild(getNewHtml("&#x2022; " + value));
        valueDiv.setStyle(Style.CHILD_RESULT_VALUE);
        Div div = getNewDiv();
        div.appendChild(valueDiv);
        div.setStyle(Style.RESULT);
        return div;
    }

    protected Div getChildResultDiv(String value, String success) {
        Div div = getNewDiv();
        div.appendChild(getValueDiv(value, true));
        if (success != null) {
            div.appendChild(getStatusDiv(success));
        }
        div.setStyle(Style.RESULT);
        return div;
    }

    protected Div getResultDiv(String value, String success) {
        Div div = getNewDiv();
        div.appendChild(getValueDiv(value, false));
        if (success != null) {
            div.appendChild(getStatusDiv(success));
        }
        div.setStyle(Style.RESULT);
        return div;
    }

    protected Div getValueDiv(String value, boolean isChildDiv) {
        Div div = getNewDiv();
        div.appendChild(getNewHtml("&#x2022; " + getLabel(value)));
        div.setStyle(isChildDiv ? Style.CHILD_RESULT_VALUE : Style.RESULT_VALUE);
        return div;
    }

    protected Div getStatusDiv(String success) {
        Div div = getNewDiv();
        div.appendChild(getNewHtml(getLabel(success)));
        div.setStyle(getStyle(success));
        return div;
    }

    protected String getStyle(String success) {
        if (success.contains(Constant.SUCCESS) || success.contains(Constant.TRUE)) {
            return Style.RESULT_STATUS_SUCCESS;
        } else if (success.contains(Constant.FAIL) || success.contains(Constant.FALSE)) {
            return Style.RESULT_STATUS_FAIL;
        } else {
            return Style.RESULT_STATUS;
        }
    }

    protected String getLabel(String label) {
        return Labels.getLabel(label);
    }

    protected Div getNewDiv() {
        return new Div();
    }

    protected Button getNewButton(String text) {
        return new Button(text);
    }

    protected Html getNewHtml(String text) {
        return new Html(text);
    }

    public void setCheckConnectionFacade(BraintreeCheckConnectionFacade checkConnectionFacade) {
        this.checkConnectionFacade = checkConnectionFacade;
    }

    public void setModelService(ModelService modelService) {
        this.modelService = modelService;
    }
}
