package com.liangjian.dataplatform.member.service.impl;

import com.liangjian.dataplatform.member.dao.secondary.UserLevelDescRepository;
import com.liangjian.dataplatform.member.dao.secondary.UserLevelUnitRepository;
import com.liangjian.dataplatform.member.entity.po.secondary.UserLevelDesc;
import com.liangjian.dataplatform.member.entity.po.secondary.UserLevelUnit;
import com.liangjian.dataplatform.member.entity.vo.request.LevelListAndDesc;
import com.liangjian.dataplatform.member.service.IUserLevelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Author: 黄子奇
 * @Date: 2019/11/15
 */
@Service
public class UserLevelService implements IUserLevelService {
    @Autowired
    private UserLevelDescRepository userLevelDescRepository;
    @Autowired
    private UserLevelUnitRepository userLevelUnitRepository;

    @Override
    public UserLevelDesc getLevelDesc() {
        List<UserLevelDesc> all = userLevelDescRepository.findAll();
        if(all.isEmpty()) {
            return new UserLevelDesc();
        } else {
            return all.get(0);
        }
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean setLevelDesc(UserLevelDesc userLevelDesc) {
        List<UserLevelDesc> all = userLevelDescRepository.findAll();
        try {
            if (all.isEmpty()) {
                userLevelDescRepository.saveWithCycle(userLevelDesc);
            } else {
                userLevelDesc.setId(all.get(0).getId());
                userLevelDescRepository.saveWithCycle(userLevelDesc);
            }
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }

    @Override
    public List<UserLevelUnit> getAllLevelUnit() {
        return userLevelUnitRepository.findAll();
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean addUserLevelUnit(UserLevelUnit userLevelUnit) {
        if(!userLevelUnit.getId().isEmpty())
            return false;
        try {
            userLevelUnitRepository.saveWithCycle(userLevelUnit);
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }

    @Override
    public Optional<UserLevelUnit> getById(String id) {
        return userLevelUnitRepository.findById(id);
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean saveUserLevelUnit(UserLevelUnit userLevelUnit) {
        if(userLevelUnit.getId().isEmpty())
            return false;
        try {
            userLevelUnitRepository.saveWithCycle(userLevelUnit);
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean deleteUserLevelUnit(String id) {
        try {
            userLevelUnitRepository.deleteById(id);
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }

    @Override
    public Optional<UserLevelUnit> getLevelIn(Integer balance) {
        Specification<UserLevelUnit> specification = (Specification<UserLevelUnit>) (root, criteriaQuery, criteriaBuilder) -> {
            Predicate p1 = criteriaBuilder.le(root.get("growthFrom"), balance);
            Predicate p2 = criteriaBuilder.ge(root.get("growthTo"), balance);
            return criteriaBuilder.and(p1,p2);
        };
        return userLevelUnitRepository.findOne(specification);
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean saveAll(LevelListAndDesc levelListAndDesc) {
        //找出原本所有的
        List<String> upIds = levelListAndDesc.getList().stream().map(i -> i.getId()).collect(Collectors.toList());
        List<UserLevelUnit> all = getAllLevelUnit();
        List<UserLevelUnit> toDelete = all.stream().filter(i -> !upIds.contains(i.getId())).collect(Collectors.toList());

        try {
            userLevelUnitRepository.deleteInBatch(toDelete);
            userLevelUnitRepository.saveAllWithCycle(levelListAndDesc.getList());
            userLevelDescRepository.saveWithCycle(levelListAndDesc.getDesc());
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }
}
