package cn.iselab.mooctest.user.service.impl;

import cn.iselab.mooctest.user.mapper.IntegralMapper;
import cn.iselab.mooctest.user.mapper.User2IntegralDao;
import cn.iselab.mooctest.user.mapper.UserIntegralMapper;
import cn.iselab.mooctest.user.model.Integral;
import cn.iselab.mooctest.user.model.User2Integral;
import cn.iselab.mooctest.user.model.UserIntegral;
import cn.iselab.mooctest.user.service.IntegralService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @Author ROKG
 * @Description
 * @Date: Created in 下午6:36 2018/2/13
 * @Modified By:
 */
@Service
public class IntegralServiceImpl implements IntegralService {

    @Autowired
    UserIntegralMapper userIntegralMapper;

    @Autowired
    User2IntegralDao user2IntegralDao;

    @Autowired
    IntegralMapper integralMapper;

    @Override
    public UserIntegral findByUserId(long userId){
        List<UserIntegral> userIntegrals= userIntegralMapper.findByUserId(userId);
        if(userIntegrals!=null && userIntegrals.size()>0){
            return userIntegrals.get(0);
        }else {
            return null;
        }
    }

    @Override
    public UserIntegral saveIntegral(UserIntegral userIntegral){
        userIntegralMapper.save(userIntegral);
        return userIntegral;
    }

    @Override
    public UserIntegral updateIntegral(UserIntegral userIntegral){
        userIntegralMapper.update(userIntegral);
        return userIntegral;
    }

    @Override
    public List<UserIntegral> findPage(String keyword){
        return userIntegralMapper.findAll();
    }

    @Override
    public List<User2Integral> findByTime(long userId, long startTime, long endTime){
        Specifications<User2Integral> where=Specifications.where(getUser2Integral(new Timestamp(startTime),new Timestamp(endTime)));
        return user2IntegralDao.findAll(where);
    }

    @Override
    public User2Integral saveUser2Integral(User2Integral user2Integral){
        return user2IntegralDao.save(user2Integral);
    }

    @Override
    public List<Integral> findIntegrals(){
        return integralMapper.findAll();
    }

    @Override
    public User2Integral findIntegralBySource(String source,long userId){
        Specifications<User2Integral> where=Specifications.where(checkIntegral(source,userId));
        List<User2Integral> user2Integrals= user2IntegralDao.findAll(where);
        return user2Integrals.size()>0?user2Integrals.get(0):null;
    }

    @Override
    public List<User2Integral> findUserIntegralCaught(long userId, long type, String source) {
        return user2IntegralDao.findByUserIdAndAndTypeAndSource(userId, type, source);
    }

    private Specification<User2Integral> getUser2Integral(Timestamp startTime, Timestamp endTime){
        return new Specification<User2Integral>() {
            @Override
            public Predicate toPredicate(Root<User2Integral> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate p=criteriaBuilder.conjunction();
                p.getExpressions()
                        .add(criteriaBuilder.lessThan(root.get("createTime"),endTime));
                p.getExpressions()
                        .add(criteriaBuilder.greaterThan(root.get("createTime"),startTime));
                return p;
            }
        };
    }

    private Specification<User2Integral> checkIntegral(String source, long userId){
        return new Specification<User2Integral>() {
            @Override
            public Predicate toPredicate(Root<User2Integral> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate p=criteriaBuilder.conjunction();
                if (source!=null) {
                    p.getExpressions()
                            .add(criteriaBuilder.equal(root.get("source"), source));
                }
                p.getExpressions()
                        .add(criteriaBuilder.equal(root.get("userId"),userId));
                Date date=new Date();
                SimpleDateFormat time=new SimpleDateFormat("yyyy MM dd");
                SimpleDateFormat sdfmat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Timestamp start,end;
                try {
                    start=new Timestamp(time.parse(time.format(date)).getTime());
                    end=new Timestamp(time.parse(time.format(date)).getTime()+86400000);
                }catch (ParseException e){
                    return p;
                }
                p.getExpressions()
                        .add(criteriaBuilder.between(root.get("createTime"),start,end));
                return p;
            }
        };
    }
}
