/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package performa.utils;

import java.util.HashMap;
import java.util.Map;
import oneit.objstore.ObjectTransaction;
import oneit.objstore.rdbms.filters.EqualsFilter;
import oneit.objstore.rdbms.filters.GreaterThanEqualFilter;
import oneit.objstore.rdbms.filters.LessThanEqualFilter;
import oneit.utils.MultiHashtable;
import oneit.utils.table.SingleValueTableModel;
import performa.orm.Answer;
import performa.orm.Candidate;
import performa.orm.Factor;
import performa.orm.FactorQuestionLink;
import performa.orm.FactorScoreResult;
import performa.orm.Level;
import performa.orm.types.QuestionType;

/**
 *
 * @author nilu
 */
public class AnalysisEngine 
{
  
    public static SingleValueTableModel analyseAnswers(Answer[] answers, Level level)
    {
    
        SingleValueTableModel               model               =   new SingleValueTableModel();
        ObjectTransaction                   objTran             =   level.getTransaction();
        MultiHashtable<Candidate, Answer>   answersByCandidate  =   new MultiHashtable<>();
        
        answersByCandidate.groupValues(answers, Answer.pipesAnswer().toCandidate());
        
        int     index   =   0;
        
        for (Candidate candidate : answersByCandidate.keySet())
        {           
            int                     rowNumber       =   0;
            int                     colNumber       =   ( index * 3 ) + 1;
            Map<Factor, Integer>    factorScoreMap  =   new HashMap<>();
            
            model.addCell(rowNumber++, colNumber, new SingleValueTableModel.CellModel(candidate.getFirstName(), ""));
            
            for (Answer answer : answersByCandidate.getValuesForKey(candidate))
            {
                FactorQuestionLink[]    links   = FactorQuestionLink.SearchByAll()
                                                                .andQuestion(new EqualsFilter<>(answer.getQuestion()))
                                                                .search(objTran);
        
                int factorScore = 0;

                for (FactorQuestionLink link: links) 
                {
                    Factor  factor  =   link.getFactor();

                    if(factorScoreMap.containsKey(factor))
                    {
                        factorScore += factorScoreMap.get(factor);
                    }

                    if(link.getReverseScore())
                    {
                        if(answer.getQuestion().getSection().getQuestionType() == QuestionType.IPSATIVE)
                        {
                            factorScore += (10 - answer.getAnswerNo());
                        }
                        else
                        {
                            factorScore += (8 - answer.getAnswerNo());
                        }
                    }
                    else
                    {
                        factorScore += answer.getAnswerNo();
                    }

                    factorScoreMap.put(factor, factorScore);
                }
            }
            
            for (Map.Entry<Factor, Integer> entrySet : factorScoreMap.entrySet()) 
            {
                Factor  factor      = entrySet.getKey();
                Integer factorScore = entrySet.getValue();

                if(index == 0)
                {
                    model.addCell(rowNumber, 0, new SingleValueTableModel.CellModel(factor.getDescription(), ""));
                }
                
                FactorScoreResult result    = FactorScoreResult.SearchByFactorScore()
                                                            .andFactor(new EqualsFilter<>(factor))
                                                            .andLevel(new EqualsFilter<>(level))
                                                            .andFromScore(new LessThanEqualFilter<>(factorScore))
                                                            .andToScore(new GreaterThanEqualFilter<>(factorScore))
                                                            .search(objTran);


                int score   = result != null ? result.getColorCode().getWeightage() : 0;

                // TODO: calculate normalised score based on importance

                model.addCell(rowNumber, colNumber, new SingleValueTableModel.CellModel(String.valueOf(score), ""));
                model.addCell(rowNumber, colNumber + 1, new SingleValueTableModel.CellModel(result != null ? result.getColorCode().getDescription() : "", ""));
                model.addCell(rowNumber++, colNumber + 2, new SingleValueTableModel.CellModel(result != null ? result.getNarrative().getGraphicNotes(): "", ""));

            }
            
            index++;
        }
                
        return model;
    }
}