package com.pcloud.book.group.biz.impl;

import com.pcloud.analysisengine.wechatgroupan.dto.GroupBrowseDTO;
import com.pcloud.appcenter.app.dto.AppDto;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.consumer.analysisengine.WechatGroupAnConsr;
import com.pcloud.book.consumer.app.AppConsr;
import com.pcloud.book.consumer.reader.ReaderConsr;
import com.pcloud.book.consumer.resource.ProductConsr;
import com.pcloud.book.consumer.trade.TradeConsr;
import com.pcloud.book.group.biz.LearningReportBiz;
import com.pcloud.book.group.dao.*;
import com.pcloud.book.group.dto.AppClickDTO;
import com.pcloud.book.group.dto.ClassifyDTO;
import com.pcloud.book.group.dto.LearningScoreDTO;
import com.pcloud.book.group.dto.UserLearningInfoDTO;
import com.pcloud.book.group.entity.GroupQrcode;
import com.pcloud.book.group.entity.LearningReportBrowseRecord;
import com.pcloud.book.group.entity.LearningReportTouchRecord;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.QrcodeUtils;
import com.pcloud.common.utils.httpclient.UrlUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.facade.tradecenter.dto.SaleDetailByQrcodeDto;
import com.pcloud.readercenter.wechat.entity.WechatUser;
import com.pcloud.resourcecenter.product.dto.ProductDto;
import com.pcloud.resourcecenter.product.dto.ProductTypeDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @Description
 * @Author ruansiyuan
 * @Date 2019/7/23 19:49
 **/
@Component("learningReportBiz")
public class LearningReportBizImpl implements LearningReportBiz {

    @Autowired
    private LearningReportBrowseRecordDao learningReportBrowseRecordDao;
    @Autowired
    private LearningReportTouchRecordDao learningReportTouchRecordDao;
    @Autowired
    private GroupQrcodeDao groupQrcodeDao;
    @Autowired
    private BookGroupClassifyDao bookGroupClassifyDao;
    @Autowired
    private AppClickRecordDao appClickRecordDao;
    @Autowired
    private AppConsr appConsr;
    @Autowired
    private ProductConsr productConsr;
    @Autowired
    private ReaderConsr readerConsr;
    @Autowired
    private WechatGroupAnConsr wechatGroupAnConsr;
    @Autowired
    private TradeConsr tradeConsr;

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("新增学习报告浏览记录")
    @Override
    public Long createLearningReportBrowseRecord(LearningReportBrowseRecord learningReportBrowseRecord) {
        learningReportBrowseRecordDao.insert(learningReportBrowseRecord);
        return learningReportBrowseRecord.getId();
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("新增学习触发浏览记录")
    @Override
    public Long createLearningReportTouchRecord(String wxUserId, String wxGroupId) {
        LearningReportTouchRecord learningReportTouchRecord = new LearningReportTouchRecord();
        learningReportTouchRecord.setWxUserId(wxUserId);
        GroupQrcode groupQrcode = groupQrcodeDao.getGroupQrcodeByGroupId(wxGroupId);
        if (groupQrcode != null) {
            learningReportTouchRecord.setQrcodeId(groupQrcode.getId());
            Long classifyId = groupQrcode.getClassifyId();
            learningReportTouchRecord.setClassifyId(classifyId);
            if (classifyId != null) {
                ClassifyDTO classifyDTO = bookGroupClassifyDao.getById(classifyId);
                if (classifyDTO != null) {
                    learningReportTouchRecord.setBookGroupId(classifyDTO.getBookGroupId());
                }
            }
        }
        learningReportTouchRecordDao.insert(learningReportTouchRecord);
        return learningReportTouchRecord.getId();
    }

    @ParamLog("获取最近学习")
    @Override
    public List<AppClickDTO> getRecentlyLearning(Long wechatUserId, Long qrcodeId) {
        if (wechatUserId == null || qrcodeId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "参数错误！");
        }
        List<AppClickDTO> appClickDTOS = appClickRecordDao.getRecentlyClick(wechatUserId, qrcodeId, 2);
        if (!ListUtils.isEmpty(appClickDTOS)) {
            List<Long> appIds = new ArrayList<>();
            List<Long> productIds = new ArrayList<>();
            for (AppClickDTO appClickDTO : appClickDTOS) {
                if ("APP".equalsIgnoreCase(appClickDTO.getServeType())) {
                    appIds.add(appClickDTO.getServeId());
                }
                if ("PRODUCT".equalsIgnoreCase(appClickDTO.getServeType())) {
                    productIds.add(appClickDTO.getServeId());
                }
            }
            Map<Long, AppDto> appDtoMap = new HashMap<>();
            if (!ListUtils.isEmpty(appIds)) {
                appDtoMap = appConsr.mapByIds(appIds);
            }
            Map<Long, ProductDto> productDtoMap = new HashMap<>();
            if (!ListUtils.isEmpty(productIds)) {
                productDtoMap = productConsr.getProBasesByIds(productIds);
            }
            for (AppClickDTO appClickDTO : appClickDTOS) {
                Long id = appClickDTO.getServeId();
                String type = appClickDTO.getServeType();
                if ("PRODUCT".equalsIgnoreCase(type)) {
                    ProductDto productDto = productDtoMap.get(id);
                    if (productDto != null) {
                        appClickDTO.setServeName(productDto.getProductName());
                        appClickDTO.setImage(productDto.getCoverImg());
                        ProductTypeDto productTypeDto = productDto.getProductTypeDto();
                        if (productTypeDto != null) {
                            appClickDTO.setTypeName(productTypeDto.getTypeName());
                            appClickDTO.setTypeCode(productTypeDto.getTypeCode());
                        }
                    }
                }
                if ("APP".equalsIgnoreCase(type)) {
                    AppDto appDto = appDtoMap.get(id);
                    if (appDto != null) {
                        appClickDTO.setTypeName(appDto.getTypeName());
                        appClickDTO.setServeName(appDto.getTitle());
                        appClickDTO.setImage(appDto.getSquareImg());
                        appClickDTO.setTypeCode(appDto.getTypeCode());
                    }
                }
            }

        }
        return appClickDTOS;
    }

    @ParamLog("获取学习元气值前五名")
    @Override
    public List<LearningScoreDTO> getLearningTopFive(Long qrcodeId) {
        List<LearningScoreDTO> learningScoreDTOS = getLearningScoreDTOSortList(qrcodeId);
        learningScoreDTOS = learningScoreDTOS.stream().limit(5).collect(Collectors.toList());
        if (!ListUtils.isEmpty(learningScoreDTOS)) {
            List<Long> fiveUserIds = learningScoreDTOS.stream().map(LearningScoreDTO::getWechatUserId).collect(Collectors.toList());
            Map<Long, WechatUser> userMap = readerConsr.getUserList(fiveUserIds);
            for (LearningScoreDTO learningScoreDTO : learningScoreDTOS) {
                Long userId = learningScoreDTO.getWechatUserId();
                WechatUser wechatUser = userMap.get(userId);
                if (wechatUser != null) {
                    learningScoreDTO.setNickName(wechatUser.getWechatUserNickname());
                    learningScoreDTO.setHeadUrl(wechatUser.getWechatUserHeadurl());
                }
            }
        }
        return learningScoreDTOS;
    }

    @ParamLog("获取元气值全部排行")
    private List<LearningScoreDTO> getLearningScoreDTOSortList(Long qrcodeId){
        //获取浏览记录
        List<GroupBrowseDTO> groupBrowseDTOS = wechatGroupAnConsr.getGroupBrowseList(qrcodeId);
        Map<Long, Integer> browseMap = new HashMap<>();
        for (GroupBrowseDTO groupBrowseDTO : groupBrowseDTOS) {
            browseMap.put(groupBrowseDTO.getUserId(), groupBrowseDTO.getAllBrowseTimes());
        }
        //内部接口根据qrcodeId获取群应用和作品购买情况
        List<SaleDetailByQrcodeDto> saleDetailByQrcodeDtos = tradeConsr.getSaleDetailByQrcodeId(qrcodeId);
        Map<Long, Double> buyMap = new HashMap<>();
        for (SaleDetailByQrcodeDto saleDetailByQrcodeDto:saleDetailByQrcodeDtos){
            buyMap.put(saleDetailByQrcodeDto.getWechatUserId(),saleDetailByQrcodeDto.getAmount().doubleValue());
        }
        //计算
        List<Long> userIds = new ArrayList<>();
        userIds.addAll(browseMap.keySet());
        userIds.addAll(buyMap.keySet());
        userIds = userIds.stream().distinct().collect(Collectors.toList());
        Map<Long, Integer> scoreMap = new HashMap<>();
        for (Long userId : userIds) {
            Integer score = 0;
            Integer browseTime = browseMap.get(userId);
            if (browseTime != null) {
                score = score + browseTime / 60;
            }
            Double buyAmount = buyMap.get(userId);
            if (buyAmount != null) {
                BigDecimal bd = new BigDecimal(buyAmount).setScale(0, BigDecimal.ROUND_HALF_UP);
                score = score + Integer.parseInt(bd.toString());
            }
            scoreMap.put(userId, score);
        }
        List<LearningScoreDTO> learningScoreDTOS = new ArrayList<>();
        for (Long userId : userIds) {
            Integer score = scoreMap.get(userId);
            LearningScoreDTO learningScoreDTO = new LearningScoreDTO();
            learningScoreDTO.setWechatUserId(userId);
            learningScoreDTO.setScore(score);
            learningScoreDTOS.add(learningScoreDTO);
        }
        learningScoreDTOS = learningScoreDTOS.stream().filter(s -> s.getScore() != null && s.getScore() > 0).sorted(Comparator.comparingInt(LearningScoreDTO::getScore).reversed()).collect(Collectors.toList());
        return learningScoreDTOS;
    }

    @ParamLog("获取微信用户元气值")
    @Override
    public LearningScoreDTO getUserLearningSore(Long qrcodeId, Long wechatUserId) {
        //获取浏览记录
        GroupBrowseDTO groupBrowseDTO = wechatGroupAnConsr.getGroupBrowseForOne(qrcodeId, wechatUserId);
        LearningScoreDTO learningScoreDTO = new LearningScoreDTO();
        learningScoreDTO.setWechatUserId(wechatUserId);
        //计算
        Integer score = 0;
        if (groupBrowseDTO != null) {
            Integer browseTime = groupBrowseDTO.getAllBrowseTimes();
            learningScoreDTO.setAllLearningTime(browseTime);
            if (browseTime != null) {
                score = score + browseTime / 60;
            }
        }
        //交易内部接口获取购买情况
        BigDecimal buyAmount = tradeConsr.getAmountByQrcodeId(qrcodeId,wechatUserId);
        if (buyAmount != null) {
            BigDecimal bd = buyAmount.setScale(0, BigDecimal.ROUND_HALF_UP);
            score = score + Integer.parseInt(bd.toString());
        }
        learningScoreDTO.setScore(score);
        WechatUser wechatUser = readerConsr.getWechatUser(wechatUserId);
        if (wechatUser != null) {
            learningScoreDTO.setNickName(wechatUser.getWechatUserNickname());
            learningScoreDTO.setHeadUrl(wechatUser.getWechatUserHeadurl());
        }
        return learningScoreDTO;
    }

    @ParamLog("获取微信用户榜单")
    @Override
    public UserLearningInfoDTO getUserLearningInfo(Long qrcodeId, Long wechatUserId, String qrcodeUrlS) {
        if (wechatUserId == null || qrcodeId == null || StringUtil.isEmpty(qrcodeUrlS)) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "参数错误！");
        }
        UserLearningInfoDTO userLearningInfoDTO = new UserLearningInfoDTO();
        String qrcodeUrl=QrcodeUtils.create(UrlUtils.getShortUrl4Own(qrcodeUrlS));
        userLearningInfoDTO.setQrcodeUrl(qrcodeUrl);
        LearningScoreDTO learningScoreDTO = getUserLearningSore(qrcodeId, wechatUserId);
        if (learningScoreDTO != null) {
            userLearningInfoDTO.setAllLearningTime(learningScoreDTO.getAllLearningTime());
            userLearningInfoDTO.setHeadUrl(learningScoreDTO.getHeadUrl());
            userLearningInfoDTO.setNickName(learningScoreDTO.getNickName());
            userLearningInfoDTO.setScore(learningScoreDTO.getScore());
            userLearningInfoDTO.setWechatUserId(wechatUserId);
        }
        Integer userNum = 0;
        GroupQrcode groupQrcode = groupQrcodeDao.getById(qrcodeId);
        if (groupQrcode != null) {
            userNum = groupQrcode.getUserNumber();
        }
        List<LearningScoreDTO> learningScoreDTOSortList = getLearningScoreDTOSortList(qrcodeId);
        Integer groupSort = learningScoreDTOSortList.size() + 1;
        if (!ListUtils.isEmpty(learningScoreDTOSortList)) {
            for (int i = 0; i < learningScoreDTOSortList.size(); i++) {
                if (wechatUserId.equals(learningScoreDTOSortList.get(i).getWechatUserId())) {
                    groupSort = i + 1;
                }
            }
        }
        userLearningInfoDTO.setGroupSort(groupSort);
        Double exceedPercent = 1.00D;
        if (userNum != null && userNum > 0) {
            exceedPercent = (userNum - groupSort) / userNum.doubleValue();
        }
        userLearningInfoDTO.setExceedPercent(exceedPercent);
        return userLearningInfoDTO;
    }
}
