package gov.va.vinci.dart.db.impl;

import gov.va.vinci.dart.biz.DocumentReviewStatus;
import gov.va.vinci.dart.common.exception.ObjectNotFoundException;
import gov.va.vinci.dart.db.DocumentReviewStatusDAO;
import gov.va.vinci.dart.db.util.HibernateDAO;

import static gov.va.vinci.dart.common.ESAPIValidator.validateIntegerInput;

import java.util.List;

import javax.persistence.NoResultException;
import javax.persistence.Query;

public class DocumentReviewStatusDAOImpl extends HibernateDAO implements DocumentReviewStatusDAO {

	@SuppressWarnings("unchecked")
	@Override
	public DocumentReviewStatus findById(final int documentId, final int reviewerId, final int groupId) throws ObjectNotFoundException {
//		Query query = createQuery("from DocumentReviewStatus where document.id=:did and reviewer.id=:rid and group.id=:gid");
		Query query = createQuery("from DocumentReviewStatus where document.id=:did and reviewer.id=:rid and group.id=:gid order by id desc");
		query.setParameter("did", documentId);
		query.setParameter("rid", reviewerId);
		query.setParameter("gid", groupId);
		try {
			//testing -- occasionally getting some dirty data with more than one record here
			//DocumentReviewStatus result = (DocumentReviewStatus)query.getSingleResult();
			
			DocumentReviewStatus result = null;

			
			List<DocumentReviewStatus> docStatusList = (List<DocumentReviewStatus>)query.getResultList();
			
			if( docStatusList == null || docStatusList.size() < 1 )
				throw new ObjectNotFoundException("No DocumentReviewStatus found for document id " + documentId);
				
			result = docStatusList.get(0);

			
			if (result == null) {
				throw new ObjectNotFoundException("No DocumentReviewStatus found for document id " + documentId);
			}
			
			return result;
		} catch (NoResultException e) {
			throw new ObjectNotFoundException("No DocumentReviewStatus found for document id " + documentId, e);
		}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public DocumentReviewStatus findByGroupId(final int documentId, final int groupId) throws ObjectNotFoundException {
//		Query query = createQuery("from DocumentReviewStatus where document.id=:did and group.id=:gid");
		Query query = createQuery("from DocumentReviewStatus where document.id=:did and group.id=:gid order by id desc");
		query.setParameter("did", documentId);
		query.setParameter("gid", groupId);
		try {
			//testing -- the original business rules imply that there could be more than one DocumentReviewStatus here (because we originally set the DocumentReviewStatus per reviewer, NOT per group)
			//DocumentReviewStatus result = (DocumentReviewStatus)query.getSingleResult();
			
			
			DocumentReviewStatus result = null;

			
			List<DocumentReviewStatus> docStatusList = (List<DocumentReviewStatus>)query.getResultList();
			
			if( docStatusList == null || docStatusList.size() < 1 )
				throw new ObjectNotFoundException("No DocumentReviewStatus found for document id " + documentId);
				
			result = docStatusList.get(0);
			
			
			if (result == null) {
				throw new ObjectNotFoundException("No DocumentReviewStatus found for document id " + documentId);
			}
			
			return result;
		} catch (NoResultException e) {
			throw new ObjectNotFoundException("No DocumentReviewStatus found for document id " + documentId, e);
		}
	}
	
    @Override
    public int countGroupId(final int documentId, final int groupId) throws ObjectNotFoundException {
    	int validDocumentId = validateIntegerInput(String.valueOf(documentId));
    	int validGroupId = validateIntegerInput(String.valueOf(groupId));
        Query q = createNativeQuery("SELECT count(*) FROM [hib].[documentreviewstatus] status where status.documentid=:did and status.groupid=:gid");
        q.setParameter("did", validDocumentId);
		q.setParameter("gid", validGroupId);
        int iVal = (Integer) q.getSingleResult();

        return iVal;
    }
	
	@Override
	@SuppressWarnings("unchecked")
	public List<DocumentReviewStatus> listByReviewerId(final int reviewerId) {
		Query query = createQuery("from DocumentReviewStatus where reviewer.id=:rid");
		query.setParameter("rid", reviewerId);
		return (List<DocumentReviewStatus>)query.getResultList(); 
	}

	@Override
	public void save(DocumentReviewStatus status) {
		if (status == null) {
			throw new IllegalArgumentException();
		}
		
		HibernateDAO.save(status);
	}

}
