package cn.iselab.mooctest.user.web.logic.impl;

import cn.iselab.mooctest.rpc.user.constants.IntegralEventConstants;
import cn.iselab.mooctest.rpc.user.data.AddIntegralDTO;
import cn.iselab.mooctest.rpc.user.data.IntegralCaughtDTO;
import cn.iselab.mooctest.rpc.user.data.UserIntegralDTO;
import cn.iselab.mooctest.user.configure.IntegralMap;
import cn.iselab.mooctest.user.mapper.User2IntegralDao;
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 cn.iselab.mooctest.user.web.logic.BaseLogic;
import cn.iselab.mooctest.user.web.logic.IntegralLogic;
import cn.iselab.mooctest.user.web.wrapper.IntegralCaughtWrapper;
import cn.iselab.mooctest.user.web.wrapper.UserIntegralWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author ROKG
 * @Description
 * @Date: Created in 下午11:05 2018/2/13
 * @Modified By:
 */
@Service
public class IntegralLogicImpl extends BaseLogic implements IntegralLogic {

    @Autowired
    IntegralService integralService;

    @Autowired
    IntegralCaughtWrapper integralCaughtWrapper;

    @Autowired
    UserIntegralWrapper userIntegralWrapper;

    @Autowired
    IntegralMap integralMap;

    @Override
    public IntegralCaughtDTO saveIntegralCaught(IntegralCaughtDTO dto){
        User2Integral integral= integralCaughtWrapper.unwrap(dto);
        integral.setCreateTime(new Timestamp(System.currentTimeMillis()));
        integral=integralService.saveUser2Integral(integral);
        addIntegral(integral);
        return integralCaughtWrapper.wrap(integral);
    }

    @Override
    public List<IntegralCaughtDTO> getIntegralCaughts(long userId, long startTime, long endTime){
        List<User2Integral> integrals=integralService.findByTime(userId,startTime,endTime);
        return integrals.parallelStream().map(user2Integral -> {
            IntegralCaughtDTO dto=integralCaughtWrapper.wrap(user2Integral);
            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public List<UserIntegralDTO> getUserIntegrals(String keyword){
        List<UserIntegral> integrals=integralService.findPage(keyword);
        return integrals.parallelStream()
                .map(userIntegral -> userIntegralWrapper.wrap(userIntegral)).collect(Collectors.toList());
    }

    @Override
    public UserIntegralDTO getUserIntegral(Long userId){
        UserIntegral userIntegral=integralService.findByUserId(userId);
        return userIntegralWrapper.wrap(userIntegral);
    }

    @Override
    public boolean addIntegral(AddIntegralDTO dto){
        if (dto.getEvent()==null||dto.getUserId()==null){
            return false;
        }
        Integral integral=integralMap.get(dto.getEvent());
        if (integral==null){
            return false;
        }
        if (integral.getSource().equals(IntegralEventConstants.LOGIN)){
            User2Integral user2Integral=integralService.findIntegralBySource(dto.getEvent(),dto.getUserId());
            if (user2Integral!=null){
                return false;
            }else {
                user2Integral=new User2Integral();
                user2Integral.setType(1);
                user2Integral.setPoints(integral.getPoint());
                user2Integral.setSource(integral.getSource());
                user2Integral.setUserId(dto.getUserId());
                user2Integral.setCreateTime(new Timestamp(System.currentTimeMillis()));

                this.addIntegral(user2Integral);
            }
        }
        return true;
    }

    @Override
    public Map<String,Integral> reloadIntegralMap(){
        return integralMap.reload();
    }

    @Override
    public List<IntegralCaughtDTO> getUserIntegralRecord(long userId, long type, String source) {
        List<User2Integral> user2IntegralList = integralService.findUserIntegralCaught(userId,
                type, source);
        return user2IntegralList.stream()
                .map(user2Integral -> integralCaughtWrapper.wrap(user2Integral))
                .collect(Collectors.toList());
    }

    public UserIntegral addIntegral(User2Integral integral){
        UserIntegral userIntegral=integralService.findByUserId(integral.getUserId());
        if(userIntegral!=null) {
            userIntegral.setTotal(userIntegral.getTotal() + integral.getPoints());
        }else {
            userIntegral=new UserIntegral();
            userIntegral.setUserId(integral.getUserId());
            userIntegral.setTotal(integral.getPoints());
            userIntegral.setCreateTime(new Timestamp(System.currentTimeMillis()));
            userIntegral.setEnabled(true);
        }
        integralService.saveUser2Integral(integral);
        integralService.updateIntegral(userIntegral);
        return userIntegral;
    }
}
