/********************************************************************
 * Copyright © 2005 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.esr.ui.workflow.action;

// Java classes
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.fw.security.UserPrincipal;
import gov.va.med.fw.util.StringUtils;

import gov.va.med.esr.common.model.lookup.Capability;
import gov.va.med.esr.common.model.lookup.FunctionalGroup;
import gov.va.med.esr.common.model.person.id.VPIDEntityKeyImpl;
import gov.va.med.esr.common.model.security.ESRUserPrincipalImpl;
import gov.va.med.esr.service.WorkItemsSummary;

import gov.va.med.esr.ui.ApplicationConstants;
import gov.va.med.esr.ui.common.util.DateUtils;
import gov.va.med.esr.ui.common.util.EdbStrutsValidator;

public class WorklistAction extends WorkflowAction {
               
   public static final String FWD_TO = "forwardTo";
   public static final String MY_CASES_TAB = "returnToMyCases";
   
   public WorklistAction() {
      super();
   }

   /**
    * Based on the User permisions and Functional Group, it forwards 
    * respective views EE, EE(Supervisor), DQ, DQ(Superviosr)
    */
    public ActionForward display(ActionMapping mapping, ActionForm form, 
            HttpServletRequest request, HttpServletResponse response) throws Exception {
    	//clear search results
    	clearCachedResults(request);
    	((WorklistForm)form).resetFilter();
    	String forwardTo = request.getParameter(FWD_TO);
    	if (StringUtils.isNotEmpty(forwardTo)){
    		return mapping.findForward(forwardTo);
    	}
    	else { 
    		return mapping.findForward(MY_CASES_TAB);
    	}
   }
   /**
    * Disaply Summary of Cases
    * @param mapping
    * @param form
    * @param request
    * @param response
    * @return
    * @throws Exception
    */
   public ActionForward displaySummary( ActionMapping mapping, ActionForm form,
                 HttpServletRequest request, HttpServletResponse response ) throws Exception {
       UserPrincipal userPrincipal = getLoggedInUser();
       WorkItemsSummary workItemsSummary = getWorkflowService().getWorkItemsSummaryForUser(userPrincipal);
       request.setAttribute("workItemsSummary",workItemsSummary);
       setCurrentTab(request,FWD_OVERVIEW);
       return mapping.findForward(FWD_OVERVIEW);
   }
       
   public ActionForward displayMyCases( ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response ) throws Exception {
        getMyCases(request,(WorklistForm) form);
        setCurrentTab(request,FWD_MY_CASES);
        updateAssignedToUserList(request);
        return mapping.findForward(FWD_MY_CASES);
   }

   public ActionForward displayAssigned(ActionMapping mapping, ActionForm form,
           HttpServletRequest request, HttpServletResponse response ) throws Exception {
       getAssignedCases(request,(WorklistForm) form);      
       setCurrentTab(request,FWD_ASSIGNED_CASES);
       updateAssignedToUserList(request);
       return mapping.findForward(FWD_ASSIGNED_CASES);
   }
   
    public ActionForward displayUnassigned(ActionMapping mapping, ActionForm form,
          HttpServletRequest request, HttpServletResponse response ) throws Exception {
        getUnassignedCases(request,(WorklistForm) form); 
        setCurrentTab(request,FWD_UNASSIGNED_CASES);
        updateAssignedToUserList(request);
        return mapping.findForward(FWD_UNASSIGNED_CASES);
    }
      
    public ActionForward displayOpenCases(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response ) throws Exception {
          getOpenCases(request,(WorklistForm) form);    
          setCurrentTab(request,FWD_OPEN_CASES);
          updateAssignedToUserList(request);
          return mapping.findForward(FWD_OPEN_CASES);
      }
    
    /**
     * Assign the selected Case
     */
    public ActionForward assignCases(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response ) throws Exception {
                
        //Get the selected workflow Cases and reassign them to selected users
        List selectedCases = getSelectedCases(mapping,form,request,response);

        //Check the assign to user name
        if (StringUtils.isNotEmpty(((WorklistForm)form).getAssignTo()) && selectedCases.size() > 0){
            String assignToName = ((WorklistForm)form).getAssignTo();
            UserPrincipal assignTo = null;
            FunctionalGroup assignToGroup = null;
	        
            //pre-defined unassigned pool for dq cases
            if (Capability.DQ_UNASSIGNED_POOL.getName().equals(assignToName)){
                assignToGroup = (FunctionalGroup)getLookupCacheService().getByCodeFromCache(
                        FunctionalGroup.class.getName(),FunctionalGroup.DQ.getName());
            }
            else {
               //Optimize the call when user lookup is created with minimum info 
               assignTo = getUserAdminService().getUserByName(assignToName);
               assignToGroup = ((ESRUserPrincipalImpl)assignTo).getFunctionalGroup();
            } 
	        getWorkflowService().assign(selectedCases, getLoggedInUser(), assignTo, assignToGroup);
	        
	    	//clear search results to refresh
	    	clearCachedResults(request);
	    }
        //forward to appropriate tab
    	return mapping.findForward(((WorklistForm)form).getReturnLink());        
    }
    
    /**
     * Update slected Cases (Currently options only support close)
     */
    public ActionForward updateCases(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response ) throws Exception {
        
        //Get the selected workflow Cases and close them (only action supported now)        
        List selectedCases = getSelectedCases(mapping,form,request,response);
        
       if (StringUtils.isNotEmpty(((WorklistForm)form).getUpdateAction()) && selectedCases.size() > 0){
          //only close  action is supported for now
          getWorkflowService().close(selectedCases);
          
      	  //clear search results to refresh
      	  clearCachedResults(request); 
          
          updateHeader(request);
       }
       // forward to appropriate tab  
       return mapping.findForward(((WorklistForm)form).getReturnLink());       
    }
    
    public ActionForward applyFilter(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response ) throws Exception {
                  
      //clear search results to refresh
      clearCachedResults(request);      	                 
      //Validate form 
      if (!validateFilter(request,(WorklistForm)form)){
    	  //move the error messages to session and then to request
      }
      // forward to appropriate tab  
      return mapping.findForward(((WorklistForm)form).getReturnLink());       
    }    
    
    public ActionForward resetFilter(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response ) throws Exception {
                  
      //clear search results to refresh
      clearCachedResults(request);      	                 

      //Reset the filter values
      WorklistForm worklistForm = (WorklistForm)form;
      worklistForm.resetFilter();
      // forward to appropriate tab  
      return mapping.findForward(((WorklistForm)form).getReturnLink());       
    }
    
    private boolean validateFilter(HttpServletRequest request, WorklistForm form)
    {
    	boolean valid = true;
    	//validate ssn
    	if (StringUtils.isNotEmpty(form.getSsn())){
    		String ssn = form.getSsn();
        	if (ssn.matches(EdbStrutsValidator.PATTERN_SSN) || 
        			ssn.matches(EdbStrutsValidator.PATTERN_FORMATTED_SSN)) {        		
        	}else {
        		addActionMessage(request,ApplicationConstants.MessageKeys.ERRORS_SSN,ssn);
        		valid = false;
        		form.setSsn(null);
        	}
    	}
        //Validate VPID
        if (StringUtils.isNotEmpty(form.getVpid())){
            try {
                String longVpid = VPIDEntityKeyImpl.getLongVPID(form.getVpid());
                form.setVpid(longVpid);
            }catch (Exception e){
                addActionMessage(request,ApplicationConstants.MessageKeys.ERRORS_VPID,form.getVpid());
                valid = false;
                form.setVpid(null);
            }
        }
    	//item number
    	if (StringUtils.isNotEmpty(form.getItemNumber())){
    		String itemNumber = form.getItemNumber();
        	if (!itemNumber.matches("[^-][0-9]+")) {
        		addActionMessage(request,ApplicationConstants.MessageKeys.ERRORS_NUMERIC,itemNumber);
        		valid = false;
        		form.setItemNumber(null);
        	}
    	}
    	
    	//create dates
    	if (StringUtils.isNotEmpty(form.getCreateDateFrom())){
    		String createDateFrom = form.getCreateDateFrom();    	
	       	Date date = null;
	    	try{
	    		date = DateUtils.getDate(createDateFrom);
	    	}catch (Exception e) {}
	    	if (date == null) {
	    		addActionMessage(request,ApplicationConstants.MessageKeys.ERRORS_DATE,createDateFrom);
	    		valid = false;
	    		form.setCreateDateFrom(null);
	    	}
    	}
    	if (StringUtils.isNotEmpty(form.getCreateDateTo())){
    		String createDateTo = form.getCreateDateTo();    	
	       	Date date = null;
	    	try{
	    		date = DateUtils.getDate(createDateTo);
	    	}catch (Exception e) {}
	    	if (date == null) {
	    		addActionMessage(request,ApplicationConstants.MessageKeys.ERRORS_DATE,createDateTo);
	    		valid = false;
	    		form.setCreateDateTo(null);
	    	}
    	}
    	
    	//Assigned dates
    	if (StringUtils.isNotEmpty(form.getAssignedDateFrom())){
    		String assignedDateFrom = form.getAssignedDateFrom();    	
	       	Date date = null;
	    	try{
	    		date = DateUtils.getDate(assignedDateFrom);
	    	}catch (Exception e) {}
	    	if (date == null) {
	    		addActionMessage(request,ApplicationConstants.MessageKeys.ERRORS_DATE,assignedDateFrom);
	    		valid = false;
	    		form.setAssignedDateFrom(null);
	    	}
    	}
    	if (StringUtils.isNotEmpty(form.getAssignedDateTo())){
    		String assignedDateTo = form.getAssignedDateTo();    	
	       	Date date = null;
	    	try{
	    		date = DateUtils.getDate(assignedDateTo);
	    	}catch (Exception e) {}
	    	if (date == null) {
	    		addActionMessage(request,ApplicationConstants.MessageKeys.ERRORS_DATE,assignedDateTo);
	    		valid = false;
	    		form.setAssignedDateTo(null);
	    	}
    	}    	
    	return valid;
    }
    
    protected Map getKeyMethodMap()
    {
		Map keyMethodMap = new HashMap();
		keyMethodMap.put("button.display","display");
		keyMethodMap.put("link.name.myCases","displayMyCases");
		keyMethodMap.put("link.name.assignedCases","displayAssigned");
		keyMethodMap.put("link.name.unassignedCases", "displayUnassigned");
        keyMethodMap.put("link.name.openCases", "displayOpenCases");
        keyMethodMap.put("link.name.summary", "displaySummary");
        keyMethodMap.put("button.assign","assignCases");
        keyMethodMap.put("button.update","updateCases");
        keyMethodMap.put("button.applyFilter","applyFilter");
        keyMethodMap.put("button.resetFilter","resetFilter");
        return keyMethodMap;
    }
}