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

import java.util.Date;
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.school.dao.SchoolDao;
import cn.com.qmth.stmms.biz.school.model.School;
import cn.com.qmth.stmms.biz.school.query.SchoolSearchQuery;
import cn.com.qmth.stmms.biz.school.service.SchoolService;

@Service("schoolService")
public class SchoolServiceImpl extends BaseQueryService<School> implements SchoolService {

    @Autowired
    public SchoolDao schoolDao;

    @Override
    public School findById(Integer id) {
        return schoolDao.findOne(id);
    }

    @Override
    public List<School> findAll() {
        return schoolDao.findByEnable(true);
    }

    public SchoolSearchQuery findByQuery(final SchoolSearchQuery query) {
        checkQuery(query);
        Page<School> result = schoolDao.findAll(new Specification<School>() {

            @Override
            public Predicate toPredicate(Root<School> root, CriteriaQuery<?> cQuery, CriteriaBuilder cb) {
                List<Predicate> predicates = new LinkedList<Predicate>();
                if (StringUtils.isNotBlank(query.getName())) {
                    predicates.add(cb.like(root.get("name").as(String.class), query.getName() + "%"));
                }
                if (StringUtils.isNotBlank(query.getProvince())) {
                    predicates.add(cb.equal(root.get("province"), query.getProvince()));
                }
                if (StringUtils.isNotBlank(query.getCity())) {
                    predicates.add(cb.equal(root.get("city"), query.getCity()));
                }
                return predicates.isEmpty() ? cb.conjunction()
                        : cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }

        }, query);
        fillResult(result, query);
        return query;
    }

    @Transactional
    public School save(School school) {
        if (school.getId() != null && school.getId() > 0) {
            school.setTimeModified(new Date());
        } else {
            school.setTimeCreate(new Date());
        }
        return schoolDao.save(school);
    }

    @Transactional
    public void deleteById(Integer id) {
        schoolDao.delete(id);
    }

    @Transactional
    public void delete(School school) {
        schoolDao.delete(school);
    }
}
