package cn.com.qmth.stmms.biz.exam.service.impl;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.com.qmth.stmms.biz.common.BaseQueryService;
import cn.com.qmth.stmms.biz.exam.dao.ExamQuestionDao;
import cn.com.qmth.stmms.biz.exam.dao.ExamSubjectPaperDao;
import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
import cn.com.qmth.stmms.biz.exam.model.ExamSubjectPaper;
import cn.com.qmth.stmms.biz.exam.model.ExamSubjectPaperDTO;
import cn.com.qmth.stmms.biz.exam.service.ExamSubjectPaperService;
import cn.com.qmth.stmms.biz.exam.service.query.ExamSubjectPaperSearchQuery;

@Service("examSubjectPaperService")
public class ExamSubjectPaperServiceImpl extends BaseQueryService<ExamSubjectPaper> implements ExamSubjectPaperService {

    @Autowired
    private ExamSubjectPaperDao examSubjectPaperDao;

    @Autowired
    private ExamQuestionDao examQuestionDao;

    @Override
    public ExamSubjectPaperSearchQuery findByQuery(ExamSubjectPaperSearchQuery query) {
        checkQuery(query);
        Page<ExamSubjectPaper> result = examSubjectPaperDao.findAll(buildSpecification(query), query);
        fillResult(result, query);
        return query;
    }

    private Specification<ExamSubjectPaper> buildSpecification(final ExamSubjectPaperSearchQuery query) {
        return new Specification<ExamSubjectPaper>() {

            @Override
            public Predicate toPredicate(Root<ExamSubjectPaper> root, CriteriaQuery<?> cQuery, CriteriaBuilder cb) {
                List<Predicate> predicates = new LinkedList<Predicate>();
                if (query.getExamId() > 0) {
                    predicates.add(cb.equal(root.get("examId"), query.getExamId()));
                }
                if (StringUtils.isNotEmpty(query.getCode())) {
                    predicates.add(cb.equal(root.get("code"), query.getCode()));
                }
                Predicate[] p = new Predicate[predicates.size()];
                cQuery.where(cb.and(predicates.toArray(p)));
                cQuery.orderBy(cb.asc(root.get("mainNumber")));
                return cQuery.getRestriction();
            }
        };
    }

    @Override
    public ExamSubjectPaper save(ExamSubjectPaper examSubjectPaper) {
        return examSubjectPaperDao.save(examSubjectPaper);
    }

    @Override
    public void deleteById(Integer id) {
        examSubjectPaperDao.delete(id);
    }

    @Override
    public List<ExamSubjectPaperDTO> getExamSubjectPaper(Integer id) {
        ExamSubjectPaper examSubjectPaper = getExamSubjectPaperById(id);
        Integer newCount = 0;
        List<ExamSubjectPaperDTO> list = new ArrayList<ExamSubjectPaperDTO>();
        if (examSubjectPaper != null) {
            double totalScore = examSubjectPaper.getTotalScore();
            Integer n = examSubjectPaper.getObjective();
            Integer m = 1;
            DecimalFormat df = new DecimalFormat("####.00");
            // 先查询eb_exam_subject 表中是否有对应的试卷详细结构信息
            List<ExamQuestion> examQuestionList = examQuestionDao.findByExamIdAndSubjectCodeAndObjectiveAndMainNumber(
                    examSubjectPaper.getExamId(), examSubjectPaper.getCode(), (n.equals(1)) ? true : false,
                    examSubjectPaper.getMainNumber());

            if (examQuestionList.isEmpty()) {// 则表示第一次编辑试卷详细结构信息(包括：试卷小标题的分数和标答)
                if (m.equals(n)) {// 客观题则补充无效的个数
                    newCount = examSubjectPaper.getTotalCount();
                } else {// 主观题不用补充
                    newCount = examSubjectPaper.getCount();
                }
                for (int i = 1; i <= newCount; i++) {
                    ExamSubjectPaperDTO examSubjectPaperDTO = new ExamSubjectPaperDTO();
                    examSubjectPaperDTO.setTitle(examSubjectPaper.getQuestionTypeName());
                    examSubjectPaperDTO.setMainNumber(examSubjectPaper.getMainNumber());
                    examSubjectPaperDTO.setSubNumber(i);
                    examSubjectPaperDTO.setObjective(examSubjectPaper.getObjective());
                    examSubjectPaperDTO.setCount(examSubjectPaper.getCount());
                    examSubjectPaperDTO.setIntervalScore(examSubjectPaper.getIntervalScore());
                    examSubjectPaperDTO
                            .setSocre(Double.parseDouble(df.format(totalScore / examSubjectPaper.getCount())));
                    if (i > examSubjectPaper.getCount()) {// 补充无效个数
                        examSubjectPaperDTO.setAnswer("#");
                        examSubjectPaperDTO.setSocre(0d);
                    }
                    examSubjectPaperDTO.setAnswerClass("answer" + i);
                    examSubjectPaperDTO.setScoreClass("score" + i);
                    list.add(examSubjectPaperDTO);
                }
            } else {// 表示进来修改
                for (int i = 0; i < examQuestionList.size(); i++) {
                    ExamSubjectPaperDTO examSubjectPaperDTO = new ExamSubjectPaperDTO();
                    ExamQuestion examQuestion = examQuestionList.get(i);
                    examSubjectPaperDTO.setTitle(examQuestion.getMainTitle());
                    examSubjectPaperDTO.setMainNumber(examQuestion.getMainNumber());
                    examSubjectPaperDTO.setCount(examSubjectPaper.getCount());
                    examSubjectPaperDTO.setSubNumber(examQuestion.getSubNumber());
                    examSubjectPaperDTO.setIntervalScore(examQuestion.getIntervalScore());
                    examSubjectPaperDTO.setAnswer(examQuestion.getAnswer());
                    examSubjectPaperDTO.setSocre(examQuestion.getTotalScore());
                    examSubjectPaperDTO.setAnswerClass("answer" + examQuestion.getSubNumber());
                    examSubjectPaperDTO.setScoreClass("score" + examQuestion.getSubNumber());
                    examSubjectPaperDTO.setObjective(examSubjectPaper.getObjective());
                    list.add(examSubjectPaperDTO);
                }
            }
        }
        return list;
    }

    @Override
    public String getMainNumbersByExamIdAndCodeAndType(int examId, String subjectCode, boolean objective) {
        if (objective) {
            List<String> objectivelist = examSubjectPaperDao.getMainNumbersByExamIdAndCodeAndType(examId, subjectCode,
                    1);
            if (!"[null]".equals(objectivelist.toString())) {
                return objectivelist.get(0).toString();
            }
        } else {
            List<String> subjectivelist = examSubjectPaperDao.getMainNumbersByExamIdAndCodeAndType(examId, subjectCode,
                    0);
            if (!"[null]".equals(subjectivelist.toString())) {
                return subjectivelist.get(0).toString();
            }
        }
        return "";
    }

    @Override
    public ExamSubjectPaper getExamSubjectPaperById(Integer id) {
        return examSubjectPaperDao.findOne(id);
    }

    @Transactional
    @Override
    public void deleteByExamAndCodeAndObjective(int examId, String subjectCode, int objective) {
        examSubjectPaperDao.deleteByExamAndCodeAndObjective(examId, subjectCode, objective);
    }

    @Override
    public Long getExamSubjectPaperCountBy(int examId, String subjectCode, int objective) {
        return examSubjectPaperDao.getExamSubjectPaperCountBy(examId, subjectCode, objective);
    }

}
