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

import com.apobates.forum.event.elderly.ForumActionEnum;
import com.apobates.forum.member.dao.ForumScoreRoleDao;
import com.apobates.forum.member.entity.ForumScoreRole;
import com.apobates.forum.member.service.ForumScoreRoleService;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
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 ForumScoreRoleServiceImpl implements ForumScoreRoleService{
    @Autowired
    private ForumScoreRoleDao forumScoreRoleDao;
    private final static Logger logger = LoggerFactory.getLogger(ForumScoreRoleServiceImpl.class);

    @Cacheable(value = "memberCache", key="'score'")
    @Override
    public Stream<ForumScoreRole> getAllUsed() {
        return forumScoreRoleDao.findAllUsed();
    }
    
    @CacheEvict(value = "memberCache", key="'score'")
    @Override
    public Optional<ForumScoreRole> create(ForumActionEnum action, int degree, int level, double score, boolean status) {
        ForumScoreRole fsr = new ForumScoreRole(action, degree, level, score, status);
        try{
            forumScoreRoleDao.save(fsr);
            if (fsr.getId() > 0) {
                return Optional.of(fsr);
            }
        }catch(Exception e){
            if(logger.isDebugEnabled()){
                logger.debug("创建积分规则失败", e);
            }
        }
        return Optional.empty();
    }
    
    @Cacheable(value = "memberCache", key="'score_'+#id", unless="#result==null")
    @Override
    public Optional<ForumScoreRole> get(int id) {
        if (id > 0) {
            return forumScoreRoleDao.findOne(id);
        }
        return Optional.empty();
    }
    
    @CacheEvict(value = "memberCache", key="'score_'+#id")
    @Override
    public Optional<Boolean> edit(int id, ForumScoreRole updateEntity)throws IllegalArgumentException {
        ForumScoreRole fsr = get(id).orElseThrow(()->new IllegalArgumentException("积分规则不存在"));
        fsr.setDegree(updateEntity.getDegree());
        fsr.setLevel(updateEntity.getLevel());
        fsr.setScore(updateEntity.getScore());
        fsr.setStatus(updateEntity.isStatus());
        return forumScoreRoleDao.edit(fsr);
    }
    
    @Override
    public double getMemberScore(final Map<ForumActionEnum, Long> statsActionSize) {
        if (null == statsActionSize || statsActionSize.isEmpty()) {
            return 0;
        }
        return getAllUsed().filter(Objects::nonNull).reduce(0.0, (partialResult,fsr)->{
            Long operateSize;
            try {
                operateSize = statsActionSize.get(fsr.getAction());
            } catch (Exception e) {
                operateSize = 0L;
            }
            //积分和次频
            if (null != operateSize && operateSize > 0 && fsr.getScore() != 0 && fsr.getDegree() >= 1) {
                double tmp = operateSize / fsr.getDegree() * fsr.getScore();
                return partialResult+tmp;
            }
            return partialResult;
        }, Double::sum);
    }
    
    @Override
    public Stream<ForumScoreRole> getAll() {
        return forumScoreRoleDao.findAll();
    }
}