/**
   * Customer details
   *
   * @param model
   * @param request
   * @param response
   * @return
   * @throws Exception
   */
  @PreAuthorize("hasRole('CUSTOMER')")
  @RequestMapping(value = "/admin/customers/customer.html", method = RequestMethod.GET)
  public String displayCustomer(
      Long id, Model model, HttpServletRequest request, HttpServletResponse response)
      throws Exception {

    // display menu
    this.setMenu(model, request);

    MerchantStore store = (MerchantStore) request.getAttribute(Constants.ADMIN_STORE);

    List<Language> languages = languageService.getLanguages();

    model.addAttribute("languages", languages);

    Customer customer = null;

    // if request.attribute contains id then get this customer from customerService
    if (id != null && id != 0) { // edit mode

      // get from DB
      customer = customerService.getById(id);
      if (customer == null) {
        return "redirect:/admin/customers/list.html";
      }
      if (customer.getMerchantStore().getId().intValue() != store.getId().intValue()) {
        return "redirect:/admin/customers/list.html";
      }

    } else {
      customer = new Customer();
    }
    // get list of countries (see merchant controller)
    Language language = (Language) request.getAttribute("LANGUAGE");
    // get countries
    List<Country> countries = countryService.getCountries(language);

    // get list of zones
    List<Zone> zones = zoneService.list();

    this.getCustomerOptions(model, customer, store, language);

    model.addAttribute("zones", zones);
    model.addAttribute("countries", countries);
    model.addAttribute("customer", customer);
    return "admin-customer";
  }
  @PreAuthorize("hasRole('CUSTOMER')")
  @RequestMapping(value = "/admin/customers/save.html", method = RequestMethod.POST)
  public String saveCustomer(
      @Valid @ModelAttribute("customer") Customer customer,
      BindingResult result,
      Model model,
      HttpServletRequest request,
      Locale locale)
      throws Exception {

    this.setMenu(model, request);

    String email_regEx = "\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}\\b";
    Pattern pattern = Pattern.compile(email_regEx);

    Language language = (Language) request.getAttribute("LANGUAGE");
    MerchantStore store = (MerchantStore) request.getAttribute(Constants.ADMIN_STORE);
    List<Language> languages = languageService.getLanguages();

    model.addAttribute("languages", languages);

    this.getCustomerOptions(model, customer, store, language);

    // get countries
    List<Country> countries = countryService.getCountries(language);

    if (!StringUtils.isBlank(customer.getEmailAddress())) {
      java.util.regex.Matcher matcher = pattern.matcher(customer.getEmailAddress());

      if (!matcher.find()) {
        ObjectError error =
            new ObjectError(
                "customerEmailAddress", messages.getMessage("Email.customer.EmailAddress", locale));
        result.addError(error);
      }
    } else {
      ObjectError error =
          new ObjectError(
              "customerEmailAddress",
              messages.getMessage("NotEmpty.customer.EmailAddress", locale));
      result.addError(error);
    }

    if (StringUtils.isBlank(customer.getBilling().getFirstName())) {
      ObjectError error =
          new ObjectError(
              "billingFirstName",
              messages.getMessage("NotEmpty.customer.billingFirstName", locale));
      result.addError(error);
    }

    if (StringUtils.isBlank(customer.getBilling().getLastName())) {
      ObjectError error =
          new ObjectError(
              "billingLastName", messages.getMessage("NotEmpty.customer.billingLastName", locale));
      result.addError(error);
    }

    if (StringUtils.isBlank(customer.getBilling().getAddress())) {
      ObjectError error =
          new ObjectError(
              "billingAddress",
              messages.getMessage("NotEmpty.customer.billingStreetAddress", locale));
      result.addError(error);
    }

    if (StringUtils.isBlank(customer.getBilling().getCity())) {
      ObjectError error =
          new ObjectError(
              "billingCity", messages.getMessage("NotEmpty.customer.billingCity", locale));
      result.addError(error);
    }

    if (customer.getShowBillingStateList().equalsIgnoreCase("yes")
        && customer.getBilling().getZone().getCode() == null) {
      ObjectError error =
          new ObjectError(
              "billingState", messages.getMessage("NotEmpty.customer.billingState", locale));
      result.addError(error);

    } else if (customer.getShowBillingStateList().equalsIgnoreCase("no")
        && customer.getBilling().getState() == null) {
      ObjectError error =
          new ObjectError(
              "billingState", messages.getMessage("NotEmpty.customer.billingState", locale));
      result.addError(error);
    }

    if (StringUtils.isBlank(customer.getBilling().getPostalCode())) {
      ObjectError error =
          new ObjectError(
              "billingPostalCode",
              messages.getMessage("NotEmpty.customer.billingPostCode", locale));
      result.addError(error);
    }

    // check if error from the @valid
    if (result.hasErrors()) {
      model.addAttribute("countries", countries);
      return "admin-customer";
    }

    Customer newCustomer = new Customer();

    if (customer.getId() != null && customer.getId().longValue() > 0) {
      newCustomer = customerService.getById(customer.getId());

      if (newCustomer == null) {
        return "redirect:/admin/customers/list.html";
      }

      if (newCustomer.getMerchantStore().getId().intValue() != store.getId().intValue()) {
        return "redirect:/admin/customers/list.html";
      }

    } else {
      //  new customer set marchant_Id
      MerchantStore merchantStore = (MerchantStore) request.getAttribute(Constants.ADMIN_STORE);
      newCustomer.setMerchantStore(merchantStore);
    }

    newCustomer.setEmailAddress(customer.getEmailAddress());

    // get Customer country/zone
    Country deliveryCountry =
        countryService.getByCode(customer.getDelivery().getCountry().getIsoCode());
    Country billingCountry =
        countryService.getByCode(customer.getBilling().getCountry().getIsoCode());

    Zone deliveryZone = customer.getDelivery().getZone();
    Zone billingZone = customer.getBilling().getZone();

    if (customer.getShowDeliveryStateList().equalsIgnoreCase("yes")) {
      deliveryZone = zoneService.getByCode(customer.getDelivery().getZone().getCode());
      customer.getDelivery().setState(null);

    } else if (customer.getShowDeliveryStateList().equalsIgnoreCase("no")) {
      deliveryZone = null;
      customer.getDelivery().setState(customer.getDelivery().getState());
    }

    if (customer.getShowBillingStateList().equalsIgnoreCase("yes")) {
      billingZone = zoneService.getByCode(customer.getBilling().getZone().getCode());
      customer.getBilling().setState(null);

    } else if (customer.getShowBillingStateList().equalsIgnoreCase("no")) {
      billingZone = null;
      customer.getBilling().setState(customer.getBilling().getState());
    }

    newCustomer.setDefaultLanguage(customer.getDefaultLanguage());

    customer.getDelivery().setZone(deliveryZone);
    customer.getDelivery().setCountry(deliveryCountry);
    newCustomer.setDelivery(customer.getDelivery());

    customer.getBilling().setZone(billingZone);
    customer.getBilling().setCountry(billingCountry);
    newCustomer.setBilling(customer.getBilling());

    customerService.saveOrUpdate(newCustomer);

    model.addAttribute("customer", newCustomer);
    model.addAttribute("countries", countries);
    model.addAttribute("success", "success");

    return "admin-customer";
  }