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

import gov.va.med.esr.service.UnknownLookupCodeException;
import gov.va.med.esr.service.UnknownLookupTypeException;
import gov.va.med.esr.ui.common.beans.VOASearchType;
import gov.va.med.fw.model.lookup.Lookup;
import gov.va.med.fw.ui.struts.ValueListActionUtils;
import gov.va.med.fw.ui.valuelist.MaxRecordsExceededValueListException;
import gov.va.med.fw.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

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

import net.mlw.vlh.ValueList;
import net.mlw.vlh.ValueListInfo;

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

import gov.va.med.esr.ui.ApplicationConstants;

public class VOASearchAction extends VOAResubmissionAction {
            
    public static final String MSG_SEARCH_CRITERIA_EMPTY = "error.searchCriteriaEmpty";
    public static final String MSG_SEARCH_TYPE_AND_VALUE_REQUIRED = "error.searchTypeAndValueRequired";
      
    public static final String VOA_SEARCH_TABLE_ID = "voaResubmissionSearchTableId";
    public static final String VOA_SEARCH_ADAPTER = "voaResubmissionSearchAdapter";
    public static final String VALUELIST = "vlhlist";
            
    public static String FWD_PENDING_SUBMISSIONS = "pendingSubmissions";
    public static String FWD_SEARCH_RESULTS = "searchResults";    
    
    public static final String FWD_DISPLAY = "displayPendingSubmissions";
    public static final String FWD_CLEAR = "clear";
    public static final String FWD_RESULTS= "results";
    public static final String FWD_OVERVIEW = "overview";

    
    public VOASearchAction () {
        super();
    }
    
    public ActionForward displayPendingSubmissions(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception
    {
       //Verify whether we have search results in session if yes display results
       clearCachedResults(request); 
       return mapping.findForward(FWD_DISPLAY);  
    }
   
    /**
     * Perform simple search
     * @param mapping
     * @param form
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    public ActionForward simpleSearch(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception
    {        
       //build search criteria from the user entered data
       VOASearchForm searchForm = (VOASearchForm)form;
       
       //clear cached results
       clearCachedResults(request);
         	
       //Update search fields based on the search type selection
       if (updateSearchFieldsForSimpleSearch(request,searchForm)) {
    	   return advancedSearch(mapping, searchForm, request,response);
       }else {
    	   return mapping.getInputForward();
       }
    }
    
    /**
     * Perform advanced search and retrieve results
     * @param mapping
     * @param form
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    public ActionForward advancedSearch(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        VOASearchForm searchForm = (VOASearchForm)form;
        clearCachedResults(request);
        if (!searchForm.isSelectAll() && searchForm.isEmpty()) {
            addActionMessage(request,MSG_SEARCH_CRITERIA_EMPTY);
            return mapping.getInputForward();
        }
        
        ActionForward forward = null;
        
        //TODO validate date ranges if provided 
       //build search criteria from the user entered data              
        try
        {
            // Get the value list information
            ValueList valueList = ValueListActionUtils.getValueList(searchForm,
                request, VOA_SEARCH_TABLE_ID, VOA_SEARCH_ADAPTER);

            // Check if any results were found
            ValueListInfo info = valueList.getValueListInfo();
            if (info.getTotalNumberOfEntries() == 0)
            {
                // No results were found so generate an error and forward to the
                // failure page
                addActionMessage(request, new ActionMessage(
                    ApplicationConstants.MessageKeys.ERRORS_SEARCH_NORESULT));
                forward = mapping.findForward(FWD_DISPLAY);
            }
            else
            {
                // Backup the ValueListInfo into session and store the resultant ValueList on the request
                ValueListActionUtils
                    .setValueList(request, valueList, VALUELIST);

                // Forward to the search results page.
                forward = mapping.findForward(FWD_DISPLAY);
            }
        }
        catch (MaxRecordsExceededValueListException ex)
        {
            // The search exceeded the maximum number of records allowed so generate the appropriate
            // error message.
            if ((ex.getTotalRecords() > 0) && (ex.getRecordLimit() > 0))
            {
                // We know both the total number of records that would have been returned as well
                // as the configured limit.
                addActionMessage(request, new ActionMessage(
                    ApplicationConstants.MessageKeys.ERRORS_MAX_RECORDS_EXCEEDED,
                    new Integer(ex.getTotalRecords()), new Integer(ex
                    .getRecordLimit())));
            }
            else
            {
                // We only know the configured limit
                if (ex.getRecordLimit() > 0)
                {
                    addActionMessage(request, new ActionMessage("error.personSearchExccededLimit",
                        new Integer(ex.getRecordLimit())));
                }
                else
                {
                    // Provide a generic message
                    addActionMessage(request, new ActionMessage(
                        ApplicationConstants.MessageKeys.ERRORS_MAX_RECORDS_EXCEEDED_NO_PARAMS));
                }
            }
            forward = mapping.findForward(FWD_DISPLAY);
        }
        // Return the forward
        return forward;               
    }
    
    
    
    /**
     * Clear form values
     * @param mapping
     * @param form
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    public ActionForward clear(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        form.reset(mapping,request);
       return mapping.findForward(FWD_CLEAR);        
    }
    /**
     * Fetech and set lookup code value based on the selection type
     * @param searchForm
     */
    protected boolean updateSearchFieldsForSimpleSearch(HttpServletRequest request, VOASearchForm searchForm) throws Exception{    
    	
        String searchField = searchForm.getSearchField();
        String searchValue = searchForm.getSearchValue();

        //search type is required
    	if (StringUtils.isEmpty(searchField)){
            addActionMessage(request,MSG_SEARCH_CRITERIA_EMPTY);
            return false;
    	}
    	//if all items is not selected, value is required
    	else if (!VOASearchType.CODE_ALL_PENDING_SUBMISSIONS.getName().equals(searchField) &&
    		StringUtils.isEmpty(searchValue)){
            addActionMessage(request,MSG_SEARCH_TYPE_AND_VALUE_REQUIRED);
            return false;
    	}
    	//validate dates
    		   
    	if (VOASearchType.CODE_ALL_PENDING_SUBMISSIONS.getName().equals(searchField)){
        	searchForm.setSelectAll(true);
        }
        else if (VOASearchType.CODE_SUBMISSION_ID.getName().equals(searchField)){
			searchForm.setApplicationId(searchValue);
		}
        else if (VOASearchType.CODE_FORM_TYPE.getName().equals(searchField)){
			searchForm.setFormTypeValue(searchValue);
		}    		
        else if (VOASearchType.CODE_REQUEST_RECEIVED_DATE.getName().equals(searchField)){
        	searchForm.setReqRecdDateTo(searchValue);
        	searchForm.setReqRecdDateFrom(searchValue);
        }
		        
        else if (VOASearchType.CODE_FORM_PENDING_REASON.getName().equals(searchField)){
        	searchForm.setFormPendingReason(searchValue);
        }
    	return true;
    }

    protected String getCode(Class clazz, String description) throws Exception{
    	Lookup lookup = null;
    	try {
    			lookup = getLookupService().getByDescription(clazz,description);
    			if (lookup != null) 
    				return lookup.getCode();
		} catch (Exception e) {} 	
        
    	//get the proper code for functional group and set
		try {
				lookup = getLookupCacheService().getByCodeFromCache(clazz,description);
    			if (lookup != null) 
    				return lookup.getCode();		
		} catch (Exception e){}
		return null;
    }
    
    protected Map getKeyMethodMap()
    {
        Map keyMethodMap = new HashMap();
        keyMethodMap.put("link.name.pendingSubmissions", "displayPendingSubmissions");
        keyMethodMap.put("link.name.searchVOAResubmission", "displayPendingResubmissions");
        keyMethodMap.put("button.display", "displayPendingSubmissions");
        keyMethodMap.put("button.search", "search");
        keyMethodMap.put("button.clear", "clear");
        return keyMethodMap;
    }
}
