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

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.CheckStudentDao;
import cn.com.qmth.stmms.biz.exam.model.CheckStudent;
import cn.com.qmth.stmms.biz.exam.query.CheckStudentSearchQuery;
import cn.com.qmth.stmms.biz.exam.service.CheckStudentService;
import cn.com.qmth.stmms.common.enums.CheckType;

@Service("checkStudentService")
public class CheckStudentServiceImpl extends BaseQueryService<CheckStudent> implements CheckStudentService {

    @Autowired
    private CheckStudentDao checkStudentDao;

    @Override
    public CheckStudent save(CheckStudent student) {
        return checkStudentDao.save(student);
    }

    @Override
    public List<CheckStudent> findByExamIdAndCheckedAndType(int examId, boolean checked, CheckType type) {
        return checkStudentDao.findByExamIdAndCheckedAndType(examId, checked, type);
    }

    @Transactional
    @Override
    public void deleteByStudentId(int examId) {
        checkStudentDao.deleteByStudentId(examId);
    }

    @Override
    public CheckStudent findByStudentId(Integer studentId) {
        return checkStudentDao.findOne(studentId);
    }

    @Override
    public long countByExamIdAndChecked(int examId, boolean checked) {
        return checkStudentDao.countByExamIdAndChecked(examId, checked);
    }

    @Override
    public CheckStudentSearchQuery findByQuery(final CheckStudentSearchQuery query) {
        checkQuery(query);
        Page<CheckStudent> result = checkStudentDao.findAll(new Specification<CheckStudent>() {

            @Override
            public Predicate toPredicate(Root<CheckStudent> root, CriteriaQuery<?> cQuery, CriteriaBuilder cb) {
                List<Predicate> predicates = new LinkedList<Predicate>();

                if (query.getExamId() != null) {
                    predicates.add(cb.equal(root.get("examId"), query.getExamId()));
                }
                if (query.getStudentId() != null) {
                    predicates.add(cb.equal(root.get("studentId"), query.getStudentId()));
                }
                if (StringUtils.isNotBlank(query.getSubjectCode())) {
                    predicates.add(cb.equal(root.get("subjectCode"), query.getSubjectCode()));
                }
                if (query.getChecked() != null) {
                    predicates.add(cb.equal(root.get("checked"), query.getChecked()));
                }
                if (query.getType() != null) {
                    predicates.add(cb.equal(root.get("type"), query.getType()));
                }
                return predicates.isEmpty() ? cb.conjunction() : cb.and(predicates.toArray(new Predicate[predicates
                        .size()]));
            }
        }, query);
        fillResult(result, query);
        return query;
    }

    @Override
    public long countByExamIdAndSubjectCodeAndChecked(int examId, String subjectCode, boolean checked) {
        return checkStudentDao.countByExamIdAndSubjectCodeAndChecked(examId, subjectCode, checked);
    }

    @Override
    public List<String> findCheckSubjectCode(int examId) {
        return checkStudentDao.findCheckSubjectCodeAndCheckedAndType(examId, false, CheckType.MANUAL);
    }

    @Override
    public List<CheckStudent> findByExamIdAndSubjectCodeAndCheckedAndType(int examId, String subjectCode,
            boolean checked, CheckType type) {
        return checkStudentDao.findByExamIdAndSubjectCodeAndCheckedAndType(examId, subjectCode, checked, type);
    }

}
