package com.apobates.forum.member.impl.service;

import com.apobates.forum.member.dao.MemberLevelDao;
import com.apobates.forum.member.entity.MemberLevel;
import com.apobates.forum.member.service.MemberLevelService;
import com.apobates.forum.utils.Commons;
import com.apobates.forum.utils.lang.CommonDoubleBean;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

/**
 *
 * @author xiaofanku
 * @since 20200515
 */
@Service
public class MemberLevelServiceImpl implements MemberLevelService{
    @Autowired
    private MemberLevelDao memberLevelDao;
    private final static Logger logger = LoggerFactory.getLogger(MemberLevelServiceImpl.class);
    
    @Override
    public Stream<MemberLevel> getAllUsed() {
        return memberLevelDao.findAllUsed();
    }
    
    @Override
    public Stream<MemberLevel> getAll() {
        return memberLevelDao.findAll();
    }
    
    @CacheEvict(value="memberCache", key="'level_used'")
    @Override
    public Optional<MemberLevel> create(String names, double minScore, double score, String imageAddr, boolean status) {
        MemberLevel ml = new MemberLevel(0, names, minScore, score, imageAddr, status);
        try {
            memberLevelDao.save(ml);
            return Optional.of(ml);
        } catch (Exception e) {
            if(logger.isDebugEnabled()){
                logger.debug("创建会员等级失败", e);
            }
        }
        return Optional.empty();
    }
    
    @CacheEvict(value="memberCache", key="'level_used'")
    @Override
    public Optional<MemberLevel> edit(int id, String names, double minScore, double score, String imageAddr, boolean status)throws IllegalArgumentException {
        MemberLevel ml = get(id).orElseThrow(()->new IllegalArgumentException("会员等级不存在"));
        if (Commons.isNotBlank(names)) {
            ml.setNames(names);
        }
        if (minScore != ml.getMinScore()) {
            ml.setMinScore(minScore);
        }
        if (score != ml.getScore()) {
            ml.setScore(score);
        }
        if (Commons.isNotBlank(imageAddr)) {
            ml.setImageAddr(imageAddr);
        }
        ml.setStatus(status);
        Optional<Boolean> d = memberLevelDao.edit(ml);
        if (d.isPresent()) {
            return Optional.of(ml);
        }
        return Optional.empty();
    }
    
    @Override
    public Optional<MemberLevel> get(int id) {
        if (id > 0) {
            return memberLevelDao.findOne(id);
        }
        return Optional.empty();
    }
    
    @Override
    public Optional<MemberLevel> getMemeberLevel(double scoreValue) {
        List<CommonDoubleBean> rs = getMemberLevelCommonBean();
        String levelName = CommonDoubleBean.empty().getFormatter(rs).format(scoreValue);
        //从定义中找到是几级
        Optional<CommonDoubleBean> result = rs.stream().filter(cdb -> cdb.getTitle().equals(levelName)).findFirst();
        MemberLevel data = new MemberLevel();
        data.setId(result.orElse(CommonDoubleBean.empty()).getId());
        data.setNames(levelName);
        data.setScore(scoreValue);
        data.setStatus(true);
        return Optional.of(data);
    }
    
    @Override
    public boolean editStatus(int id, boolean status) {
        return memberLevelDao.editStatus(id, status) == 1;
    }
    
    @Cacheable(value="memberCache", key="'level_used'", unless="#result==null")
    @Override
    public List<CommonDoubleBean> getMemberLevelCommonBean() {
        AtomicInteger index = new AtomicInteger(1);
        Function<MemberLevel,CommonDoubleBean> mapper = ml->{
            int rk = index.getAndIncrement();
            return new CommonDoubleBean(rk, ml.getNames(), ml.getMinScore());
        };
        return memberLevelDao.findAllUsed().sorted(Comparator.comparingDouble(MemberLevel::getMinScore)).map(mapper).collect(Collectors.toList());
    }
}