package com.infinite.focus.server.notifications.service;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.CriteriaBuilder.In;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.infinite.focus.server.activity.Activity;
import com.infinite.focus.server.activity.Activity_;
import com.infinite.focus.server.auth.Student;
import com.infinite.focus.server.home.GetNotificationsRequest;
import com.infinite.focus.server.home.Notification;
import com.infinite.focus.server.home.NotificationRepository;
import com.infinite.focus.server.students.Student_;
import com.infinite.focus.server.utils.AppUtils;
import com.infinite.focus.server.utils.DateUtils;
import com.infinite.focus.server.utils.UnitExpression;

@Service
public class NotificationServiceImpl implements NotificationService {

	@Autowired
	EntityManager entityManager;

	@Autowired
	NotificationRepository notificationRepository;

	@Override
	public List<Notification> getNotifications(GetNotificationsRequest request) {
		CriteriaBuilder qb = entityManager.getCriteriaBuilder();
		CriteriaQuery<Notification> query = qb.createQuery(Notification.class);
		Root<Notification> root = query.from(Notification.class);

		List<Predicate> predicates = new ArrayList<>();

		if (AppUtils.isNotNullOrEmpty(request.getStudentIds())) {
			Predicate genderPredicate = qb.in(root.get(Notification_.STUDENT_ID)).value(request.getStudentIds());
			predicates.add(genderPredicate);
		} else {
			Predicate genderPredicate = qb.notEqual(root.get(Notification_.STUDENT_ID), 0);
			predicates.add(genderPredicate);
		}

		predicates.add(qb.equal(root.get(Notification_.INSTRUCTOR_ID), request.getInstructor_id()));

		if (request.getFromDate() != null && request.getToDate() != null) {
			System.out.println("getNotifications FromDate " + DateUtils.dayWitTimeFormat.format(request.getFromDate())
					+ " - ToDate " + DateUtils.dayWitTimeFormat.format(request.getToDate()));

			predicates.add(
					qb.between(root.<Date>get(Notification_.CREATEDAT), DateUtils.getFromDateWithoutTime(request.getFromDate()), DateUtils.getToDateWithoutTime(request.getToDate())));
		}
		
		query.where(predicates.toArray(new Predicate[0])).orderBy(qb.desc(root.<Date>get(Notification_.CREATEDAT)));;

		TypedQuery<Notification> typedQuery = entityManager.createQuery(query);
		List<Notification> notifications = typedQuery.getResultList();
		System.out.println("Notification Count = " + notifications.size());
		return notifications;
	}

}
