package performa.orm;

import java.util.*;
import oneit.logging.LoggingArea;
import oneit.objstore.ValidationContext;
import oneit.objstore.rdbms.filters.*;
import oneit.objstore.utils.ObjstoreUtils;
import oneit.security.*;
import oneit.utils.*;
import oneit.utils.filter.CollectionFilter;
import oneit.utils.filter.Filter;
import performa.orm.types.*;
import performa.utils.Utils;


public class Job extends BaseJob
{
    private static final long serialVersionUID = 0L;
   
    public  static LoggingArea  LOG = LoggingArea.createLoggingArea("Job");

    
    // This constructor should not be called
    public Job ()
    {
        // Do not add any code to this, always put it in initialiseNewObject
    }

    
    @Override
    protected void postInitNewObj() throws BusinessException 
    {
        super.postInitNewObj();
        
        setRandomKey(RandomStringGen.getRandomStringGen().generateAlphaNum(4));
        setSecUser(SecUser.getTXUser(getTransaction()));
        setApplyBy(DateDiff.add(DateDiff.getToday(), Calendar.DATE, 30));
        
        for(CultureElement cultureElement : CultureElement.searchAll(getTransaction()))
        {
            CultureCriteria cultureCriteria =   CultureCriteria.createCultureCriteria(getTransaction());
            
            cultureCriteria.setCultureElement(cultureElement);
            addToCultureCriterias(cultureCriteria);
        }
    }
    
    
    public Boolean jobDetailsCompleted()
    {
        return getJobTitle() != null && getJobDescription() != null;
    }
    
    
    public Boolean assessmentCompleted()
    {
        return Boolean.TRUE;
    }
    
    
    public Boolean cultureCompleted()
    {
        return Boolean.FALSE;
    }
    
    
    public Boolean jobMatchCompleted()
    {
        return Boolean.TRUE;
    }
    
    
    public Collection<AssessmentCriteria> getAssessmentCriteraByType(CriteriaType criteria)
    {
        Filter  filter  = AssessmentCriteria.SearchByAll().andCriteriaType(new EqualsFilter<>(criteria));   

        return  CollectionFilter.filter(getAssessmentCriteriasSet(), filter);
    }
    
    
    public int getAssessmentCriteraCountByType(CriteriaType criteria)
    {
        return getAssessmentCriteraByType(criteria).size();
    }
    
    
    //to get All Profile Assessment Questions
    public Collection<Question> getAllProfileAssessmentQuestions()
    {
        return pipelineJob().toLevel().toFactors().toFactor().toQuestions().toQuestion().uniqueVals();
    }
    
    
    //to get only left Questions
    public List<Question> getAllLeftQuestions()
    {
        Filter  filter  = Question.SearchByAll().andIsRightQuestion(new EqualsFilter<>(Boolean.FALSE));
        
        return  ObjstoreUtils.sort(CollectionFilter.filter(getAllProfileAssessmentQuestions(), filter), 
                                new ObjectTransform[] {Question.pipesQuestion().toSection().toObjectID(), Question.pipesQuestion().toObjectID()},  
                                new Comparator[]{CollectionUtils.DEFAULT_COMPARATOR, CollectionUtils.DEFAULT_COMPARATOR});
    }
  
    
    public Collection<CultureCriteria> getCultureCriteriasForClass(CultureClass cultureClass)
    {
        Filter  elementFilter   =   CultureElement.SearchByAll().andCultureClass(new EqualsFilter(cultureClass));
        
        Set<CultureElement> cultureElements =   pipelineJob().toCultureCriterias().toCultureElement(elementFilter).uniqueVals();
        
        Filter  criteriaFilter  =   CultureCriteria.SearchByAll().andCultureElement(new InFilter(cultureElements));
        
        return pipelineJob().toCultureCriterias(criteriaFilter).vals();
    }
    
    
    public List<Level>  getAllLevels()
    {     
        List<Level> levels  =   new ArrayList<>();
        
        Utils.getLevelsForComprehensive(getTransaction()).stream().forEach((tuple) -> {
            levels.add((Level)tuple.get0());
        });
        
        return levels;
    }

    
    @Override
    public void validate(ValidationContext context) 
    {
        super.validate(context);

        if (getIncludeAssessmentCriteria())
        {
           context.check(getAssessmentCriteriasCount() > 0 ,  this, MULTIPLEREFERENCE_AssessmentCriterias, "atleastOneRequirement");
        }
    }
    
    
    public int getNoOfCandidatesApplied()
    {
        Filter<JobApplication>  filter = JobApplication.SearchByAll().andApplicationStatus(new EqualsFilter<>(ApplicationStatus.SUBMITTED));

        return this.pipelineJob().toJobApplications(filter).toCandidate().vals().size();
    }
    
    
    public int getNoOfCandidatesShortlisted()
    {
        Filter<JobApplication>  filter = JobApplication.SearchByAll().andApplicationStatus(new EqualsFilter<>(ApplicationStatus.SHORTLISTED));
        
        return this.pipelineJob().toJobApplications(filter).toCandidate().vals().size();
    }
    
    
    public String getDaysTillClose()
    {
        StringBuilder   sb  =   new StringBuilder();

        if(this.getApplyBy()!=null)
        {
            int dateDiff    = DateDiff.getDateDiff(Calendar.DATE, DateDiff.getToday(), this.getApplyBy());

            sb.append(dateDiff);

            if(dateDiff==1)
            {
                sb.append(" day till close");
            }
            else
            {
                sb.append(" days till close");
            }
        }
        return sb.toString();
    }
}