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

import java.util.ArrayList;
import java.util.List;

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

import gov.va.vinci.dart.biz.Event;
import gov.va.vinci.dart.biz.EventSummary;
import gov.va.vinci.dart.db.EventDAO;
import gov.va.vinci.dart.db.util.HibernateDAO;

public class EventDAOImpl extends HibernateDAO implements EventDAO {
	
	@Override
	public void save(final Event event) {
		if (event == null) {
			throw new IllegalArgumentException();
		}
			
		HibernateDAO.save(event);
	}
	
	@Override
	public void delete(final Event event) {
		if (event == null) {
			throw new IllegalArgumentException();
		}

		//delete the EventGroup entries, if any
		int numEventGroupsDeleted = deleteEventGroups( event.getId() );
		
		HibernateDAO.delete(event);
	}
	
	private int deleteEventGroups(final int eventId) {
		Query q = createNativeQuery("delete from hib.EventGroup where eventid=:eid");
		q.setParameter("eid", eventId);

		int numEventGroupsDeleted = q.executeUpdate();
		return numEventGroupsDeleted;
	}

	@Override
	public void deleteByEventAndRequest(final int eventTypeId, final int requestId){
	    Query q = createNativeQuery("delete from hib.Event where eventtypeid=:eventTypeId and requestid=:requestId");
        q.setParameter("eventTypeId", eventTypeId);
        q.setParameter("requestId", requestId);
        q.executeUpdate();
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public List<Event> listByActivityId(final int activityId) {
		Query q = createQuery("from Event e where e.request.activity.id=:aid order by e.request.id desc, e.createdOn desc");
		q.setParameter("aid", activityId);
		return (List<Event>) q.getResultList();
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Event> listByRequestId(final int requestId) {
		Query q = createQuery("from Event e where e.request.id=:rid order by e.request.id desc, e.createdOn desc");
		q.setParameter("rid", requestId);
		return (List<Event>) q.getResultList();
	}



	@Override
	@SuppressWarnings("unchecked")
	public List<Event> listByEventTypeAndRequestId(final int eventTypeId, final int requestId) {
		Query q = createQuery("from Event e where e.eventType.id=:etypeid and e.request.id=:rid order by e.request.id desc, e.createdOn desc");
		q.setParameter("etypeid", eventTypeId);
		q.setParameter("rid", requestId);
		return (List<Event>) q.getResultList();
	}	
	  
	
	@Override
	@SuppressWarnings("unchecked")
	public List<Event> listByActivityIdAndGroupId(final int activityId, final int groupId) {
//		Query q = createQuery("from Event e where e.request.activity.id=:aid and e.group.id=:gid order by e.request.id desc, e.createdOn desc");
		Query q = createQuery("select e from Event e inner join e.groups g where g.id=:gid and e.request.activity.id=:aid order by e.request.id desc, e.createdOn desc");
		q.setParameter("aid", activityId);
		q.setParameter("gid", groupId);
		return (List<Event>) q.getResultList();
	}	

	@Override
	@SuppressWarnings("unchecked")
	public List<Event> listByRequestIdAndGroupId(final int requestId, final int groupId) {
		Query q = createQuery("select e from Event e inner join e.groups g where g.id=:gid and e.request.id=:rid order by e.request.id desc, e.createdOn desc");
		q.setParameter("rid", requestId);
		q.setParameter("gid", groupId);
		return (List<Event>) q.getResultList();
	}	
	
	   @Override
	    @SuppressWarnings("unchecked")
	    public List<Event> listByRequestIdAndGroupIdAndReviewId(final int requestId, final int groupId, final int reviewId) {
	        Query q = createQuery("select e from Event e inner join e.groups g where g.id=:gid and e.request.id=:rid and e.review.id=:revid order by e.request.id desc, e.createdOn desc");
	        q.setParameter("rid", requestId);
	        q.setParameter("revid", reviewId);
	        q.setParameter("gid", groupId);
	        return (List<Event>) q.getResultList();
	    }
	
	@Override
	@SuppressWarnings("unchecked")
	public List<Event> listByActivityIdAndGroupOrder(final int activityId, final int groupId, final boolean isInitial) {
//		Query q = createQuery("from Event e where e.request.activity.id=:aid and e.group.id=:gid and e.initial=:isInit order by e.request.id desc, e.createdOn desc");
		Query q = createQuery("select e from Event e inner join e.groups g where e.request.activity.id=:aid and g.id=:gid and e.initial=:isInit order by e.request.id desc, e.createdOn desc");
		q.setParameter("aid", activityId);
		q.setParameter("gid", groupId);
		q.setParameter("isInit", isInitial);
		return (List<Event>) q.getResultList();		
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Event> listByRequestIdAndGroupOrder(final int requestId, final int groupId, final boolean isInitial) {
		Query q = createQuery("select e from Event e inner join e.groups g where e.request.id=:rid and g.id=:gid and e.initial=:isInit order by e.createdOn desc, e.id desc");
		q.setParameter("rid", requestId);
		q.setParameter("gid", groupId);
		q.setParameter("isInit", isInitial);
		return (List<Event>) q.getResultList();		
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public List<Event> listByEventTypeAndActivityIdAndGroupId(final int eventTypeId, final int activityId, final int groupId) {
//		Query q = createQuery("from Event e where e.eventType.id=:etypeid and e.request.activity.id=:aid and e.group.id=:gid order by e.request.id desc, e.createdOn desc");
		Query q = createQuery("select e from Event e inner join e.groups g where e.eventType.id=:etypeid and e.request.activity.id=:aid and g.id=:gid order by e.request.id desc, e.createdOn desc");
		q.setParameter("etypeid", eventTypeId);
		q.setParameter("aid", activityId);
		q.setParameter("gid", groupId);
		return (List<Event>) q.getResultList();
	}	


	
	@Override
	@SuppressWarnings("unchecked")
	public List<Event> listByEventTypeAndActivityIdAndGroupOrder(final int eventTypeId, final int activityId, final int groupId, final boolean isInitial) {
//		Query q = createQuery("from Event e where e.eventType.id=:etypeid and e.request.activity.id=:aid and e.group.id=:gid and e.initial=:isInit order by e.request.id desc, e.createdOn desc");
		Query q = createQuery("select e from Event e inner join e.groups g where e.eventType.id=:etypeid and e.request.activity.id=:aid and g.id=:gid and e.initial=:isInit order by e.request.id desc, e.createdOn desc");
		q.setParameter("etypeid", eventTypeId);
		q.setParameter("aid", activityId);
		q.setParameter("gid", groupId);
		q.setParameter("isInit", isInitial);
		return (List<Event>) q.getResultList();
	}	
	
	@Override
	@SuppressWarnings("unchecked")
	public List<Event> listByEventTypeAndRequestIdAndGroupOrder(final int eventTypeId, final int requestId, final int groupId, final boolean isInitial) {
		Query q = createQuery("select e from Event e inner join e.groups g where e.eventType.id=:etypeid and e.request.id=:rid and g.id=:gid and e.initial=:isInit order by e.request.id desc, e.createdOn desc");
		q.setParameter("etypeid", eventTypeId);
		q.setParameter("rid", requestId);
		q.setParameter("gid", groupId);
		q.setParameter("isInit", isInitial);
		return (List<Event>) q.getResultList();
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public List<Event> listByGroup(final int groupId) {
		Query query = createQuery("select distinct e from Event e inner join e.groups g where g.id=:gid");
		query.setParameter("gid", groupId);
		
		try {
			return (List<Event>)query.getResultList();
		} catch (NoResultException e) {
			return new ArrayList<Event>();
		}
	}
	
	@Override
	public List<EventSummary> listSummaryByRequestId(final int requestId) {
		return new RequestEventSummaryDAO(requestId).build();
	}

	@Override
	public List<EventSummary> listSummaryByActivityId(final int activityId) {
		return new ActivityEventSummaryDAO(activityId).build();
	}

}
