package cn.com.qmth.stmms.biz.mark.service.Impl;

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 cn.com.qmth.stmms.biz.common.BaseQueryService;
import cn.com.qmth.stmms.biz.mark.dao.RejectHistoryDao;
import cn.com.qmth.stmms.biz.mark.model.RejectHistory;
import cn.com.qmth.stmms.biz.mark.query.RejectHistorySearchQuery;
import cn.com.qmth.stmms.biz.mark.service.RejectHistoryService;
import cn.com.qmth.stmms.biz.user.model.User;
import cn.com.qmth.stmms.biz.user.service.UserService;

@Service
public class RejectHistoryServiceImpl extends BaseQueryService<RejectHistory> implements RejectHistoryService {

    @Autowired
    private RejectHistoryDao historyDao;

    @Autowired
    private UserService userService;

    @Override
    public RejectHistorySearchQuery findByQuery(final RejectHistorySearchQuery query) {
        checkQuery(query);
        Page<RejectHistory> result = historyDao.findAll(buildSpecification(query), query);
        fillResult(result, query);
        return query;
    }

    private Specification<RejectHistory> buildSpecification(final RejectHistorySearchQuery query) {
        return new Specification<RejectHistory>() {

            @Override
            public Predicate toPredicate(Root<RejectHistory> 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.isNotBlank(query.getSubjectCode())) {
                    predicates.add(cb.equal(root.get("subjectCode"), query.getSubjectCode()));
                }
                if (StringUtils.isNotBlank(query.getExamNumber())) {
                    predicates.add(cb.equal(root.get("examNumber"), query.getExamNumber()));
                }
                if (StringUtils.isNotBlank(query.getSecretNumber())) {
                    predicates.add(cb.equal(root.get("secretNumber"), query.getSecretNumber()));
                }
                if (query.getStudentId() != null) {
                    predicates.add(cb.equal(root.get("studentId"), query.getStudentId()));
                }
                if (query.getHeaderId() != null && query.getHeaderId() > 0) {
                    predicates.add(cb.equal(root.get("userId"), query.getHeaderId()));
                }
                if (query.getMarkerId() > 0) {
                    predicates.add(cb.equal(root.get("markerId"), query.getMarkerId()));
                }
                if (query.getGroupNumber() != null) {
                    predicates.add(cb.equal(root.get("groupNumber"), query.getGroupNumber()));
                }
                if (StringUtils.isNotBlank(query.getRejectReason())) {
                    predicates.add(cb.like(root.get("reason").as(String.class), query.getRejectReason() + "%"));
                }
                if (StringUtils.isNotBlank(query.getSubjectCodeIn())) {
                    String[] list = query.getSubjectCodeIn().split(",");
                    if (list.length > 0) {
                        Predicate[] sub = new Predicate[list.length];
                        for (int i = 0; i < list.length; i++) {
                            sub[i] = cb.equal(root.get("subjectCode"), list[i]);
                        }
                        predicates.add(cb.or(sub));
                    }
                }
                return predicates.isEmpty() ? cb.conjunction() : cb.and(predicates.toArray(new Predicate[predicates
                        .size()]));
            }
        };
    }

    @Override
    public RejectHistory findLastByLibraryId(Integer libraryId) {
        List<RejectHistory> list = historyDao.findByLibraryIdOrderByIdDesc(libraryId);
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public List<User> getUserIdByExamIdAndSubjectCode(int examId, String subjectCode) {
        List<Integer> userIds = historyDao.getUserIdByExamIdAndSubjectCode(examId, subjectCode);
        List<User> list = new ArrayList<User>();
        for (Integer id : userIds) {
            list.add(userService.findById(id));
        }
        return list;
    }

}
