package com.bizofficer.teacher.testdashboard;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.TypedQuery;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.crossstore.ChangeSetPersister.NotFoundException;
import org.springframework.stereotype.Service;

import com.bizofficer.hibernate.entity.PgprepTestSummary;
import com.bizofficer.hibernate.repository.PgprepTestSummaryRepository;


@Service
public class TestDashboardService{
	
	private static final Logger logger = Logger.getLogger(TestDashboardService.class);
	
	@Autowired
	EntityManagerFactory entityManagerFactory;
	
	@Autowired
	PgprepTestSummaryRepository ptsRepoObj;
	
	public Object doExecute(Object obj) throws NotFoundException{
		BeanTestDashboard objBean = (BeanTestDashboard) obj; 	
		TestDashboardResponseBean dataObj = new TestDashboardResponseBean();
		
		try {
		
			EntityManager entityManager = entityManagerFactory.createEntityManager();
			entityManager.getTransaction().begin();
			
			logger.info( "ScheduleId >>> " +  objBean.getScheduleId() );
			
			String str = "0";
			
			TypedQuery<PgprepTestSummary> queryTS = (TypedQuery<PgprepTestSummary>) entityManager.createQuery("from "+PgprepTestSummary.class.getName()+" where scheduleId=:scheduleId ", PgprepTestSummary.class);
			queryTS.setParameter("scheduleId", objBean.getScheduleId());
			queryTS.setFirstResult(0);
			queryTS.setMaxResults(1);
			List<?> resultListTS = queryTS.getResultList();
			Iterator<?> iteratorTS = resultListTS.iterator();
			if(iteratorTS.hasNext()){
				PgprepTestSummary myObj = (PgprepTestSummary)iteratorTS.next();
				dataObj.setTestTitle(myObj.getTestTitle());
				dataObj.setClassName(myObj.getClassName());
				dataObj.setTotalStudents(ptsRepoObj.countByScheduleId(objBean.getScheduleId()));

				str = String.format("%1.2f", ptsRepoObj.getAverageScoreByScheduleId(objBean.getScheduleId()));
				dataObj.setAverageScore(Double.valueOf(str));
				str = String.format("%1.2f", ptsRepoObj.getAverageTimeByScheduleId(objBean.getScheduleId()));
				dataObj.setAverageTime(Double.valueOf(str));
			}
			
			List<StudentsBean> studentsList = new ArrayList<StudentsBean>();
			StudentsBean studentsBeanObj = null;
			TypedQuery<PgprepTestSummary> query = (TypedQuery<PgprepTestSummary>) entityManager.createQuery("from "+PgprepTestSummary.class.getName()+" where answerDivision is not null and fullMarks>0 and scheduleId=:scheduleId ", PgprepTestSummary.class);
			query.setParameter("scheduleId", objBean.getScheduleId());			
			List<?> resultListCat = query.getResultList();
			Iterator<?> iteratorCat=resultListCat.iterator();
			int i=0;
			Double accuracyTotal = 0.0;
			Double totalAttempted = 0.0;
			while(iteratorCat.hasNext()){
				PgprepTestSummary myObj = (PgprepTestSummary)iteratorCat.next();

				String[] answerDivisionArr = myObj.getAnswerDivision().split("\\|");
				totalAttempted = Double.valueOf(answerDivisionArr[0]) + Double.valueOf(answerDivisionArr[1]);
				if(totalAttempted>0) {
					accuracyTotal+=Double.valueOf(answerDivisionArr[0])/totalAttempted;
				}
				
				//logger.info( "getMarksObtain >>> " +  myObj.getMarksObtain() );
				//logger.info( "getFullMarks >>> " +  myObj.getFullMarks() );
				
				studentsBeanObj = new StudentsBean();
				studentsBeanObj.setTestSession(myObj.getTestSession());
				studentsBeanObj.setStudentName(myObj.getStudentName());
				studentsBeanObj.setAdmissionNumber(myObj.getAdmissionNumber()); 
				studentsBeanObj.setScore( myObj.getMarksObtain().multiply(new BigDecimal("100")).divide(myObj.getFullMarks(), 0, RoundingMode.CEILING)   );
				
				studentsList.add(studentsBeanObj);
				i++;
			}
			
			if(i>0) {
				str = String.format("%1.2f", accuracyTotal/i);
				dataObj.setAverageAccuracy(Double.valueOf(str));
			}
			
			dataObj.setStudentsList(studentsList);
			
			
			String[] scoreRange = {">90","81-90","71-80","61-70","51-60","41-50","<41"};
			String[] scoreRangeArr = {"90$100","81$90","71$80","61$70","51$60","41$50","-100$41"};
			List<MeritStudentsBean> meritStudentsList = new ArrayList<MeritStudentsBean>();
			MeritStudentsBean meritStudentsBeanObj = null;
			
			int j=0;
			for(String myRange: scoreRangeArr) {
				TypedQuery<PgprepTestSummary> queryPTS = (TypedQuery<PgprepTestSummary>) entityManager.createQuery("from "+PgprepTestSummary.class.getName()+" where ((marksObtain*100)/fullMarks)>="+myRange.split("\\$")[0]+" AND ((marksObtain*100)/fullMarks)<="+myRange.split("\\$")[1]+" AND scheduleId=:scheduleId ", PgprepTestSummary.class);
				queryPTS.setParameter("scheduleId", objBean.getScheduleId());
				if(queryPTS.getResultList().size()>0) {
					meritStudentsBeanObj = new MeritStudentsBean();
					meritStudentsBeanObj.setScoreRange(scoreRange[j]);
					meritStudentsBeanObj.setMinScore(Integer.valueOf(myRange.split("\\$")[0]));
					meritStudentsBeanObj.setMaxScore(Integer.valueOf(myRange.split("\\$")[1]));
					meritStudentsBeanObj.setTotalStudents(queryPTS.getResultList().size());
					meritStudentsList.add(meritStudentsBeanObj);				
				}
				j++;
			}
			
			dataObj.setMeritStudents(meritStudentsList);
			
			entityManager.getTransaction().commit();
			entityManager.close();
			
			
		}catch(Exception e) {
			e.getStackTrace();
		}
		
		///logger.info( "dataList >>> " +  dataList );
			
		return dataObj;
	}
	
	
}
