package com.yonge.cooleshow.biz.dal.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yonge.cooleshow.biz.dal.dao.ActivityUserRewardDao;
import com.yonge.cooleshow.biz.dal.dto.search.ActivityUserRewardSearch;
import com.yonge.cooleshow.biz.dal.entity.ActivityEvaluationRecord;
import com.yonge.cooleshow.biz.dal.entity.ActivityPlan;
import com.yonge.cooleshow.biz.dal.entity.ActivityReward;
import com.yonge.cooleshow.biz.dal.entity.ActivityUserReward;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.queryInfo.UserRewardQueryInfo;
import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationRecordService;
import com.yonge.cooleshow.biz.dal.service.ActivityPlanService;
import com.yonge.cooleshow.biz.dal.service.ActivityRewardService;
import com.yonge.cooleshow.biz.dal.service.ActivityUserRewardService;
import com.yonge.cooleshow.biz.dal.vo.ActivityUserRewardVo;
import com.yonge.cooleshow.biz.dal.vo.UserRewardVo;
import com.yonge.cooleshow.biz.dal.vo.activity.UserRewardWrapper;
import com.yonge.cooleshow.common.enums.ActivityTypeEnum;
import com.yonge.cooleshow.common.enums.EStatus;
import com.yonge.cooleshow.common.enums.RewardTypeEnum;
import com.yonge.cooleshow.common.enums.YesOrNoEnum;
import com.yonge.toolset.base.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ActivityUserRewardServiceImpl extends ServiceImpl<ActivityUserRewardDao, ActivityUserReward> implements ActivityUserRewardService {

    @Autowired
    private ActivityPlanService activityPlanService;
    @Autowired
    private ActivityEvaluationRecordService activityEvaluationRecordService;
    @Autowired
    private ActivityRewardService activityRewardService;

	@Override
    public ActivityUserRewardVo detail(Long id) {
        return baseMapper.detail(id);
    }

    @Override
    public IPage<UserRewardVo> selectPage(IPage<UserRewardVo> page, ActivityUserRewardSearch query){

        // 活动信息
        ActivityPlan activityPlan = activityPlanService.getBaseMapper().selectById(query.getActivityId());
        if (Objects.isNull(activityPlan)) {
            throw new BizException("无效的活动ID");
        }

        if (ActivityTypeEnum.SHARE == activityPlan.getActivityType()) {
            query.setActivityGroupBy(EStatus.DISABLE.getValue());
        }

        // 活动获奖用户信息
        List<UserRewardVo> userRewards = baseMapper.selectPage(page, query);

        if (CollectionUtils.isEmpty(userRewards)) {
            // 直接返回数据，忽略后续流程
            return page.setRecords(userRewards);
        }

        List<Long> userIds = userRewards.stream().map(UserRewardVo::getUserId).distinct().collect(Collectors.toList());

        // 评测活动，获奖记录时间
        if (ActivityTypeEnum.EVALUATION == activityPlan.getActivityType()) {

            Map<Long, ActivityEvaluationRecord> collect = activityEvaluationRecordService.queryActivityUserHighestRankingInfo(query.getActivityId(), userIds).stream()
                    .collect(Collectors.toMap(ActivityEvaluationRecord::getUserId, Function.identity(), (o, n) -> n));

            ActivityEvaluationRecord record;
            for (UserRewardVo item : userRewards) {

                if (collect.containsKey(item.getUserId())) {

                    record = collect.get(item.getUserId());
                    // 重置当前获奖用户分数，评测次数，评测时间
                    item.score(record.getScore())
                            .times(record.getTimes())
                            .setEvaluationTime(record.getCreateTime());
                }
            }
        }

        // 分享活动关联老师信息
        if (ActivityTypeEnum.SHARE == activityPlan.getActivityType()) {

            // 关联老师信息
            Map<Long, String> teacherNameMap = Maps.newConcurrentMap();
            // 关联老师ID
            Map<Long, String> teacherIdMap = Maps.newConcurrentMap();

            Lists.partition(userIds, 30).parallelStream().forEach(item -> {

                List<UserRewardVo> retlist = getBaseMapper().selectActivityShareTeacher(activityPlan.getId(), item);

                // 同一个活动，用户关联多个老师信息
                Map<Long, String> collect = retlist.stream()
                        .collect(Collectors.groupingBy(UserRewardVo::getUserId, Collectors.mapping(x -> {

                            if (StringUtils.isNotEmpty(x.getUsername())) {
                                return x.getUsername();
                            }
                            return x.getRealName();
                        }, Collectors.toSet()))).entrySet().stream()
                        .collect(Collectors.toMap(Map.Entry::getKey, x -> String.join("、", x.getValue())));

                teacherNameMap.putAll(collect);

                // 老师ID
                teacherIdMap.putAll(retlist.stream()
                        .collect(Collectors.groupingBy(UserRewardVo::getUserId,
                                Collectors.mapping(UserRewardVo::getTeacherId, Collectors.toSet()))).entrySet().stream()
                        .collect(Collectors.toMap(Map.Entry::getKey, x -> String.join("、", x.getValue()))));

            });

            // 填充老师信息
            for (UserRewardVo item : userRewards) {

                item.rewardType(RewardTypeEnum.valueOf(activityPlan.getShareType()))
                        .shareType(activityPlan.getShareType())
                        .amount(1L)
                        .teacherName(teacherNameMap.getOrDefault(item.getUserId(), ""))
                        .setTeacherIds(teacherIdMap.getOrDefault(item.getUserId(), ""));
            }
        }

        return page.setRecords(userRewards);
    }

    @Override
    public void saveRewardRecord(Long activityId, Long rewardId, Long userId) {
        ActivityReward activityReward = activityRewardService.getById(rewardId);
        ActivityUserReward activityUserReward = new ActivityUserReward();
        if (activityReward != null) {
            activityUserReward.setUnit(activityReward.getUnit().getCode());
        }
        activityUserReward.setActivityId(activityId);
        activityUserReward.setRewardId(rewardId);
        activityUserReward.setUserId(userId);
        activityUserReward.setCreateTime(new Date());
        activityUserReward.setUpdateTime(new Date());
        activityUserReward.setGrantFlag(1);
        activityUserReward.setReceiveFlag(1);
        this.save(activityUserReward);
    }

    @Override
    public Boolean checkReceiveReward(Long userId, ClientEnum client) {
        UserRewardQueryInfo query = new UserRewardQueryInfo();
        query.setUserId(userId);
        query.setClient(client);
        query.setReceive(YesOrNoEnum.NO);

        return baseMapper.selectReceiveRewardCount(query) >0;
    }

    @Override
    public Boolean receiveReward(Long userId, Long receiveRewardId) {
        ActivityUserReward activityUserReward = getById(receiveRewardId);
        Date receiveTime = new Date();
        // 修改领奖状态
        int i  = baseMapper.receiveReward(userId,receiveRewardId,receiveTime);
        if (i == 0) {
            return false;
        }

        activityRewardService.receiveReward(userId,receiveTime,activityUserReward.getActivityId(),activityUserReward.getRewardId());
        return true;
    }

    @Override
    public IPage<UserRewardWrapper> receiveRewardList(IPage<UserRewardWrapper> page, UserRewardQueryInfo query) {

        return baseMapper.selectReceiveRewardList(page,query);
    }
}