package gov.va.med.esr.ui.admin.action;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import gov.va.med.esr.common.model.lookup.EEServiceField;
import gov.va.med.esr.common.model.security.EEServiceRequest;
import gov.va.med.esr.common.model.security.EEServiceRequestField;
import gov.va.med.esr.common.model.security.EEServiceRequestLite;
import gov.va.med.esr.common.model.security.EEServiceUser;
import gov.va.med.esr.common.model.security.EEServiceUserRequest;
import gov.va.med.esr.ui.ApplicationConstants.MessageKeys;
import gov.va.med.esr.ui.common.action.AbstractAction;
import gov.va.med.esr.ui.common.util.EdbStrutsValidator;
import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.model.EntityKeyFactory;
import gov.va.med.fw.security.PasswordEncryptionService;

public class ServiceUserAction extends AbstractAction {
	
	public static final String FORWARD_DISPLAY_LIST_SUCCESS = "listsuccess";

	public static final String USER_SAVED = "message.serviceUserAdded";

	public static final String USER_UPDATED = "message.serviceUserUpdated";

	public static final String FORWARD_DISPLAY_EDIT = "displayEdit";

	public static final String FORWARD_DISPLAY_NEW = "displayNew";

	public static final String REQUIRED = MessageKeys.ERRORS_REQUIRED;

	public static final String LABEL_KEY_USERNAME = "Account Name";

	public static final String LABEL_KEY_PASSWORD = "Password";

	public static final String LABEL_KEY_CONTACTNAME = "Contact Name";

	public static final String LABEL_KEY_CONTACTPHONE = "Phone";

	public static final String FIELD_UNIQUE = "error.uniquename";

	public static final String PASSWORD_NOT_VALID = "message.changePassword.password"; //ESR 4.0_CodeCR12941
	public static final String MASKED_PASSWORD = "************"; //ESR 4.0_CodeCR12941

	public ActionForward list(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		List serviceUsers = getEeServiceAdminService().getEEServiceUsers();
		if (serviceUsers != null && !serviceUsers.isEmpty())
			request.setAttribute("serviceUsers", serviceUsers);

		return mapping.findForward(FORWARD_DISPLAY_LIST_SUCCESS);
	}

	public ActionForward display(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		ServiceUserForm serviceUserForm = (ServiceUserForm) form;

		String userId = serviceUserForm.getUserId();
		EntityKey key = EntityKeyFactory.createEntityKey(userId,
				EEServiceUser.class);
		EEServiceUser serviceUser = getEeServiceAdminService()
				.getEEserviceUser(key);
		serviceUserForm.clearForm();
		serviceUserForm.setUserId(serviceUser.getIdentifier().toString());
		serviceUserForm.setUserName(serviceUser.getUserName());
		//CodeCR12941 - Do not display or return encrypted password to UI
		serviceUserForm.setPassword(MASKED_PASSWORD);
		serviceUserForm.setContactName(serviceUser.getContactName());
		serviceUserForm.setContactPhone(serviceUser.getContactPhone());
		serviceUserForm.setActive(serviceUser.getActive());

		List requests = getEeServiceAdminService().getEEServiceLiteRequests();
		serviceUserForm.setRequestList(requests);

		serviceUserForm.setSelectedRequestMap(serviceUser.getEeServiceUserRequests());
		return mapping.findForward("displayEdit");
	}

	public ActionForward saveUser(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		boolean isFormValid = validateForm(mapping, form, request, response);

		ServiceUserForm serviceUserForm = (ServiceUserForm) form;
		EEServiceUser eeServiceUser = null;
		if (!isFormValid) {
			return mapping.findForward(FORWARD_DISPLAY_EDIT);
		}

		if (eeServiceUser == null) {
			eeServiceUser = new EEServiceUser();
		}
		eeServiceUser.setUserName(serviceUserForm.getUserName().trim());
		eeServiceUser.setContactName(serviceUserForm.getContactName().trim());
		eeServiceUser.setContactPhone(serviceUserForm.getContactPhone().trim());

		//ESR 4.0_CodeCR12941
		if (!MASKED_PASSWORD.equals(serviceUserForm.getPassword().trim())) {
			eeServiceUser.setPassword(serviceUserForm.getPassword().trim());
		}
		eeServiceUser.setActive(serviceUserForm.isActive());

		String[] selectedRequest = serviceUserForm.getSelectedRequests();

		List requests = getEeServiceAdminService().getEEServiceLiteRequests();
		if (selectedRequest != null && selectedRequest.length > 0) {
			for (int index = 0; index < selectedRequest.length; index++) {
				if (requests != null || requests.size() > 0) {

					Iterator reqitr = requests.iterator();
					while (reqitr.hasNext()) {

						EEServiceRequestLite req = (EEServiceRequestLite) reqitr
								.next();
						if (req.getEntityKey().getKeyValueAsString().equals(
								selectedRequest[index].toString())) {
							eeServiceUser.addEEServiceUserRequest(req);
						}

					}
				}
			}

		}
		getEeServiceAdminService().saveEEServiceUser(eeServiceUser);
		addInformationMessage(request, USER_SAVED);
		serviceUserForm.setSelectedRequestMap(eeServiceUser.getEeServiceUserRequests());
		return list(mapping, form, request, response);
	}

	public ActionForward updateUser(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		boolean isFormValid = validateForm(mapping, form, request, response);

		ServiceUserForm serviceUserForm = (ServiceUserForm) form;
		String userId = serviceUserForm.getUserId();
		EntityKey key = EntityKeyFactory.createEntityKey(userId,
				EEServiceUser.class);
		EEServiceUser eeServiceUser = getEeServiceAdminService()
				.getEEserviceUser(key);
//		eeServiceUser.removeAllEEServiceUserRequest();
		
		if (!isFormValid) {
			return mapping.findForward(FORWARD_DISPLAY_EDIT);
		}
		if (eeServiceUser == null) {
			eeServiceUser = new EEServiceUser();
		}
		eeServiceUser.setUserName(serviceUserForm.getUserName().trim());
		eeServiceUser.setContactName(serviceUserForm.getContactName().trim());
		eeServiceUser.setContactPhone(serviceUserForm.getContactPhone().trim());

		// encrypted in validation.
		//ESR 4.0_CodeCR12941
		if (!MASKED_PASSWORD.equals(serviceUserForm.getPassword().trim())) {
			eeServiceUser.setPassword(serviceUserForm.getPassword());
		}
		eeServiceUser.setActive(serviceUserForm.isActive());
	
		List requests = getEeServiceAdminService().getEEServiceLiteRequests();
		
		Set newRequests = new HashSet();
		String[] selectedRequest = serviceUserForm.getSelectedRequests();
    	if (selectedRequest != null && selectedRequest.length > 0) {
			for (int index = 0; index < selectedRequest.length; index++) {
				if (requests != null || requests.size() > 0) {

					Iterator reqitr = requests.iterator();
					while (reqitr.hasNext()) {
						EEServiceRequestLite req = (EEServiceRequestLite) reqitr.next();
						if (req.getEntityKey().getKeyValueAsString().equals(selectedRequest[index].toString())) {
							newRequests.add(req);
						}
					}

				}

			}

		}	 
	Set existingRequest = eeServiceUser.getEeServiceUserRequests();
    	
    	Set removeRequest = new HashSet();
    	if (existingRequest != null && existingRequest.size() > 0 ) {
    		Iterator existingRequestsitr = existingRequest.iterator();
    		while (existingRequestsitr.hasNext()) {
    			EEServiceUserRequest existingUserReq = (EEServiceUserRequest) existingRequestsitr.next();
    			EEServiceRequestLite req=existingUserReq.getEeServiceRequestLite();
    			if ( ! newRequests.contains(req)) {
    				// eeRequest.removeField(existingReqField);
    				removeRequest.add(existingUserReq);
    			}
    		}
    	}
    	eeServiceUser.removeRequests(removeRequest);
    	
    	if (newRequests != null && newRequests.size() > 0 ) {
    		Iterator newReqsitr = newRequests.iterator();
    		while (newReqsitr.hasNext()) {
    			EEServiceRequestLite newRequest = (EEServiceRequestLite) newReqsitr.next();
    			eeServiceUser.addEEServiceUserRequest(newRequest);
    		}
    	}
    	
	
		getEeServiceAdminService().saveEEServiceUser(eeServiceUser);
		addInformationMessage(request, USER_UPDATED);
		serviceUserForm.setSelectedRequestMap(eeServiceUser.getEeServiceUserRequests());
		return list(mapping, form, request, response);
	}

	private boolean validateForm(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		ServiceUserForm serviceUserForm = (ServiceUserForm) form;

		boolean valid = true;
		if (serviceUserForm.getUserName() == null
				|| serviceUserForm.getUserName().length() <= 0) {
			addActionMessage(request, REQUIRED, LABEL_KEY_USERNAME);
			valid = false;
		}
		if (serviceUserForm.getUserId() != null
				&& serviceUserForm.getUserName() != null) {
			EEServiceUser eeServiceUser = getEeServiceAdminService()
					.getEEServiceUser(serviceUserForm.getUserName());

			if (eeServiceUser != null) {
				if (!eeServiceUser.getIdentifier().toString().equals(
						serviceUserForm.getUserId())) {
					addActionMessage(request, FIELD_UNIQUE, LABEL_KEY_USERNAME);
					valid = false;
				}
				String newPassword = serviceUserForm.getPassword();
				if (serviceUserForm.getPassword() == null
						|| serviceUserForm.getPassword().length() <= 0) {
					addActionMessage(request, REQUIRED, LABEL_KEY_PASSWORD);
					valid = false;
				} else if (newPassword != null 
						&& !MASKED_PASSWORD.equals(newPassword) //ESR 4.0_CodeCR12941
						&& !eeServiceUser.getPassword().equals(newPassword)) {
					// password changed validate it.
					if (!EdbStrutsValidator.validatePassword(newPassword)) {
						addActionMessage(request, PASSWORD_NOT_VALID,
								LABEL_KEY_PASSWORD);
						valid = false;

					} else {
						// password is changed and it is valid. encrypt
						String encryptedNewPassword = getPasswordEncryptionService()
								.encryptPassword(newPassword);
						serviceUserForm.setPassword(encryptedNewPassword);
					}

				}
			} else {// this for new user
				String newPassword = serviceUserForm.getPassword();
				if (serviceUserForm.getPassword() == null
						|| serviceUserForm.getPassword().length() <= 0) {
					addActionMessage(request, REQUIRED, LABEL_KEY_PASSWORD);
					valid = false;
				} else if (newPassword != null
						&& !EdbStrutsValidator.validatePassword(newPassword)) {
					addActionMessage(request, PASSWORD_NOT_VALID,
							LABEL_KEY_PASSWORD);
					valid = false;
				} else {
					// encrypt
					String encryptedNewPassword = getPasswordEncryptionService()
							.encryptPassword(newPassword);
					serviceUserForm.setPassword(encryptedNewPassword);
				}
			}
		}
		if (serviceUserForm.getContactName() == null
				|| serviceUserForm.getContactName().length() <= 0) {
			addActionMessage(request, REQUIRED, LABEL_KEY_CONTACTNAME);
			valid = false;
		}

		if (serviceUserForm.getContactPhone() == null
				|| serviceUserForm.getContactPhone().length() <= 0) {
			addActionMessage(request, REQUIRED, LABEL_KEY_CONTACTPHONE);
			valid = false;
		}
		return valid;
	}

	public ActionForward displayNew(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		ServiceUserForm serviceUserForm = (ServiceUserForm) form;

		serviceUserForm.clearForm();
		List requests = getEeServiceAdminService().getEEServiceLiteRequests();
		serviceUserForm.setRequestList(requests);
		EEServiceUser serviceUser = new EEServiceUser();

		return mapping.findForward(FORWARD_DISPLAY_NEW);
	}
	 public ActionForward reset(ActionMapping mapping, ActionForm form,
	            HttpServletRequest request, HttpServletResponse response) throws Exception {
	    	
	    	ServiceUserForm serviceUserForm = (ServiceUserForm) form;
	    	
	    	String userId = serviceUserForm.getUserId();
	    	
	    	if ( userId == null ||userId.trim().length() <= 0 ) {
	    		// new request so go to newRequest page.
	    		return displayNew(mapping, form, request, response);
	    	}
	    	else
	    	{
	    		return display(mapping, form, request, response);
	    		
	    	}
	    	
	    }
	public void afterPropertiesSet() throws Exception {

	}

	/**
	 * Initialize and get the Struts lookup dispatch method map hashmap.
	 * 
	 * @return the method map
	 * @see org.apache.struts.actions.LookupDispatchAction#getKeyMethodMap()
	 */
	protected Map getKeyMethodMap() {
		Map map = new HashMap();
		map.put("button.eeserviceUser.update", "updateUser");
		map.put("button.eeserviceUser.add", "saveUser");
		map.put("button.eeserviceUser.cancel", "list");
		map.put("button.eeserviceUser.list", "list");
		map.put("button.eeserviceUser.reset", "reset");
		map.put("button.eeserviceUser.display", "display");
		map.put("button.eeserviceUser.displayNew", "displayNew");
		return map;
	}

}
