package com.braintree.controllers.pages;

import de.hybris.platform.acceleratorstorefrontcommons.breadcrumb.Breadcrumb;
import de.hybris.platform.acceleratorstorefrontcommons.controllers.util.GlobalMessages;
import de.hybris.platform.b2bacceleratoraddon.constants.B2bacceleratoraddonWebConstants;
import de.hybris.platform.b2bacceleratoraddon.controllers.secureportal.AbstractB2BRegistrationController;
import de.hybris.platform.b2bacceleratoraddon.forms.RegistrationForm;
import de.hybris.platform.b2bacceleratorfacades.exception.CustomerAlreadyExistsException;
import de.hybris.platform.b2bacceleratorfacades.exception.RegistrationNotEnabledException;
import de.hybris.platform.b2bacceleratorfacades.registration.B2BRegistrationFacade;
import de.hybris.platform.b2bcommercefacades.data.B2BRegistrationData;
import de.hybris.platform.cms2.exceptions.CMSItemNotFoundException;
import de.hybris.platform.cms2.model.pages.AbstractPageModel;
import de.hybris.platform.cms2.model.pages.ContentPageModel;
import de.hybris.platform.util.localization.Localization;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.support.RequestContextUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Collections;

@RequestMapping(value = B2bacceleratoraddonWebConstants.RequestMappings.ACCOUNT_REGISTRATION)
public class BrainTreeB2BRegistrationController extends AbstractB2BRegistrationController
{
    private static final Logger LOG = Logger.getLogger(BrainTreeB2BRegistrationController.class);

    private static final String REGISTER_SUBMIT_CONFIRMATION = "text.braintree.register.submit.confirmation";
    private static final String SCP_LINK_CREATE_ACCOUNT = "text.secureportal.link.createAccount";
    private static final String REGISTER_ACCOUNT_EXISTING = "text.braintree.register.account.existing";
    private static final String HOME_REDIRECT = REDIRECT_PREFIX + ROOT;
    private static final String LOGIN_PAGE_REDIRECT = REDIRECT_PREFIX + "/login";

    @Resource(name = "b2bRegistrationFacade")
    private B2BRegistrationFacade b2bRegistrationFacade;

    @Resource(name = "brainTreeSecurePortalRegistrationValidator")
    private Validator registrationValidator;

    @RequestMapping(method = RequestMethod.GET)
    public String showRegistrationPage(final HttpServletRequest request, final Model model) throws CMSItemNotFoundException
    {
        if (getCmsSiteService().getCurrentSite().isEnableRegistration())
        {
            return getDefaultRegistrationPage(model, getContentPageForLabelOrId(getRegistrationCmsPage()));
        }
        return HOME_REDIRECT;
    }

    @RequestMapping(method = RequestMethod.POST)
    public String submitRegistration(final RegistrationForm form, final BindingResult bindingResult, final Model model,
                                     final HttpServletRequest request, final HttpSession session, final RedirectAttributes redirectModel)
            throws CMSItemNotFoundException
    {

        populateModelCmsContent(model, getContentPageForLabelOrId(getRegistrationCmsPage()));
        model.addAttribute(form);

        getRegistrationValidator().validate(form, bindingResult);
        if (bindingResult.hasErrors())
        {
            GlobalMessages.addErrorMessage(model, "form.global.error");
            return getRegistrationView();
        }

        try
        {
            b2bRegistrationFacade.register(convertFormToData(form));
        }
        catch (final CustomerAlreadyExistsException | RegistrationNotEnabledException e) //NOSONAR
        {
            LOG.error("Failed to register account. Account already exists.");
            GlobalMessages.addErrorMessage(model, Localization.getLocalizedString(REGISTER_ACCOUNT_EXISTING));
            return getRegistrationView();
        }

        GlobalMessages.addFlashMessage(RequestContextUtils.getOutputFlashMap(request), GlobalMessages.INFO_MESSAGES_HOLDER,
                Localization.getLocalizedString(REGISTER_SUBMIT_CONFIRMATION), null);

        return LOGIN_PAGE_REDIRECT;
    }

    protected B2BRegistrationData convertFormToData(final RegistrationForm form)
    {
        final B2BRegistrationData registrationData = new B2BRegistrationData();
        BeanUtils.copyProperties(form, registrationData);
        registrationData.setName(StringUtils.trim(form.getFirstName()) + " " + StringUtils.trim(form.getLastName()));
        return registrationData;
    }

    @Override
    protected Validator getRegistrationValidator()
    {
        return registrationValidator;
    }

    @Override
    protected String getRegistrationView()
    {
        return B2bacceleratoraddonWebConstants.Views.REGISTRATION_PAGE;
    }

    @Override
    protected String getRegistrationCmsPage()
    {
        return B2bacceleratoraddonWebConstants.CMS_REGISTER_PAGE_NAME;
    }

    @Override
    protected void populateModelCmsContent(final Model model, final ContentPageModel contentPageModel)
    {

        storeCmsPageInModel(model, contentPageModel);
        setUpMetaDataForContentPage(model, contentPageModel);

        final Breadcrumb registrationBreadcrumbEntry = new Breadcrumb("#",
                getMessageSource().getMessage(SCP_LINK_CREATE_ACCOUNT, null, getI18nService().getCurrentLocale()), null);
        model.addAttribute("breadcrumbs", Collections.singletonList(registrationBreadcrumbEntry));
    }

    @Override
    protected String getView()
    {
        return B2bacceleratoraddonWebConstants.Views.LOGIN_PAGE;
    }

    @Override
    protected AbstractPageModel getCmsPage() throws CMSItemNotFoundException
    {
        return getContentPageForLabelOrId("login");
    }

    @Override
    protected String getSuccessRedirect(final HttpServletRequest request, final HttpServletResponse response)
    {
        return HOME_REDIRECT;
    }
}
