/**
 * Created July 2011
 * Project: UI
 * Author: VHADMAHAGADORNB
 */
package gov.va.med.esr.ui.comms.action;

// Java classes
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

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

import org.apache.commons.lang.StringUtils;
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.common.model.comms.DeliveryPreference;
import gov.va.med.esr.common.model.comms.HandBookMailQueue;
import gov.va.med.esr.common.model.lookup.DeliveryPreferenceType;
import gov.va.med.esr.common.model.lookup.HandBookMailStatusType;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.service.CommsEmailBulletinService;
import gov.va.med.esr.service.trigger.BulletinTrigger;

import gov.va.med.esr.ui.ApplicationConstants;
import gov.va.med.esr.ui.util.SessionManager;
import gov.va.med.fw.service.ServiceConfigurationException;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.ui.UIConstants;


public class DeliveryPreferencesAction extends CommsLogAction {

	   // Struts forwards
	   public static final String FORWARD_DELIVERY_PREFERENCES = "deliveryPreferences";
	   public static final String FORWARD_CANCEL = "cancel";
	   
	   private static final String MESSAGE_DELIVERY_PREFERENCES_UPDATED = "message.deliveryPreferences.updated";
	   private static final String MESSAGE_NEED_EMAIL_ADDRESS = "error.deliveryPreferences.needEmail";
	   private static final String MESSAGE_NEED_HANDBOOK_SENT = "error.deliveryPreferences.needHandbookSent";
	   
	   private static final String  HANDBOOK_SEND_TO_CMS_CODE = HandBookMailStatusType.SEND_TO_CMS.getCode();
	   
   public DeliveryPreferencesAction() {
      super();
   }

   public static final int MAX_ADD_COMMENTS_LENGTH=255;

   /**
    * Displays a search record
    *
    * @param mapping An action mapping
    * @param form A form bean
    * @param request A http request from an search.jsp page
    * @param response A http response to stream data to a next page
    * @return An action forward class encapsulating information about a next page
    * @throws java.lang.Exception Thrown if failed to process
    */
   public ActionForward display( ActionMapping mapping,
                                  ActionForm form,
                                  HttpServletRequest request,
                                  HttpServletResponse response )
       throws Exception {
       // Get delivery preferences specific form
	   DeliveryPreferencesForm dpForm = getDeliveryPreferencesForm(form);

       dpForm.setAddAPerson(SessionManager.isAddAPerson(request));
       
       // Get the Person object from the cache
       Person person = getSelectedPerson(request);
       
       DeliveryPreference dp = getHandBookService().findDeliveryPreferenceByPersonId(person.getPersonEntityKey().getKeyValueAsString());
       
       if (dp != null)
       {
           conversionService.convert(dp, dpForm);
       }

       // Return to the delivery preferences screen
       return mapping.findForward(FORWARD_DELIVERY_PREFERENCES);
   }

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

        return mapping.findForward(FORWARD_CANCEL);
    }

   private boolean isHandbookSent(Person person)
   {
	   
	   if (person == null)
		   return false;
	   List hbQueues = null;
	   try{
		   //As per ccr 12068 after discussion the changes were made.-02-20-2013
		  // hbQueues = this.getHandBookService().findHandbookEntriesByPersonId(person.getEntityKey().getKeyValueAsString());
		   hbQueues = this.getHandBookService().findDeliveryPreferenceEditableStatusByPersonId(person.getEntityKey().getKeyValueAsString());
		  
	   } catch (ServiceException ex)
	   {
		   //log it and return false
		   this.logger.error("Delivery Preference: Unable to retrieve handbook mailing queue" , ex);
		   return false;
	   }
	   
	   if (hbQueues == null || hbQueues.size() == 0){
		   return false;
	   }else{
		   return true;
	   }
		/* 
	   Iterator iter = hbQueues.iterator();
	   while (iter.hasNext()) {
		   HandBookMailQueue hbmq = (HandBookMailQueue) iter.next();
		   //CCR 11628: If a Handbook was triggered and is not in a status of "Send to CMS" 
		   //then we should allow a change to the delivery preference. 
		   if (hbmq.getHandBookMailStatus() != null && 
				   hbmq.getHandBookMailStatus().getStatusType() != null &&
				   ! HANDBOOK_SEND_TO_CMS_CODE.equals(hbmq.getHandBookMailStatus().getStatusType().getCode())) 
			   return true;
		 }
	   
	   return false;
	  */
   }
   /**
    * Updates the Delivery Preferences information.
    *
    * @param mapping Struts action mapping for this action
    * @param form Struts form bean for this action
    * @param request The Http Request
    * @param response The Http Response
    *
    * @return A struts action forward for where we will go next.
    * @throws Exception If there are any errors during processing.
    */
   public ActionForward update(ActionMapping mapping, ActionForm form,
       HttpServletRequest request, HttpServletResponse response) throws Exception
   {
	   DeliveryPreferencesForm dpForm = getDeliveryPreferencesForm(form);
       Person selectedPerson = (Person)getSelectedPerson(request);
       
	   if (DeliveryPreferenceType.CODE_ONLINE.getCode().equals(dpForm.getDeliveryPreference()))
	   {
		   //when online is selected, 
		   //1. handbook must have been sent before
		   //2. email address & email type must not be empty		   
		   if (!isHandbookSent(selectedPerson))
		   {
		        addActionMessage(request, new ActionMessage(MESSAGE_NEED_HANDBOOK_SENT));
		        return mapping.findForward(FORWARD_DELIVERY_PREFERENCES);
		   }
		   
		   if (StringUtils.isBlank(dpForm.getEmailAddress()) ||
				   StringUtils.isBlank(dpForm.getEmailType()))
		   {
		        addActionMessage(request, new ActionMessage(MESSAGE_NEED_EMAIL_ADDRESS));
		        return mapping.findForward(FORWARD_DELIVERY_PREFERENCES);
		   }
		}

//       MessageResources messageResources = dpForm.getResources(request);
//       ActionMessages errors = dpForm.getActionMessages(request);
       
       // Create some action forwards
       boolean isAddAPerson = false;
       isAddAPerson = SessionManager.isAddAPerson(request);
       dpForm.setAddAPerson(isAddAPerson);

       DeliveryPreference dp = getHandBookService().findDeliveryPreferenceByPersonId(selectedPerson.getPersonEntityKey().getKeyValueAsString());
       if (dp == null)
       {
    	   dp = new DeliveryPreference();
    	   selectedPerson.addDeliveryPreference(dp);
    	   //default type is MAIL
    	   dp.setDeliveryPreferenceType((DeliveryPreferenceType)getLookupCacheService()
                    .getByCodeFromCache(DeliveryPreferenceType.class, DeliveryPreferenceType.CODE_MAIL.getCode()));
       }
       
       DeliveryPreference oldDp = (DeliveryPreference)dp.clone();
       
       //convert
       conversionService.convert(dpForm, dp);

       //save the delivery preferences
       this.getHandBookService().saveDeliveryPreference(dp);
           
       //send email if necessary
       sendEmail(oldDp, dp);

       	   
       addInformationMessage(request,MESSAGE_DELIVERY_PREFERENCES_UPDATED);
       
       this.updateSelectedPerson(request, selectedPerson);
       
       return display(mapping, form,request,response);
       
   }

   private void sendEmail(DeliveryPreference oldDp, DeliveryPreference newDp) throws ServiceException
   {   
	   if (oldDp.getDeliveryPreferenceType().getCode().equals(DeliveryPreferenceType.CODE_MAIL.getCode()) &&
		   newDp.getDeliveryPreferenceType().getCode().equals(DeliveryPreferenceType.CODE_ONLINE.getCode()) &&
		   newDp.getEmail() != null && !StringUtils.isBlank(newDp.getEmail().getAddress()) )  
	   {  //change from mail to online
		   ((CommsEmailBulletinService)getBean( "commsEmailBulletinService" )).sendEmailBulletin(
			BulletinTrigger.DataType.DELIVERY_PREFERENCE_CHANGE_MAIL_TO_ONLINE,
			newDp.getEmail().getAddress());
	   } else if (oldDp.getDeliveryPreferenceType().getCode().equals(DeliveryPreferenceType.CODE_ONLINE.getCode()) &&
			      newDp.getDeliveryPreferenceType().getCode().equals(DeliveryPreferenceType.CODE_MAIL.getCode()) &&
			      oldDp.getEmail() != null && !StringUtils.isBlank(oldDp.getEmail().getAddress()))
	   {
		   //change from online to mail
		   ((CommsEmailBulletinService)getBean( "commsEmailBulletinService" )).sendEmailBulletin(
			BulletinTrigger.DataType.DELIVERY_PREFERENCE_CHANGE_ONLINE_TO_MAIL,
			oldDp.getEmail().getAddress());
	   }
	   
   }
    /**
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    public void afterPropertiesSet() {
        // Check for required components here
    }

    protected Map getKeyMethodMap()
    {

        Map map = new HashMap();

        map.put("title.deliveryPreferences", "display");
        map.put("button.update","update");
        map.put("button.cancel","cancel");
        return map;
    }

    
    /**
     * Checks to ensure the passed in ActionForm is not null and of the correct type.
     *
     * @param form The struts form to check
     *
     * @return The passed in form type-casted to a DeliveryPreferencesForm
     * @throws ServiceConfigurationException if the form is null or of an incorrect type.
     */
    protected DeliveryPreferencesForm getDeliveryPreferencesForm(ActionForm form) throws ServiceConfigurationException
    {
 	   DeliveryPreferencesForm dpForm =
            (form instanceof DeliveryPreferencesForm) ? (DeliveryPreferencesForm)form : null;
        if (dpForm == null)
        {
            throw new ServiceConfigurationException("DeliveryPreferencesForm not properly configured.");
        }
        return dpForm;
    }
}