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

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import gov.va.med.fw.conversion.ConversionServiceException;
import gov.va.med.fw.util.StringUtils;

import gov.va.med.esr.common.model.cases.Assignment;
import gov.va.med.esr.common.model.cases.Comment;
import gov.va.med.esr.common.model.cases.Status;
import gov.va.med.esr.common.model.cases.WorkflowCase;
import gov.va.med.esr.common.model.lookup.FunctionalGroup;
import gov.va.med.esr.common.model.lookup.WkfCaseStatusType;
import gov.va.med.esr.common.model.security.ESRUserPrincipalImpl;

import gov.va.med.esr.ui.common.service.LookupCacheService;
import gov.va.med.esr.ui.common.util.DateUtils;
import gov.va.med.esr.ui.conversion.UIConversionServiceImpl;
/**
 * Conversion service for workflowCase 
 * @author DNS   KATIKM
 *
 */
public class WorkItemConversionService extends UIConversionServiceImpl {
    
    public WorkItemConversionService() {
        super();
    }
    
    protected void convertBean(Object source, Object target) throws ConversionServiceException {
        if (source instanceof WorkflowCase && target instanceof WorkItemForm) {
            convert((WorkflowCase)source,(WorkItemForm)target);
        }
        else if (target instanceof WorkflowCase && source instanceof WorkItemForm) {
            convert((WorkItemForm)source,(WorkflowCase)target);
        }
        else 
        {
            throw new ConversionServiceException("Can not conver from " + 
                    source.getClass().getName() + " to " + target.getClass().getName());
        }
    }
    
    private void convert(WorkflowCase workflowCase, WorkItemForm workItemForm) 
        throws ConversionServiceException {
        // Item details
        workItemForm.setWorkflowCaseId(workflowCase.getWorkflowCaseID().toString());
        workItemForm.setPersonId(workflowCase.getPerson().getEntityKey().getKeyValueAsString());

        // Get current Assignment
        Assignment currentAssignment = workflowCase.getAssignment();
        if (currentAssignment != null) {
            workItemForm.setAssignedTo(currentAssignment.getAssignedTo());
        }

        // Status
        Status currentStatus = workflowCase.getStatus();
        if (currentStatus != null) {
            workItemForm.setStatusValue(currentStatus.getStatusValue() == null ? null
                            : currentStatus.getStatusValue().getCode());
        }
        
        //Funtional Group
        FunctionalGroup functionalGroup = workflowCase.getGroupType();        
        workItemForm.setCaseGroup(functionalGroup == null ? "" :functionalGroup.getCode());
        
        //Logged in User details group and name
        ESRUserPrincipalImpl loogedInUser = (ESRUserPrincipalImpl)getLoggedInUser();
        workItemForm.setLoggedInUserName(loogedInUser.getName());
        FunctionalGroup userFunctionalGroup = loogedInUser.getFunctionalGroup();
        workItemForm.setLoggedInUserGroup(userFunctionalGroup == null ? "" :userFunctionalGroup.getCode());
        
        // Comments
        List comments = new ArrayList(workflowCase.getComments());
        Date currentDate = DateUtils.getCurrentDate();
        String currentUser = loogedInUser.getName();
        if (comments.size() > 0) {
            Collections.sort(comments);
            Comment comment = (Comment) comments.get(comments.size()-1);
            if (currentDate.before(comment.getCreatedOn()) && 
                currentUser.equalsIgnoreCase(comment.getModifiedBy().getName()))
            {
                workItemForm.setComment(comment.getCommentText());
                workItemForm.setCommentId(comment.getEntityKey().getKeyValueAsString());
            }
        }
    }
    
    private void convert(WorkItemForm workItemForm, WorkflowCase workflowCase) 
        throws ConversionServiceException {
        
        LookupCacheService lookupCacheService = getLookupCacheService();
        try{
            // Conversion
            // update if the new comment is not null
            if (StringUtils.isNotEmpty(workItemForm.getComment())) {
                //Verify whether we are editing an existing comment or not
                Comment comment = null;
                if (StringUtils.isNotEmpty(workItemForm.getCommentId())) {
                    //get the comment from the existing list
                    Set comments = workflowCase.getComments();
                    for (Iterator i=comments.iterator(); i.hasNext();) {
                        comment = (Comment)i.next();
                        if (comment != null && workItemForm.getCommentId().equals(comment.getEntityKey().getKeyValueAsString())){
                            break;
                        }
                    }
                    
                    //update comment text
                    if (comment != null) {
                    	comment.setCommentText(workItemForm.getComment());
                    }
                }
                else {
                    comment = new Comment();
                    if (comment != null) {
	                    comment.setCommentText(workItemForm.getComment());
	                    workflowCase.addComments(comment); 
                    }
                }
            }
    
            // Update or Create Status
            if (StringUtils.isNotEmpty(workItemForm.getAssignedTo())) {
                Assignment assignment = workflowCase.getAssignment();
                    
                // Verify whether status has been changed
                if (assignment == null) {
                    assignment = new Assignment();
                    assignment.setAssignedTo(workItemForm.getAssignedTo());
                    assignment.setAssignmentDate(DateUtils.getCurrentDate());
                    assignment.setAssignedBy(getLoggedInUser().getName());
                    workflowCase.setAssignment(assignment);
                } else if (!workItemForm.getAssignedTo().equals(
                        assignment.getAssignedTo())) {
                    assignment.setAssignedTo(workItemForm.getAssignedTo());
                    assignment.setAssignmentDate(DateUtils.getCurrentDate());
                    assignment.setAssignedBy(getLoggedInUser().getName());                    
                }
            }    
            
            
            // Update or Create Status
            if (StringUtils.isNotEmpty(workItemForm.getStatusValue())) {
                WkfCaseStatusType statusType = 
                    (WkfCaseStatusType) lookupCacheService.getByCodeFromCache(
                            WkfCaseStatusType.class, workItemForm.getStatusValue());
                Status status = workflowCase.getStatus();
    
                // Verify whether status has been changed
                if (status == null) {
                    status = new Status();
                    status.setStatusValue(statusType);
                    workflowCase.setStatus(status);
                } else if (!statusType.equals(status.getStatusValue())) {
                    status.setStatusValue(statusType);
                    workflowCase.setStatus(status);
                }
            }    
        }catch(Exception e) {
            throw new ConversionServiceException("Conversion Failed ", e);
        }
    }
}
