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

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

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.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.campus.dao.CampusDao;
import cn.com.qmth.stmms.biz.campus.model.Campus;
import cn.com.qmth.stmms.biz.campus.query.CampusSearchQuery;
import cn.com.qmth.stmms.biz.campus.service.CampusService;
import cn.com.qmth.stmms.biz.common.BaseQueryService;

@Service("campusService")
public class CampusServiceImp extends BaseQueryService<Campus> implements CampusService {

    protected static Logger logger = LoggerFactory.getLogger(CampusServiceImp.class);

    @Autowired
    public CampusDao campusDao;

    @Override
    public Campus findById(Integer id) {
        return campusDao.findOne(id);
    }

    public List<Campus> findBySchoolId(int schoolId) {
        return campusDao.findBySchoolId(schoolId);
    }

    public Map<String, Campus> findBySchool(int schoolId) {
        Map<String, Campus> map = new HashMap<String, Campus>();
        List<Campus> list = findBySchoolId(schoolId);
        if (list != null) {
            for (Campus campus : list) {
                map.put(campus.getName(), campus);
            }
        }
        return map;
    }

    // @Cacheable(value = "campus_cache", key =
    // "T(String).valueOf(#schoolId)+'-'+#name", condition = "#schoolId>0 &&
    // #name!=null")
    public Campus findBySchoolAndName(int schoolId, String name) {
        List<Campus> list = campusDao.findBySchoolIdAndName(schoolId, name);
        return list != null && list.size() > 0 ? list.get(0) : null;
    }

    public CampusSearchQuery findByQuery(final CampusSearchQuery query) {
        checkQuery(query);
        Page<Campus> result = campusDao.findAll(new Specification<Campus>() {

            @Override
            public Predicate toPredicate(Root<Campus> root, CriteriaQuery<?> cQuery, CriteriaBuilder cb) {
                List<Predicate> predicates = new LinkedList<Predicate>();
                if (query.getSchoolId() != null) {
                    predicates.add(cb.equal(root.get("schoolId"), query.getSchoolId()));
                }
                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()));
                }
                if (StringUtils.isNotBlank(query.getDistrict())) {
                    predicates.add(cb.equal(root.get("district"), query.getDistrict()));
                }
                return predicates.isEmpty() ? cb.conjunction()
                        : cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }

        }, query);

        fillResult(result, query);
        return query;
    }

    @Transactional
    // @CachePut(value = "campus_cache", key =
    // "T(String).valueOf(#campus.schoolId)+'-'+#campus.name", condition =
    // "#campus!=null && #campus.schoolId!=null && #campus.name!=null")
    public Campus save(Campus campus) {
        return campusDao.save(campus);
    }

    @Transactional
    // @CacheEvict(value = "campus_cache", allEntries = true, beforeInvocation =
    // true)
    public void deleteById(Integer id) {
        campusDao.delete(id);
    }

    @Transactional
    // @CacheEvict(value = "campus_cache", allEntries = true, beforeInvocation =
    // true)
    public void delete(Campus campus) {
        campusDao.delete(campus);
    }
}
