@SuppressWarnings("unchecked")
  @RequestMapping(
      value = "/admin/customers/page.html",
      method = RequestMethod.POST,
      produces = "application/json")
  public @ResponseBody String pageCustomers(
      HttpServletRequest request, HttpServletResponse response) {

    AjaxPageableResponse resp = new AjaxPageableResponse();

    // Language language = (Language)request.getAttribute("LANGUAGE");
    MerchantStore store = (MerchantStore) request.getAttribute(Constants.ADMIN_STORE);

    try {

      // Map<String,Country> countriesMap = countryService.getCountriesMap(language);

      int startRow = Integer.parseInt(request.getParameter("_startRow"));
      int endRow = Integer.parseInt(request.getParameter("_endRow"));
      String email = request.getParameter("email");
      String name = request.getParameter("name");
      String firstName = request.getParameter("firstName");
      String lastName = request.getParameter("lastName");
      String country = request.getParameter("country");

      CustomerCriteria criteria = new CustomerCriteria();
      criteria.setStartIndex(startRow);
      criteria.setMaxCount(endRow);

      if (!StringUtils.isBlank(email)) {
        criteria.setEmail(email);
      }

      if (!StringUtils.isBlank(name)) {
        criteria.setName(name);
      }

      if (!StringUtils.isBlank(country)) {
        criteria.setCountry(country);
      }

      if (!StringUtils.isBlank(firstName)) {
        criteria.setFirstName(firstName);
      }

      if (!StringUtils.isBlank(lastName)) {
        criteria.setLastName(lastName);
      }

      CustomerList customerList = customerService.listByStore(store, criteria);

      if (customerList.getCustomers() != null) {

        for (Customer customer : customerList.getCustomers()) {
          @SuppressWarnings("rawtypes")
          Map entry = new HashMap();
          entry.put("id", customer.getId());
          entry.put("firstName", customer.getBilling().getFirstName());
          entry.put("lastName", customer.getBilling().getLastName());
          entry.put("email", customer.getEmailAddress());
          entry.put("country", customer.getBilling().getCountry().getIsoCode());
          resp.addDataEntry(entry);
        }
      }

    } catch (Exception e) {
      LOGGER.error("Error while paging orders", e);
      resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE);
    }

    String returnString = resp.toJSONString();

    return returnString;
  }
  @PreAuthorize("hasRole('CUSTOMER')")
  @RequestMapping(
      value = "/admin/customers/resetPassword.html",
      method = RequestMethod.POST,
      produces = "application/json")
  public @ResponseBody String resetPassword(
      HttpServletRequest request, HttpServletResponse response) {

    String customerId = request.getParameter("customerId");

    MerchantStore store = (MerchantStore) request.getAttribute(Constants.ADMIN_STORE);
    AjaxResponse resp = new AjaxResponse();

    try {

      Long id = Long.parseLong(customerId);

      Customer customer = customerService.getById(id);

      if (customer == null) {
        resp.setErrorString("Customer does not exist");
        resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE);
        return resp.toJSONString();
      }

      if (customer.getMerchantStore().getId().intValue() != store.getId().intValue()) {
        resp.setErrorString("Invalid customer id");
        resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE);
        return resp.toJSONString();
      }

      Language userLanguage = customer.getDefaultLanguage();

      Locale customerLocale = LocaleUtils.getLocale(userLanguage);

      String password = UserReset.generateRandomString();
      String encodedPassword = passwordEncoder.encodePassword(password, null);

      customer.setPassword(encodedPassword);

      customerService.saveOrUpdate(customer);

      // send email

      try {

        // creation of a user, send an email
        String[] storeEmail = {store.getStoreEmailAddress()};

        Map<String, String> templateTokens =
            EmailUtils.createEmailObjectsMap(
                request.getContextPath(), store, messages, customerLocale);
        templateTokens.put(
            EmailConstants.LABEL_HI, messages.getMessage("label.generic.hi", customerLocale));
        templateTokens.put(
            EmailConstants.EMAIL_CUSTOMER_FIRSTNAME, customer.getBilling().getFirstName());
        templateTokens.put(
            EmailConstants.EMAIL_CUSTOMER_LASTNAME, customer.getBilling().getLastName());
        templateTokens.put(
            EmailConstants.EMAIL_RESET_PASSWORD_TXT,
            messages.getMessage("email.customer.resetpassword.text", customerLocale));
        templateTokens.put(
            EmailConstants.EMAIL_CONTACT_OWNER,
            messages.getMessage("email.contactowner", storeEmail, customerLocale));
        templateTokens.put(
            EmailConstants.EMAIL_PASSWORD_LABEL,
            messages.getMessage("label.generic.password", customerLocale));
        templateTokens.put(EmailConstants.EMAIL_CUSTOMER_PASSWORD, password);

        Email email = new Email();
        email.setFrom(store.getStorename());
        email.setFromEmail(store.getStoreEmailAddress());
        email.setSubject(messages.getMessage("label.generic.changepassword", customerLocale));
        email.setTo(customer.getEmailAddress());
        email.setTemplateName(RESET_PASSWORD_TPL);
        email.setTemplateTokens(templateTokens);

        emailService.sendHtmlEmail(store, email);
        resp.setStatus(AjaxResponse.RESPONSE_STATUS_SUCCESS);

      } catch (Exception e) {
        LOGGER.error("Cannot send email to user", e);
        resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE);
      }

    } catch (Exception e) {
      LOGGER.error("An exception occured while changing password", e);
      resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE);
    }

    return resp.toJSONString();
  }
  @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";
  }