package performa.form;

import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import oneit.logging.*;
import oneit.objstore.*;
import oneit.objstore.parser.BusinessObjectParser;
import oneit.objstore.services.TransactionTask;
import oneit.servlets.forms.*;
import oneit.servlets.process.*;
import oneit.utils.*;
import oneit.utils.parsers.FieldException;
import performa.intercom.utils.IntercomUtils;
import performa.orm.*;
import performa.orm.types.ApplicationStatus;
import performa.utils.AnalysisEngine;
 

public class CompleteApplicationFP extends SaveFP
{
    @Override
    public SuccessfulResult processForm(ORMProcessState process, SubmissionDetails submission, Map params) throws BusinessException, StorageException 
    {
        HttpServletRequest  request         =   submission.getRequest();
        ObjectTransaction   objTran         =   process.getTransaction();
        JobApplication      jobApplication  =   (JobApplication) process.getAttribute("JobApplication");
        
        if(jobApplication.getStatus() != ObjectStatus.NEW)  //getInTransaction will return NULL for NEW object, resulting NPE
        {
            jobApplication  =   (JobApplication) jobApplication.getInTransaction (objTran);
            
            final Long  applicationID   =   jobApplication.getID().longID();
            
            objTran.runInNewTX((ObjectTransaction newTran) ->
            {
                updateJobApplication(newTran, applicationID);
            });
        }
        else
        {
            updateJobApplication(objTran, jobApplication.getID().longID());
        }
        // restarting process as custom attributes needs to be updated to intercom
        completeProcessRestartAndRestoreAttribs(process, request);
        
        jobApplication  = (JobApplication) process.getAttribute("JobApplication");

        // Update company in intercom
        if(jobApplication != null && jobApplication.getJob().getCreatedBy() != null)
        {
            IntercomUtils.updateCompany(jobApplication.getJob().getCreatedBy().getCompany());
        }
        
        return super.processForm(process, submission, params);
    }

    
    @Override
    public void validate(ORMProcessState process, SubmissionDetails submission, MultiException exceptions, Map params) throws StorageException 
    {
        HttpServletRequest  request         =   submission.getRequest();
        ObjectTransaction   objTran         =   ObjectTransaction.getTransaction();
        JobApplication      jobApplication  =   (JobApplication) process.getAttribute("JobApplication");
        
        if(!jobApplication.cultureCompleted())
        {
            BusinessObjectParser.assertFieldCondition(jobApplication.getCandidate().getCultureCriteriaAnswersCount()>0, jobApplication, JobApplication.FIELD_ObjectID, "completeCulture", exceptions, true, request);
        }
        
        if(jobApplication.isIncludeAssessmentCriteria())
        {
            JobApplication  application =   jobApplication.getInTransaction(objTran);
            
            BusinessObjectParser.assertFieldCondition(jobApplication.getJob().getAssessmentCriteriasCount() == application.getAssessmentCriteriaAnswersCount(), jobApplication, JobApplication.FIELD_ObjectID, "completeAssessment", exceptions, true, request);
        }
        
        super.validate(process, submission, exceptions, params);
    }
    
    //This function was created to update Job Application in separate transaction otherwise it doesn't return submitted ANSWERS properly, and thus Test Analysis doesn't work.
    private void updateJobApplication(ObjectTransaction objTran, Long jobApplicationID) throws FieldException
    {
        JobApplication  jobApplication  =   JobApplication.getJobApplicationByID(objTran, jobApplicationID);
        
        LogMgr.log(JobApplication.LOG, LogLevel.PROCESSING2, "CompleteApplicationFP Job Application :", jobApplication);
        
        jobApplication.setApplicationStatus(ApplicationStatus.SUBMITTED);
        jobApplication.setSubmittedDate(new Date());
        
        AnalysisEngine.analyseAnswers(jobApplication.getCandidate(), jobApplication.getJob().getLevel(), jobApplication.getCompletedAnswers()); //getCompletedAnswers() returns collection now
        
        if(jobApplication.hasFailedEssentialRequirements())
        {
            jobApplication.setApplicationStatus(ApplicationStatus.UNSUITABLE);
        }
        LogMgr.log(JobApplication.LOG, LogLevel.PROCESSING2, "Job Application Completed", jobApplication);
    }
}