package com.cirle.scientific.service.impl;

import com.cirle.scientific.constants.TaskConsts;
import com.cirle.scientific.dao.QkjShareDao;
import com.cirle.scientific.dto.ShareRankDto;
import com.cirle.scientific.po.QkjMember;
import com.cirle.scientific.po.QkjShare;
import com.cirle.scientific.service.MemberService;
import com.cirle.scientific.service.MemberTaskInfoService;
import com.cirle.scientific.service.QkjShareService;
import com.cirle.scientific.service.QkjTaskService;
import com.cirle.scientific.utils.redis.DistributedLockCache;
import com.cirle.scientific.utils.redis.QkLock;
import com.cirle.scientific.utils.redis.RedisUtil;
import com.google.common.collect.Lists;
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.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Component
@Transactional
@Slf4j
public class QkjShareServiceImpl implements QkjShareService {


    private static final Long timeout = 2000L;
    private static final Long tryInterval = 100L;
    private static final Long lockExpireTime = 500L;

    @Autowired
    private QkjShareDao qkjShareDao;

    @Autowired
    private MemberTaskInfoService taskInfoService;


    @Autowired
    private MemberService memberService;

    @Autowired
    private DistributedLockCache distributedLockCache;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveQkjShare(QkjShare share) {
        log.info("saveQkjShare share:{}", share);
        //参数校验
        if (Objects.isNull(share) || StringUtils.isBlank(share.getShareMemcard())
                || StringUtils.isBlank(share.getClickMemcard()) || Objects.isNull(share.getObjType())
                || Objects.isNull(share.getObjId())) {
            return false;
        }
        String lockName = "saveQkjShare" + share.getClickMemcard();
        String lockValue = "saveQkjShare" + share.getClickMemcard();
        QkLock qkLock = QkLock.builder().name(lockName).value(lockValue).build();
        try {
            if (distributedLockCache.tryLock(qkLock, timeout, tryInterval, lockExpireTime)) {
                //同一类型的活动，每一次活动，每人一次机会，已经点击过的不再加积分
                List<QkjShare> oldList = qkjShareDao.getQkjShare(share.getShareMemcard(), share.getClickMemcard(), share.getObjType(), share.getObjId());
                if (CollectionUtils.isNotEmpty(oldList)) {
                    return false;
                }
                //自己给自己点击不加积分
                if (StringUtils.equals(share.getShareMemcard(), share.getClickMemcard())) {
                    return false;
                }
                //添加分享记录
                qkjShareDao.save(share);
                //添加积分
                taskInfoService.increasePoints(share.getShareMemcard(), TaskConsts.SHARE_TASK);
            } else {
                log.info("加锁失败 share:{}", share);
                return false;
            }

        } catch (Exception e) {
            log.error("saveQkjShare err:{}", e);
            throw e;
        } finally {
            distributedLockCache.releaseLock(qkLock);
        }
        return true;
    }

    @Override
    public List<ShareRankDto> inviteRank(String memCard, Integer objType, Integer objId) {
        log.info("inviteRank memCard:{} objType:{} objId:{}", memCard, objType, objId);

        List<ShareRankDto> reslutList = Lists.newArrayList();

        List<QkjShare> shares = qkjShareDao.getQkjShareByObjTYpeAndObjId(objType, objId);
        if (CollectionUtils.isEmpty(shares)) {
            return Collections.emptyList();
        }
        Map<String, List<QkjShare>> shareToClickMap = shares.stream().collect(Collectors.groupingBy(QkjShare::getShareMemcard));
        //查询用户基本信息
        List<String> memcardsSet = Lists.newArrayList(shareToClickMap.keySet());
        Map<String, QkjMember> memCardToObjectMap = memberService.getQkjMemberList(memcardsSet).stream().collect(Collectors.toMap(QkjMember::getMemCard, e -> e, (v1, v2) -> v1));

        for (Map.Entry<String, List<QkjShare>> entry : shareToClickMap.entrySet()) {
            String k = entry.getKey();
            List<QkjShare> v = entry.getValue();
            QkjMember member = memCardToObjectMap.get(k);
            ShareRankDto build = ShareRankDto.builder().count(v.size()).memNickname(member.getMemNickname()).memHeadimg(member.getMemHeadimg()).build();
            reslutList.add(build);
        }
        reslutList = reslutList.stream().sorted(Comparator.comparing(ShareRankDto::getCount).reversed()).collect(Collectors.toList());
        return reslutList;
    }
}
