package gov.va.vinci.dart.json.builder;

import java.text.SimpleDateFormat;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import gov.va.vinci.dart.biz.Group;
import gov.va.vinci.dart.biz.Person;
import gov.va.vinci.dart.biz.RequestStatus;
import gov.va.vinci.dart.biz.RequestSummary;
import gov.va.vinci.dart.biz.Role;
import gov.va.vinci.dart.biz.WorkflowSummary;
import gov.va.vinci.dart.json.RequestView;
import gov.va.vinci.dart.json.WorkflowNameView;
import gov.va.vinci.dart.json.WorkflowStatusView;
import gov.va.vinci.dart.json.atom.AtomLinkFactory;
import gov.va.vinci.dart.json.atom.LinkListView;
import gov.va.vinci.dart.json.atom.LinkView;
import gov.va.vinci.dart.json.atom.Relation;

@Component
public class RequestViewBuilder {
	private static Log log = LogFactory.getLog(RequestViewBuilder.class);
	
	public static final SimpleDateFormat SDF = new SimpleDateFormat("MM/dd/yyyy");

	@Autowired
	private AtomLinkFactory linkFactory;


	/**
	 * Requestor tab:  list of the requests for a specific participant
	 * 
	 * @param summary
	 * @param bIncludeLinks
	 * @return
	 */
	public RequestView buildRequestorTab(final RequestSummary summary, final boolean bIncludeLinks) {
		RequestView result = new RequestView();
		
		result.setRequestId(summary.getRequestId());
		result.setActivityId(summary.getActivityId());
		result.setReviewId(summary.getReviewId());
		result.setTrackingNumber(summary.getTrackingNumber());
		result.setActivityName(summary.getActivityName());

		result.setSubmitted(summary.getSubmittedOn()==null?null:SDF.format(summary.getSubmittedOn()));
		result.setCreated(summary.getSubmittedOn()==null?null:SDF.format(summary.getSubmittedOn()));  // TODO- not the correct value! (not used in the dashboard UI)
		result.setUpdated(summary.getUpdatedOn()==null?null:SDF.format(summary.getUpdatedOn()));	//TODO: not used in the dashboard UI

		result.setRequestType(summary.getRequestType());
		result.setResearchRequest(summary.isResearchRequest());
		result.setOperationsRequest(summary.isOperationsRequest());
		result.setPreparatoryRequest(summary.isPreparatoryRequest());
		result.setEditable(summary.isEditable());
		result.setAmendable(summary.isAmendable());
		result.setDaysElapsed(String.valueOf(summary.getDaysElapsed()));	//TODO: not used in the dashboard UI
		result.setContact(summary.getPrincipalInvestigatorName());


		//
		//get and display the details of each workflow attached to this request
		if( summary.getWorkflowSummaryList() != null && summary.getWorkflowSummaryList().size() > 0 ) {
			for( WorkflowSummary workflowSummary : summary.getWorkflowSummaryList() ) {
				if( workflowSummary != null ) {
					populateRequestStatusClass( result, workflowSummary.getRequestState(), workflowSummary.getWorkflowId(), workflowSummary.getWorkflowGroupId() );	//use the status calculated by the query (includes the "elaborate status" calculation)
				}//end if
			}//end for

			populateWorkflowNamePadLeft(result);	//update the padding once per request (for all workflows)
		}//end if

		
		
		if( bIncludeLinks == true ) {	//add the links? (not used in the dashboard UI)
			buildLinks(result, summary.getRequestId());
		}//end if
		
		return result;
	}


	/**
	 * Requestor tab:  list of the requests for a specific participant
	 * 
	 * @param summary
	 * @param person
	 * @param bIncludeLinks	-- build the links?
	 * @return
	 */
	public RequestView buildRequestorTab(final RequestSummary summary, final Person person, final boolean bIncludeLinks) {
		RequestView result = buildRequestorTab(summary, bIncludeLinks);
		
		Role.initialize();
		if( person != null && person.hasRole(Role.SUPER_USER) ) {	//super-user cannot edit the request
			result.setEditable(false);
			result.setAmendable(false);
		}

		return result;
	}


	private void buildLinks(final RequestView result, final int requestId) {
		LinkListView linkListView = new LinkListView();
		result.setLinks(linkListView);
		
		// TODO- use a builder, please
		LinkView link = linkFactory.buildLink("/requests/" + requestId, Relation.SELF);
		linkListView.getLink().add(link);
		link = linkFactory.buildLink("/requests/" + requestId + "/activity", Relation.RELATED);
		linkListView.getLink().add(link);
		link = linkFactory.buildLink("/requests/" + requestId + "/primaryInfo", Relation.RELATED);
		linkListView.getLink().add(link);
		link = linkFactory.buildLink("/requests/" + requestId + "/participants", Relation.RELATED);
		linkListView.getLink().add(link);
		link = linkFactory.buildLink("/requests/" + requestId + "/locations", Relation.RELATED);
		linkListView.getLink().add(link);
		link = linkFactory.buildLink("/requests/" + requestId + "/dataSources", Relation.RELATED);
		linkListView.getLink().add(link);
		link = linkFactory.buildLink("/requests/" + requestId + "/documents", Relation.RELATED);
		linkListView.getLink().add(link);
		link = linkFactory.buildLink("/requests/" + requestId + "/reviews", Relation.RELATED);
		linkListView.getLink().add(link);
		link = linkFactory.buildLink("/requests/" + requestId + "/comments", Relation.RELATED);
		linkListView.getLink().add(link);
		link = linkFactory.buildLink("/requests/" + requestId + "/events", Relation.RELATED);
		linkListView.getLink().add(link);

	}


	/**
	 * Set the status and statusClass values for the dashboard UI.  (Work around for the "slow script" issue.)
	 * @param requestView
	 * @param status
	 */
	public static void populateRequestStatusClass( RequestView requestView, final String status, final int workflowId, final int groupId ) {

		if( status != null ) {

//TODO: need to handle the display if the overall request status is closed (close the top-level request for the multi-workflow?)

			WorkflowStatusView workflowStatusView = new WorkflowStatusView();
			WorkflowNameView workflowNameView = new WorkflowNameView();


			//
			//set the workflow ID and name
			if( workflowId >= 0 ) {

				workflowStatusView.setWorkflowId(workflowId);
				workflowNameView.setWorkflowId(workflowId);

				String workflowName = "";
				if( RequestStatus.INITIATED.getName().equalsIgnoreCase(status) == false ) {	//don't bother to get the workflow info if this request hasn't yet been submitted

					if( workflowId == 0 ) {	//request before the multi-workflow changes (top-level group is NDS)

						Group.initialize();
						workflowName = Group.NDS.getStatusDisplayName();
						workflowNameView.setGroupId(Group.NDS.getId());

					} else {	//use the workflowId

						workflowName = Group.getStatusDisplayName( groupId );
						workflowNameView.setGroupId( groupId );

					}//end else

				}//end if -- NOT initiated status

				workflowNameView.setWorkflowName(workflowName);	//workflow display name
			}//end if -- workflowId



			if( RequestStatus.INITIATED.getName().equalsIgnoreCase(status) ) {
				workflowStatusView.setStatusClass("label-inverse");
				workflowStatusView.setStatus("NOT SUBMITTED");
				
				workflowNameView.setWorkflowName("");	//no workflow name before the request is submitted
			}

			else if( RequestStatus.SUBMITTED.getName().equalsIgnoreCase(status) ) {
				workflowStatusView.setStatusClass("label-info");
				workflowStatusView.setStatus("SUBMITTED");
			}

			else if( RequestStatus.CHANGE_REQUESTED.getName().equalsIgnoreCase(status) ) {
				workflowStatusView.setStatusClass("label-warning");
				workflowStatusView.setStatus("CHANGE REQUESTED");
			}

			else if( RequestStatus.CLOSED.getName().equalsIgnoreCase(status) ) { 
				workflowStatusView.setStatusClass("label-important");
				workflowStatusView.setStatus("CLOSED");
			}

			else if( RequestStatus.DENIED.getName().equalsIgnoreCase(status) )	{
				workflowStatusView.setStatusClass("label-important");
				workflowStatusView.setStatus("DENIED");
			}

			else if( RequestStatus.APPROVED.getName().equalsIgnoreCase(status) ) {
				workflowStatusView.setStatusClass("label-success");
				workflowStatusView.setStatus("APPROVED");
			}


			//% complete
			else {
				workflowStatusView.setStatusClass("label-info");
				workflowStatusView.setStatus(status);
			}


			requestView.getWorkflowStatusList().add( workflowStatusView );
			requestView.getWorkflowNameList().add( workflowNameView );
		}
	}

	
	public static void populateWorkflowNamePadLeft( RequestView requestView ) {
		if( requestView != null ) {
			
			List<WorkflowNameView> workflowNameList = requestView.getWorkflowNameList();
			if( workflowNameList != null ) {
				
				boolean hasSQDUG = false;
				boolean hasGroup = false;
				
				for( WorkflowNameView currNameView : workflowNameList ) {
					if( currNameView != null ) {
						int groupId = currNameView.getGroupId();
						if( groupId != 0 ) {
							hasGroup = true;
							
							if( groupId == Group.SQDUG.getId() ) {
								hasSQDUG = true;
								break;
							}
						}
					}//end if
				}//end for
				
				
				if( hasGroup == false && requestView.getPadLeft().isEmpty() == true ) {
					requestView.setPadLeft("notsubmittedWorkflow");
				} else {
					if( hasSQDUG == false ) {
						requestView.setPadLeft("ndsWorkflow");
					}
				}//end else
			}//end if
			
		}
	}

}
