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

import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.util.StringUtils;

import gov.va.med.esr.common.model.lookup.Capability;
import gov.va.med.esr.common.model.security.CapabilitySet;
import gov.va.med.esr.common.model.security.UserCapability;

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

public class UserProfileForm extends AbstractUserProfileForm {

    private static final long serialVersionUID = 158788621786362850L;
    
    //User information
    private String userId;
    private String name;    //login name
    private String functionalGroup;
    private String fullName;
    
    public UserProfileForm () {
        super();
        initialize();
    }

    public void reset(ActionMapping mapping, HttpServletRequest request)
    {
        super.reset(mapping, request);
        initialize();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }
    
    public String getFunctionalGroup() {
        return functionalGroup;
    }

    public void setFunctionalGroup(String functionalGroup) {
        this.functionalGroup = functionalGroup;
    }

    public String getFullName() {
        return fullName;
    }
    public void  setFullName(String fullName) {
        this.fullName = fullName;
    }    
    /**
     * Set assigned Capablities
     * @param assignedCapabilities
     */
    public void setAssignedCapabilities(List assignedCapabilities) {
        //Loop through the list and set the properties
        if (assignedCapabilities != null) {
            Collections.sort(assignedCapabilities);
            for (int i=0; i<assignedCapabilities.size(); i++) {
                UserCapability userCapability = (UserCapability) assignedCapabilities.get(i);
                Capability capability = userCapability.getCapability();
                setAssignedCapabilityCode(i,capability.getCode());
                setAssignedCapabilityName(i,capability.getName());
                EntityKey key = userCapability.getEntityKey();
                String keyStr = (key == null ? null : key.getKeyValueAsString());                
                setAssignedUserCapabilityId(i,keyStr);
                setAssignedCapabilityInd(i,Boolean.TRUE);  
                setAssignedCapabilityActiveDate(i,
                        DateUtils.format(userCapability.getActiveDate(),null));
                setAssignedCapabilityInactiveDate(i,
                        DateUtils.format(userCapability.getInactiveDate(),null));
                if (key != null){
                    setAssignedCapabilityOldActiveDate(i,
                        DateUtils.format(userCapability.getOldActiveDate(),null));
                    setAssignedCapabilityOldInactiveDate(i,
                        DateUtils.format(userCapability.getOldInactiveDate(),null));
                }
                else {
                    setAssignedCapabilityOldActiveDate(i,null);
                    setAssignedCapabilityOldInactiveDate(i,null);
                }
            }
        }        
    }
        
    /**
     * Set Assigned Capability Sets
     * @param assignedCapabilitySets
     */
    public void setAssignedCapabilitySets(List assignedCapabilitySets) {
        //Loop through the list and set the properties
        if (assignedCapabilitySets != null) {
            Collections.sort(assignedCapabilitySets);
            for (int i=0; i<assignedCapabilitySets.size(); i++) {
                CapabilitySet capabilitySet = (CapabilitySet) assignedCapabilitySets.get(i);
                setAssignedCapabilitySetId(i,capabilitySet.getEntityKey().getKeyValueAsString());
                setAssignedCapabilitySetName(i,capabilitySet.getName()); 
                setAssignedCapabilitySetInd(i,Boolean.TRUE);  
                setAssignedCapabilitySetActiveDate(i,
                        DateUtils.format(capabilitySet.getActiveDate(),null));
                setAssignedCapabilitySetInactiveDate(i,
                        DateUtils.format(capabilitySet.getInactiveDate(),null));
            }
        }        
    }

    /**
     * Validates form data after submission
     * To highligh the system parameter name, parameter name is passed as field name
     */
    public ActionMessages validateForm(ActionMapping mapping, HttpServletRequest request)
    {
        // Get the list of existing messages and resources
        ActionMessages messages = getActionMessages(request);
        
        int activeDates = getCapabilityActiveDateList().size();
        int assignedActiveDates = getAssignedCapabilityActiveDateList().size();
        
        boolean newAssignment = true;
        for (int i=0; i<activeDates; i++) {            
            //Validate the dates if the capability was selected
            if (Boolean.TRUE.equals(getCapabilityInd(i))) {
                //check active date for assigned available capabilities
                checkActiveInactiveDates(messages,getCapabilityActiveDate(i),
                    getCapabilityInactiveDate(i),i,"capabilityName", null, null);
            }             
        }
        for (int i=0; i<assignedActiveDates; i++) {            
            //Validate the dates if the capability was selected
            if (Boolean.TRUE.equals(getAssignedCapabilityInd(i))) {
                //check active date for assigned available capabilities
                newAssignment = StringUtils.isEmpty(getAssignedUserCapabilityId(i)) ? true : false;
                checkActiveInactiveDates(messages,
                    getAssignedCapabilityActiveDate(i),getAssignedCapabilityInactiveDate(i),
                    i,"assignedCapabilityName",
                    getAssignedCapabilityOldActiveDate(i),getAssignedCapabilityOldInactiveDate(i));
            }             
        }        
            
        //Return the updated Action Messages
        return messages;
    }
    
    private void checkActiveInactiveDates(ActionMessages messages, 
            String activeDateStr, String inactiveDateStr, 
            int index, String indexFieldName, String oldActiveDateStr, String oldInactiveDateStr){
        
        if (StringUtils.isEmpty(activeDateStr) && StringUtils.isEmpty(inactiveDateStr)) {
            return;
        }

        Date current = DateUtils.getCurrentDate();

        Date activeDate = null;
        Date inactiveDate = null;
        Date oldActiveDate = getDate(oldActiveDateStr,null);
        Date oldInactiveDate = getDate(oldInactiveDateStr,null);          
        //check active date value
        if (StringUtils.isNotEmpty(activeDateStr)) {
            try {
                activeDate = DateUtils.getDate(activeDateStr);
                //check active date is not past
                if ((oldActiveDate == null || !oldActiveDate.equals(activeDate)) && activeDate.before(current)) {                
                    messages.add(indexFieldName+"["+index+"]",
                        new ActionMessage(ERRORS_ACTIVE_DATE_PAST));   
                }
            }catch (IllegalArgumentException e){
                //ignore exception
            }
            if (activeDate == null) {
                messages.add(indexFieldName+"["+index+"]",
                        new ActionMessage(MessageKeys.ERRORS_DATE, "Active Date"));                    
            }            
        }
        if (StringUtils.isNotEmpty(inactiveDateStr)) {
            try {
                inactiveDate = DateUtils.getDate(inactiveDateStr);
                //check inactive date is not in the past
                if ((oldInactiveDate == null || !oldInactiveDate.equals(inactiveDate)) && inactiveDate.before(current)) {
                    messages.add(indexFieldName+"["+index+"]",
                        new ActionMessage(ERRORS_INACTIVE_DATE_PAST));  
                }
            }catch (IllegalArgumentException e){
                //ignore exception
            }
            if (inactiveDate == null) {
            messages.add(indexFieldName+"["+index+"]",
                new ActionMessage(MessageKeys.ERRORS_DATE,"Inactive Date"));
            }
        }
        
        if (activeDate != null && inactiveDate != null) {
            //check active date is not after inactive date
            if (activeDate.after(inactiveDate)) {
                messages.add(indexFieldName+"["+index+"]",
                    new ActionMessage(ERRORS_ACTIVE_DATE));
            }
        }
    }
    
    /**
     * Return default date when the date string is empty or not valid
     * @param dateStr
     * @param defDate
     * @return
     */
    private Date getDate(String dateStr, Date defDate){
        try{
           return DateUtils.getDate(dateStr);
        }
        catch (Exception e){}
        
        return defDate;
    }
    /**
     * Initialize 
     */
    private void initialize() {
         userId = null;
         name = null;
         fullName = null;
         functionalGroup = null;
    }
}
