package com.bizofficer.apiweb.testsubmit;



import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.TypedQuery;
import javax.sql.DataSource;

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.PgprepTestDetails;
import com.bizofficer.hibernate.entity.PgprepTestSummary;
import com.bizofficer.hibernate.entity.QbGroupedItem;
import com.bizofficer.hibernate.repository.PgprepTestDetailsRepository;
import com.bizofficer.hibernate.repository.PgprepTestSummaryRepository;
import com.bizofficer.util.module.MysqlTableNames;
import com.bizofficer.util.module.QuestionHtml;
import com.bizofficer.util.system.MakeDate;
import com.fasterxml.jackson.databind.ObjectMapper;



@Service
public class TestSubmitService{
	
	private static final Logger logger = Logger.getLogger(TestSubmitService.class);
	
	@Autowired
	EntityManagerFactory entityManagerFactory;
	
	@Autowired
	PgprepTestDetailsRepository tdRepoObj;
	
	@Autowired
	PgprepTestSummaryRepository tsRepoObj;
	
	@Autowired
    DataSource appDataSource;
    Connection conn;
    PreparedStatement ps;
    ResultSet rs;
	
	public Object save(Object obj) throws NotFoundException{
		TestSubmitBean myObjTestSubmitBean = (TestSubmitBean) obj; 	
		TestSubmitResponseBean testSubmitResponseBeanObj = new TestSubmitResponseBean();
		
		try {
			testSubmitResponseBeanObj.setResponseTxt("failed");
			
			EntityManager entityManager = entityManagerFactory.createEntityManager();
			entityManager.getTransaction().begin();
			
			ObjectMapper objectMapper = new ObjectMapper();
			AnsDetailsBeanMapper objBean = objectMapper.readValue(myObjTestSubmitBean.getAnsdetails(), AnsDetailsBeanMapper.class);
			
			if(objBean.getOrganisationId()==null || objBean.getStudentId()==null || objBean.getTestTitle()==null || objBean.getQuestionSet()==null) {
				return testSubmitResponseBeanObj;
			}
			
			logger.info("TestSubmitService Test Title: "+objBean.getTestTitle() );
			logger.info("TestSubmitService Student Id: "+objBean.getStudentId() );
			
			MakeDate makeDateObj = new MakeDate();
			
				String testSession = UUID.randomUUID().toString();
				Integer correctAns=0, incorrectAns=0, notAnswered=0;
				BigDecimal fullMarks = new BigDecimal(0);
				BigDecimal marksObtain = new BigDecimal(0);
				String marksDivision = "";
				List<Integer> sectionIdList = new ArrayList<Integer>();
				
				if(objBean.getTestType()!=3 && objBean.getQuestionSet()!=null && objBean.getQuestionSet().size()>0) { 
					marksDivision = objBean.getQuestionSet().get(0).getCorrectAnswerMarks()+";"+objBean.getQuestionSet().get(0).getIncorrectAnswerMarks()+";"+objBean.getQuestionSet().get(0).getNotAnswerMarks();
				}
				
				for(QuestionSetBean myQObj: objBean.getQuestionSet()) {
					
					///FIND CORRECT ANSWER **************************************************************
					if(myQObj.getItemId()!=null && myQObj.getItemId()>0) {
						TypedQuery<QbGroupedItem> queryGBGI = (TypedQuery<QbGroupedItem>) entityManager.createQuery("from "+QbGroupedItem.class.getName()+" where itemId="+myQObj.getItemId(), QbGroupedItem.class);
						queryGBGI.setFirstResult(0);
						queryGBGI.setMaxResults(1);
						List<?> resultListGBGI = queryGBGI.getResultList();
						Iterator<?> iteratorGBGI = resultListGBGI.iterator();
						if(iteratorGBGI.hasNext()){
							QbGroupedItem myObjGBGI = (QbGroupedItem)iteratorGBGI.next();

							myQObj.setCorrectResponse(new QuestionHtml().getAnswerFromXmlParser(myObjGBGI.getItemText(),myObjGBGI.getItemTitle()));
							logger.info("CorrectResponse: "+myQObj.getCorrectResponse());
							
						}
						
					}else {					
						conn = appDataSource.getConnection();
			            if(conn != null){	
							String sqlAA = "SELECT q.assess_id,t.qb_id,q.assess_title,q.assess_text,q.display_id FROM "+MysqlTableNames.getQbAssessmentItem()+" q, "+MysqlTableNames.getQbItems()+" t WHERE q.assess_id=t.item_id AND q.assess_id=? LIMIT 1 ";
							PreparedStatement psAA = conn.prepareStatement(sqlAA);	
							psAA.setInt(1, myQObj.getQuestionId() );
							logger.info("Quesions query: " + psAA);
							ResultSet rsAA = psAA.executeQuery();
			                if (rsAA.next()) {
								myQObj.setCorrectResponse(new QuestionHtml().getAnswerFromXmlParser(rsAA.getString("assess_text"),rsAA.getString("assess_title")));
								logger.info("CorrectResponse: "+myQObj.getCorrectResponse());
			                }  
			                rsAA.close();
			                psAA.close();			                
			            }
			            conn.close();
		            }
					
					
						PgprepTestDetails saveTDObj = new PgprepTestDetails();
						saveTDObj.setTestSession(testSession);						
						saveTDObj.setStudentId(objBean.getStudentId());
						saveTDObj.setSectionName(myQObj.getSectionName());
						if(myQObj.getItemId()!=null && myQObj.getItemId()>0) {
							saveTDObj.setItemId(myQObj.getItemId());
							String assessId = String.valueOf(myQObj.getQuestionId());
							assessId = assessId.substring(0, assessId.length()-4);
							saveTDObj.setAssessId(Integer.valueOf(assessId));
						}else {
							saveTDObj.setAssessId(myQObj.getQuestionId());
						}
						
						logger.info("AssessId: "+ myQObj.getQuestionId() );
						
						saveTDObj.setTopicId(myQObj.getTopicId());						
						saveTDObj.setAnswerGiven(myQObj.getStudentResponse());					
						if(myQObj.getCorrectResponse()!=null && myQObj.getStudentResponse()!=null && myQObj.getCorrectResponse().length()>0 && myQObj.getStudentResponse().length()>0 && myQObj.getCorrectResponse().equalsIgnoreCase(myQObj.getStudentResponse()) ) {
							saveTDObj.setMarks(myQObj.getCorrectAnswerMarks());					
							saveTDObj.setStatus("Correct");
							marksObtain = marksObtain.add(myQObj.getCorrectAnswerMarks());
							correctAns+=1;
							logger.info("AssessId: "+myQObj.getQuestionId()+" ---> Correct" );
							
						}else if(myQObj.getCorrectResponse()!=null && myQObj.getStudentResponse()!=null && myQObj.getCorrectResponse().length()>0 && myQObj.getStudentResponse().length()>0 && !myQObj.getCorrectResponse().equalsIgnoreCase(myQObj.getStudentResponse()) ) {
							saveTDObj.setMarks(myQObj.getIncorrectAnswerMarks());					
							saveTDObj.setStatus("Incorrect");						
							marksObtain = marksObtain.add(myQObj.getIncorrectAnswerMarks());
							incorrectAns+=1;
							logger.info("AssessId: "+myQObj.getQuestionId()+" ---> Incorrect" );
							
						}else if(myQObj.getStudentResponse()==null || (myQObj.getStudentResponse()!=null && myQObj.getStudentResponse().length()<1)) {
							saveTDObj.setMarks(myQObj.getNotAnswerMarks());					
							saveTDObj.setStatus("NotAnswer");
							marksObtain = marksObtain.add(myQObj.getNotAnswerMarks());
							notAnswered+=1;
							
							logger.info("AssessId: "+myQObj.getQuestionId()+" ---> NotAnswer" );
						}					
						
						logger.info("CorrectResponse: "+myQObj.getCorrectResponse() );
						logger.info("StudentResponse: "+myQObj.getStudentResponse() );
						
						saveTDObj.setCorrectAns(myQObj.getCorrectResponse());
						saveTDObj.setAnswerDate(makeDateObj.getCurrentTimeStamp());
						saveTDObj.setTimeSpent(myQObj.getTimeSpent());
						saveTDObj.setTotalMarks(myQObj.getCorrectAnswerMarks());
						fullMarks = fullMarks.add(myQObj.getCorrectAnswerMarks());
						
						if(objBean.getTestType()==3 && myQObj.getSectionId()!=null && myQObj.getSectionId()>0 && sectionIdList.indexOf(myQObj.getSectionId())==-1  ) {
							sectionIdList.add(myQObj.getSectionId());
							marksDivision += myQObj.getSectionId()+"~"+myQObj.getCorrectAnswerMarks()+";"+myQObj.getIncorrectAnswerMarks()+";"+myQObj.getNotAnswerMarks()+"|";
						}
						
						tdRepoObj.save(saveTDObj);					
				}
				
				PgprepTestSummary  saveTSObj = new PgprepTestSummary();
				saveTSObj.setOrganisationId(objBean.getOrganisationId());
				saveTSObj.setTestSession(testSession);
				saveTSObj.setStudentId(objBean.getStudentId());
				saveTSObj.setTestRootId(objBean.getTestId());
				saveTSObj.setTestNodeId(objBean.getModelTestId());
				saveTSObj.setTestType(objBean.getTestType());				
				saveTSObj.setTestOption(objBean.getTestType());				
				saveTSObj.setTestTitle(objBean.getTestTitle());
				saveTSObj.setAnswerDivision(String.valueOf(correctAns)+"|"+String.valueOf(incorrectAns)+"|"+String.valueOf(notAnswered));
				saveTSObj.setTotalTime(objBean.getTotalTime());
				
				if(objBean.getRemainingTime()<4) {
					objBean.setRemainingTime(0);
				}
				
				saveTSObj.setTimeSpent((objBean.getTotalTime()*60)-objBean.getRemainingTime());
				saveTSObj.setMarksDivision(marksDivision);				
				saveTSObj.setFullMarks(fullMarks);
				saveTSObj.setMarksObtain(marksObtain);
				saveTSObj.setStartDate(makeDateObj.getCurrentTimeStamp());
				saveTSObj.setEndDate(makeDateObj.getCurrentTimeStamp());
				saveTSObj.setTestStatus(1);
				saveTSObj.setLastVisitedQuestion(0);
				saveTSObj.setTotalQuestion(objBean.getTotalQuestion());
				
				saveTSObj.setStudentName(objBean.getStudentName());
				saveTSObj.setAdmissionNumber(objBean.getAdmissionNumber());
				saveTSObj.setSchoolId(objBean.getSchoolId());
				saveTSObj.setSchoolName(objBean.getSchoolName());
				saveTSObj.setClassName(objBean.getClassName());			
				saveTSObj.setScheduleId(objBean.getScheduleId());
				saveTSObj.setSubject(objBean.getSubject());
				
				PgprepTestSummary resultObj = tsRepoObj.save(saveTSObj);
				
				if(resultObj!=null && resultObj.getId()>0) {
					testSubmitResponseBeanObj.setTestType(objBean.getTestType());
					testSubmitResponseBeanObj.setTestSession(testSession);
					testSubmitResponseBeanObj.setResponseTxt("OK");
					
					/// DELETE IF EXIST INCOMPLETE TEST ******************************************
					//EntityManager entityManager = entityManagerFactory.createEntityManager();
					///entityManager.getTransaction().begin();
					TypedQuery<PgprepTestSummary> queryaa = (TypedQuery<PgprepTestSummary>) entityManager.createQuery("from "+PgprepTestSummary.class.getName()+" where testStatus=0 and organisationId=:organisationId and studentId=:studentId order by id desc ", PgprepTestSummary.class);
					queryaa.setParameter("organisationId", objBean.getOrganisationId()); 
					queryaa.setParameter("studentId", objBean.getStudentId()); 
					queryaa.setFirstResult(0);
					queryaa.setMaxResults(5);
					List<?> resultListAA = queryaa.getResultList();
					Iterator<?> iteratorAA=resultListAA.iterator();	
					while(iteratorAA.hasNext()){
						PgprepTestSummary myObj = (PgprepTestSummary)iteratorAA.next();
						PgprepTestSummary enquiryb = entityManager.find(PgprepTestSummary.class, myObj.getId());
						if(enquiryb != null){					
							entityManager.remove(enquiryb);
							entityManager.getTransaction().commit();
				        }
					}
					////***************************************************************************
					
					logger.info("**************************************************************");
					logger.info("Test submitted successfully. Session: "+testSession+" Student Id: "+objBean.getStudentId());
					logger.info("**************************************************************");
					
				}
				
				
				entityManager.getTransaction().commit();
				entityManager.close();	
				
		}catch(Exception e) {
			e.getStackTrace();
		}
		
		
		return testSubmitResponseBeanObj;
	}
	
	
	
	
}
