package gov.va.vinci.dart;

import gov.va.vinci.dart.biz.Activity;
import gov.va.vinci.dart.biz.Comment;
import gov.va.vinci.dart.biz.NestableComment;
import gov.va.vinci.dart.biz.Person;
import gov.va.vinci.dart.biz.Request;
import gov.va.vinci.dart.biz.Role;
import gov.va.vinci.dart.common.exception.ObjectNotFoundException;
import gov.va.vinci.dart.common.exception.ValidationException;
import gov.va.vinci.dart.common.json.ErrorView;
import gov.va.vinci.dart.db.util.HibernateSessionManager;
import gov.va.vinci.dart.json.CommentIdView;
import gov.va.vinci.dart.json.CommentListView;
import gov.va.vinci.dart.json.CommentView;
import gov.va.vinci.dart.json.RequestIdView;
import gov.va.vinci.dart.json.SaveNewerCommentView;
import gov.va.vinci.dart.json.SaveReplyCommentView;
import gov.va.vinci.dart.json.builder.CommentListViewBuilder;
import gov.va.vinci.dart.usr.UserPreferences;
import gov.va.vinci.dart.wf2.EmailUtils;
import gov.va.vinci.dart.wf2.WorkflowResolver;

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

import javax.validation.Valid;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class CommunicationController extends DartController { 
	public static final SimpleDateFormat SDF = new SimpleDateFormat("MM/dd/yyyy");
	public static final SimpleDateFormat DATE_TIME_SDF = new SimpleDateFormat("MM/dd/yyyy mm:ss aa");
	private static Log log = LogFactory.getLog(CommunicationController.class);
	
	@Autowired
	private WorkflowResolver workflowResolver;
	
	/**
	 * Retrieve the comments for a specific request.
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/listCommentsByRequest", method = RequestMethod.POST)
	@ResponseBody
	public Object listCommentsByRequest(@RequestBody @Valid final RequestIdView request) {

		if (request == null) {
			return new ErrorView("Error retrieving comments.");
		}
		
		log.debug("list comments for request " + request.getRequestId());
		try {
			HibernateSessionManager.start();

			UserPreferences prefs = getUserPreferences();

			Person person = null;
			try {
				person = Person.findById(prefs.getUserId());
			} catch (ObjectNotFoundException e) {
				throw new ObjectNotFoundException("Cannot find person with id: " + prefs.getUserId());
			}
			Role.initialize();

			
			CommentListView result = new CommentListView();		
			
			int requestId = request.getRequestId();
			
			Request req = null;
			try {
	
				req = RequestController.retrieveRequest(requestId);
	
			} catch (ObjectNotFoundException e) {
				log.error("Error loading request " + requestId, e);
			}
	
			if (req == null) {
				return new ErrorView("Error retrieving comments.");
			}
			
			Activity activity = req.getActivity();
			if( activity == null ) {
				return new ErrorView("Error retrieving comments.");
			}
			
			//verify the access permissions
			if( activity.verifyReadAccessPermissions(person) == false ) {
				log.error("Error retrieving comments: invalid user permissions.");
				return new ErrorView("Error retrieving comments.");
			}


			//get the list of comments for this request
			List<NestableComment> commentList = Comment.listByRequestId(req.getId());
			
			result = (new CommentListViewBuilder().build( commentList ));

			// there used to be a curly brace here that looked like this: }	
			// I think it was the end of an if block that was removed.
			
			return result;
		} catch (Exception e) {
			log.error("Error retrieving comments.", e);
			HibernateSessionManager.rollback();
			return new ErrorView("Error retrieving comments.");
		} finally {
			HibernateSessionManager.close();
		}
	}
	
	
	@RequestMapping(value = "/saveNewComment", method = RequestMethod.POST)
	@ResponseBody
	public Object saveNewComment(@RequestBody @Valid final SaveNewerCommentView view) throws Exception {
		
		log.debug("save new comment");
		
		//int activityId = request.getActivityId();
		int requestId = view.getRequestId();
		
		try {
			HibernateSessionManager.start();
			UserPreferences prefs = getUserPreferences();
			Person person = null;
			try {
				person = Person.findById(prefs.getUserId());
			} catch (ObjectNotFoundException e) {
				throw new ObjectNotFoundException("Cannot find person with id: " + prefs.getUserId());
			}
			Role.initialize();
		
			Request request = null;
			try {
	
				request = RequestController.retrieveRequest(requestId);
	
			} catch (ObjectNotFoundException e) {
				log.error("Error loading request " + requestId, e);
				return new ErrorView("Error loading request " + requestId);
			}
			
			
			if( request != null ) {

				Activity activity = request.getActivity();
				if( activity == null ) {
					return new ErrorView("Error saving comment.");
				}

				//verify the access permissions
				if( activity.verifyReadAccessPermissions(person) == false ) {
					log.error("Error saving comment: invalid user permissions.");
					return new ErrorView("Error saving comment.");
				}


				Comment.create(view.getTopic(), request, prefs.getUserLoginId(), view.getText());

				StringBuffer newComment = new StringBuffer();
				newComment.append("The following communication was added to Request ");
				newComment.append(request.getTrackingNumber());
                newComment.append("\n\n");
                newComment.append(view.getTopic());
                newComment.append("\n\n");
				newComment.append(view.getText());

				EmailUtils.appendDartIndexPageInstructions(newComment);

				StringBuffer subject = EmailUtils.createDARTDefaultSubject(request);
				subject.append("VINCI Dart Communication");

				// send an email to the request owner.
				EmailUtils.emailRequestorAndAllNotifications(request, subject.toString(), newComment.toString());

			}//end if

			return new ErrorView("OK");

		} catch (Exception e) {
			log.error("Error saving comment.", e);
			HibernateSessionManager.rollback();
			return new ErrorView("Error saving comment.");
		} 
		finally {
			HibernateSessionManager.close();
		}
	}
	

	@RequestMapping(value = "/getComment", method = RequestMethod.POST)
	@ResponseBody
	public Object getComment(@RequestBody @Valid final CommentIdView request) {
		
		if (request == null) {
			return new ErrorView("Error retrieving comment.");
		}
		
		log.debug("get comment with id " + request.getCommentId());

		int commentId = request.getCommentId();
		try {
			HibernateSessionManager.start();

			UserPreferences prefs = getUserPreferences();
			
			Person person = null;
			try {
				person = Person.findById(prefs.getUserId());
			} catch (ObjectNotFoundException e) {
				throw new ObjectNotFoundException("Cannot find person with id: " + prefs.getUserId());
			}
			Role.initialize();


			Comment comment = Comment.findById(commentId);
			if( comment == null ) {
				return new ErrorView("Error retrieving comment.");
			}
			
			Request req = comment.getRequest();
			if( req == null ) {
				return new ErrorView("Error retrieving comment.");
			}
			
			Activity activity = req.getActivity();
			if( activity == null ) {
				return new ErrorView("Error retrieving comment.");
			}


			//verify the access permissions
			if( activity.verifyReadAccessPermissions(person) == false ) {
				log.error("Error retrieving comment: invalid user permissions.");
				return new ErrorView("Error retrieving comment.");
			}

			
			//get the author of the comment
			Person author = null;
			try {
				if( comment.getCreatedBy() != null ) {
					author = Person.findByName(comment.getCreatedBy());
				}//end if
			} catch( ObjectNotFoundException e ) {
				//do nothing
			} catch ( ValidationException e ) {
				//do nothing
			}//end catch
			
			
			CommentView view = new CommentView();
			view.setCommentId(comment.getId());
			view.setActivityId(comment.getRequest().getActivity().getId());
			view.setRequestId(comment.getRequest().getId());
			
			if( author != null ) {
				view.setAuthor(author.getFullName());
			} else {
				view.setAuthor(comment.getCreatedBy());
			}
			
			view.setCreated(SDF.format(comment.getCreatedOn()));
			view.setDescription(comment.getDescription());
			view.setCommentText(comment.getText());
			int txtLen = comment.getText().length();
			if (txtLen < 40) {
				view.setShortText(comment.getText());
			}
			else {
				view.setShortText(comment.getText().substring(0,40));
			}
			
			return view;
			
		} catch (Exception e) {
			log.error("Error retrieving comment.", e);
			HibernateSessionManager.rollback();
			return new ErrorView("Error retrieving comment.");
		} 
		finally {
			HibernateSessionManager.close();
		}
	}
	
	@RequestMapping(value = "/saveReplyComment", method = RequestMethod.POST)
	@ResponseBody
	public Object saveReplyComment(@RequestBody @Valid final SaveReplyCommentView request) throws Exception {
		
		if (request == null) {
			return new ErrorView("Error saving comment reply.");
		}
		
		log.debug("save reply comment");
		
		try {
			HibernateSessionManager.start();
			
			UserPreferences prefs = getUserPreferences();
			Person person = null;
			try {
				person = Person.findById(prefs.getUserId());
			} catch (ObjectNotFoundException e) {
				throw new ObjectNotFoundException("Cannot find person with id: " + prefs.getUserId());
			}
			Role.initialize();


			int commentId = request.getCommentId();
			Comment comment = Comment.findById(commentId);
			if (comment == null) {
				return new ErrorView("Error saving comment reply.");
			}

			Request origReq = comment.getRequest();
			if( origReq == null ) {
				return new ErrorView("Error saving comment reply.");
			}
			
			Activity activity = origReq.getActivity();
			if( activity == null ) {
				return new ErrorView("Error saving comment reply.");
			}
			
			//verify the access permissions
			if( activity.verifyReadAccessPermissions(person) == false ) {
				log.error("Error saving comment reply: invalid user permissions.");
				return new ErrorView("Error saving comment reply.");
			}

			
			Comment newComment = Comment.create(comment.getDescription(), comment.getRequest(), prefs.getUserLoginId(), request.getText());
			newComment.setPreviousComment(comment);
			
			StringBuffer newComment1 = new StringBuffer();
			newComment1.append("The following communication was added to Request ");
			newComment1.append(comment.getRequest().getTrackingNumber());
			newComment1.append("\n\n");
			newComment1.append(request.getText());
			
			EmailUtils.appendDartIndexPageInstructions(newComment1);
			
			Request req = newComment.getRequest();
			
			StringBuffer subject = EmailUtils.createDARTDefaultSubject(req);
			subject.append("VINCI Dart Communication");	//only append this to the subject line once
			
			// send an email to the request owner and the poster of the previous comment
			EmailUtils.emailRequestorAndAllNotifications(comment.getRequest(),subject.toString(), newComment1.toString());

			if (comment.getRequest().getCreatedBy().equals(comment.getCreatedBy()) == false) {
			    EmailUtils.sendEmailToUserLoginId(comment.getCreatedBy(), subject.toString(), newComment1.toString());
			}
			
		} catch (ValidationException e) {
			log.error("Error saving comment reply.", e);
			HibernateSessionManager.rollback();
			return new ErrorView("Error saving comment reply.");
		} 
		finally {
			HibernateSessionManager.close();
		}
	
		return new ErrorView("OK");
	}
	
}
