package com.pcloud.book.group.set;

import com.pcloud.analysisengine.browse.dto.GroupBrowseStatisticVO;
import com.pcloud.appcenter.assist.dto.AssistTempletDTO;
import com.pcloud.book.consumer.analysisengine.BrowseRecordConsr;
import com.pcloud.book.consumer.app.AssistTempletConsr;
import com.pcloud.book.consumer.common.ExportConsr;
import com.pcloud.book.consumer.trade.TradeConsr;
import com.pcloud.book.consumer.user.AdviserConsr;
import com.pcloud.book.consumer.user.ChannelConsr;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.group.dao.BookGroupCipherUserDao;
import com.pcloud.book.group.dao.BookGroupClassifyDao;
import com.pcloud.book.group.dto.BookGroupStatisticDTO;
import com.pcloud.book.group.dto.GroupTopicDTO;
import com.pcloud.book.group.vo.BookGroupAnalysisVO;
import com.pcloud.book.keywords.dao.BookKeywordDao;
import com.pcloud.book.keywords.dto.KeywordResourceDTO;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.core.constant.MQTopicProducer;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.facade.tradecenter.dto.ProductSaleDetailDto;
import com.pcloud.usercenter.party.adviser.dto.AdviserBaseInfoDto;
import com.pcloud.wechatgroup.group.dto.GroupUserCountDTO;

import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @描述：
 * @作者：zhuyajie
 * @创建时间：16:26 2019/7/16
 * @版本：1.0
 */
@Component("groupSet")
public class GroupSet {

    private static final Logger LOGGER = LoggerFactory.getLogger(GroupSet.class);

    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private AssistTempletConsr assistTempletConsr;
    @Autowired
    private AdviserConsr adviserConsr;
    @Autowired
    private ChannelConsr channelConsr;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private BookGroupClassifyDao bookGroupClassifyDao;
    @Autowired
    private BookKeywordDao bookKeywordDao;
    @Autowired
    private ExportConsr exportConsr;
    @Autowired
    private TradeConsr tradeConsr;
    @Autowired
    private BookGroupCipherUserDao bookGroupCipherUserDao;
    @Autowired
    private BrowseRecordConsr browseRecordConsr;

    /**
     * 群分类删除topic
     * @param classifyId
     */
    public void sendGroupClassifyDeleteTopic(Long classifyId) {
        LOGGER.info("【社群书】发送群分类删除topic,<START>classifyId:{}", classifyId);
        GroupTopicDTO groupTopicDTO = new GroupTopicDTO();
        groupTopicDTO.setClassifyId(classifyId);
        try {
            amqpTemplate.convertAndSend(MQTopicProducer.EXCHAGE, MQTopicProducer.GROUP_CLASSIFY_DELETE, groupTopicDTO);
        } catch (Exception e) {
            LOGGER.error("【社群书】发送群分类删除topic,<ERROR>", e);
        }
    }

    /**
     * 设置书刊分类名称
     * @param recordList
     */
    @ParamLog("设置书刊分类名称")
    public void setTempletName(List<BookGroupAnalysisVO> recordList) {
        if (ListUtils.isEmpty(recordList)) {
            return;
        }
        List<Long> templetIds = new ArrayList<>();
        recordList.forEach(bookGroupAnalysisVO -> {
            if (Objects.nonNull(bookGroupAnalysisVO.getTempletId())) {
                templetIds.add(bookGroupAnalysisVO.getTempletId());
            }
            if (Objects.nonNull(bookGroupAnalysisVO.getSecondTempletId())) {
                templetIds.add(bookGroupAnalysisVO.getSecondTempletId());
            }
        });
        final Map<Long, AssistTempletDTO> assistTempletIds = assistTempletConsr.mapByIds(templetIds);
        if (MapUtils.isEmpty(assistTempletIds)) {
            return;
        }
        recordList.forEach(analysisVO -> {
            Long secondTempletId = analysisVO.getSecondTempletId();
            Long templetId = analysisVO.getTempletId();
            if (Objects.nonNull(secondTempletId)) {
                AssistTempletDTO templetDTO = assistTempletIds.get(secondTempletId);
                analysisVO.setSecondTempletName(Optional.ofNullable(templetDTO).map(AssistTempletDTO::getTempletName).orElse(null));
            }
            if (Objects.nonNull(templetId)) {
                AssistTempletDTO templetDTO = assistTempletIds.get(templetId);
                analysisVO.setTempletName(Optional.ofNullable(templetDTO).map(AssistTempletDTO::getTempletName).orElse(null));
            }
        });
    }


    /**
     * 设置出版运营编辑名称
     * @param recordList
     */
    @ParamLog("设置出版运营编辑名称")
    public void setPartyInfo(List<BookGroupAnalysisVO> recordList) {
        if (ListUtils.isEmpty(recordList)) {
            return;
        }
        List<Long> adviserIds = recordList.stream().filter(s -> s.getAdviserId() != null).map(BookGroupAnalysisVO::getAdviserId).distinct().collect(Collectors.toList());
        List<Long> channelIds = recordList.stream().filter(s -> s.getChannelId() != null).map(BookGroupAnalysisVO::getChannelId).distinct().collect(Collectors.toList());
        Map<Long, AdviserBaseInfoDto> adviserBaseInfoDtoMap = adviserConsr.getAdviserId2AdviserInfoDtoMap(adviserIds);
        Map<Long, String> channelNameMap = channelConsr.getNamesByIdList(channelIds);
        recordList.forEach(bookGroupAnalysisVO -> {
            if (!MapUtils.isEmpty(adviserBaseInfoDtoMap) && adviserBaseInfoDtoMap.containsKey(bookGroupAnalysisVO.getAdviserId())) {
                AdviserBaseInfoDto adviserBaseInfoDto = adviserBaseInfoDtoMap.get(bookGroupAnalysisVO.getAdviserId());
                if (null != adviserBaseInfoDto) {
                    bookGroupAnalysisVO.setAdviserName(adviserBaseInfoDto.getPartyName());
                    bookGroupAnalysisVO.setAgentId(adviserBaseInfoDto.getAgentId());
                    bookGroupAnalysisVO.setAgentName(adviserBaseInfoDto.getAgentName());
                }
            }
            if (!MapUtils.isEmpty(channelNameMap) && channelNameMap.containsKey(bookGroupAnalysisVO.getChannelId())) {
                bookGroupAnalysisVO.setChannelName(channelNameMap.get(bookGroupAnalysisVO.getChannelId()));
            }
        });
    }

    /**
     * 设置社群码扫码量
     * @param recordList
     * @param monthDate
     */
    @ParamLog("设置社群码扫码量")
    public void setGroupScanCount(List<BookGroupAnalysisVO> recordList, String monthDate) {
        if (ListUtils.isEmpty(recordList)) {
            return;
        }
        List<Long> bookGroupIds = recordList.stream().filter(s -> s.getBookGroupId() != null).map(BookGroupAnalysisVO::getBookGroupId).distinct().collect(Collectors.toList());
        Map<Long, GroupUserCountDTO> userCountDTOMap = wechatGroupConsr.getScanCountByGroup(bookGroupIds, monthDate);
        if (MapUtils.isEmpty(userCountDTOMap)) {
            return;
        }
        recordList.forEach(bookGroupAnalysisVO -> {
            GroupUserCountDTO groupUserCountDTO = userCountDTOMap.get(bookGroupAnalysisVO.getBookGroupId());
            if (null != groupUserCountDTO) {
                bookGroupAnalysisVO.setScanCount(groupUserCountDTO.getCount());
                bookGroupAnalysisVO.setScanUserCount(groupUserCountDTO.getUserCount());
            }
        });
    }

    /**
     * 设置微信群数据（分类数，群数，群人数，累计进群人数，好友数，资源数）
     * @param recordList
     * @param monthDate
     */
    public void setGroupStatistic(List<BookGroupAnalysisVO> recordList, String monthDate) {
        if (ListUtils.isEmpty(recordList)) {
            return;
        }
        List<Long> bookGroupIds = recordList.stream().filter(s -> s.getBookGroupId() != null).map(BookGroupAnalysisVO::getBookGroupId).distinct().collect(Collectors.toList());
        if (ListUtils.isEmpty(bookGroupIds)) {
            return;
        }
        String startTime = null;
        String endTime = null;
        if (!StringUtil.isEmpty(monthDate)) {
            startTime = monthDate + "-01";
            endTime = DateUtils.formatDate(DateUtils.getMonthEnd(DateUtils.getDateByStr(startTime)), DateUtils.DATE_FORMAT_DATEONLY);
        }
        //分类数，群数，群人数
        Map<Long, BookGroupStatisticDTO> bookGroupStatisticDTOMap = bookGroupClassifyDao.getBookGroupStatistic(bookGroupIds);
        //社群码下资源数量（关键词及1v1配置资源）
        Map<Long, KeywordResourceDTO> keywordResourceDTOMap = bookKeywordDao.getBookGroupResourceCount(bookGroupIds);
        //累计进群人数-按月
        Map<Long, GroupUserCountDTO> userCountDTOMap = wechatGroupConsr.mapBookGroupJoinUserCount(bookGroupIds, monthDate);
        for (BookGroupAnalysisVO bookGroupAnalysisVO : recordList) {
            if (!MapUtils.isEmpty(bookGroupStatisticDTOMap)) {
                BookGroupStatisticDTO bookGroupStatisticDTO = bookGroupStatisticDTOMap.get(bookGroupAnalysisVO.getBookGroupId());
                if (null != bookGroupStatisticDTO) {
                    bookGroupAnalysisVO.setClassifyCount(bookGroupStatisticDTO.getClassifyCount());
                    bookGroupAnalysisVO.setGroupCount(bookGroupStatisticDTO.getGroupNumber());
                    bookGroupAnalysisVO.setUserNumber(bookGroupStatisticDTO.getUserNumber());
                }
            }
            if (!MapUtils.isEmpty(keywordResourceDTOMap)) {
                KeywordResourceDTO resourceDTO = keywordResourceDTOMap.get(bookGroupAnalysisVO.getBookGroupId());
                if (null != resourceDTO) {
                    bookGroupAnalysisVO.setResourceCount(resourceDTO.getCount());
                }
            }
            if (!MapUtils.isEmpty(userCountDTOMap)) {
                GroupUserCountDTO userCountDTO = userCountDTOMap.get(bookGroupAnalysisVO.getBookGroupId());
                bookGroupAnalysisVO.setJoinUserCount(null == userCountDTO ? 0 : userCountDTO.getUserCount());
            }
            //好友数量-按月
            Integer friendsCount = bookGroupCipherUserDao.getFriendsCountByBookGroupByTime(bookGroupAnalysisVO.getBookGroupId(), startTime, endTime);
            bookGroupAnalysisVO.setFriendsCount(friendsCount);
        }
    }

    /**
     * 设置资源数据(浏览量，读者量，销售额，支付率，客单价)
     * @param recordList
     * @param monthDate
     */
    public void setResourceStatistic(List<BookGroupAnalysisVO> recordList, String monthDate) {
        List<Long> bookGroupIds = recordList.stream().filter(s -> s.getBookGroupId() != null).map(BookGroupAnalysisVO::getBookGroupId).distinct().collect(Collectors.toList());
        if (ListUtils.isEmpty(bookGroupIds)) {
            return;
        }
        Map<Long, GroupBrowseStatisticVO> browseStatisticVOMap = browseRecordConsr.mapGroupBrowseStatistic(bookGroupIds,monthDate);
        Map<Long, ProductSaleDetailDto> saleDetailDtoMap = tradeConsr.getSaleInfo4Group(bookGroupIds, monthDate);
        for (BookGroupAnalysisVO bookGroupAnalysisVO : recordList) {
            Integer browserCount = 0;//读者量
            Long payCount = 0L;//购买人数
            //浏览量，读者量
            if (!MapUtils.isEmpty(browseStatisticVOMap)) {
                GroupBrowseStatisticVO statisticVO = browseStatisticVOMap.get(bookGroupAnalysisVO.getBookGroupId());
                bookGroupAnalysisVO.setBrowseCount(null == statisticVO ? 0 : statisticVO.getBrowseCount());
                browserCount = null == statisticVO ? 0 : statisticVO.getBrowserCount();
                bookGroupAnalysisVO.setBrowserCount(browserCount);
            }
            //销售额，客单价
            if (!MapUtils.isEmpty(saleDetailDtoMap)) {
                ProductSaleDetailDto saleDetailDto = saleDetailDtoMap.get(bookGroupAnalysisVO.getBookGroupId());
                payCount = (null == saleDetailDto || null == saleDetailDto.getPayCount()) ? 0L : saleDetailDto.getPayCount();
                //销售额
                BigDecimal saleMoney = (null == saleDetailDto || null == saleDetailDto.getSaleMoney()) ? BigDecimal.ZERO : BigDecimal.valueOf(saleDetailDto.getSaleMoney());
                //购买次数
                Long saleCount = (null == saleDetailDto || null == saleDetailDto.getSaleCount()) ? 0L : saleDetailDto.getSaleCount();
                BigDecimal avgSaleAmount = saleCount.equals(0L) ? BigDecimal.ZERO : new BigDecimal(saleMoney.doubleValue() / saleCount).
                        setScale(2, BigDecimal.ROUND_HALF_UP);
                bookGroupAnalysisVO.setSaleAmount(saleMoney);
                bookGroupAnalysisVO.setAvgSaleAmount(avgSaleAmount);
            }
            //支付率(支付人数/读者量)
            bookGroupAnalysisVO.setPayRate(browserCount.equals(0) ? BigDecimal.ZERO : new BigDecimal(payCount.doubleValue() / browserCount).
                    setScale(4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));
        }
    }

    /**
     * 社群书分析-导出表格
     * @param list
     * @param fileName
     * @return
     */
    public String fillBookGroupExcel(List<BookGroupAnalysisVO> list, String fileName) {
        String[] rowsName = {"序号", "图书名称", "ISBN", "书刊分类", "创建时间", "出版社名称", "运营平台", "编辑名称", "是否基金书", "扫码次数", "扫码人数",
                "获取资源方式", "群分类数", "添加客服好友数", "微信群数", "累计进群人数", "资源数", "浏览量", "读者量", "支付率", "销售额", "客单价", "是否版权保护", "社群码"};
        List<Object[]> dataList = new ArrayList<>();
        Object[] objs;
        for (int i = 0; i < list.size(); i++) {
            BookGroupAnalysisVO analysisVO = list.get(i);
            objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = analysisVO.getBookName();
            objs[2] = analysisVO.getIsbn();
            String templetName = "";
            if (!StringUtil.isEmpty(analysisVO.getTempletName())) {
                templetName = analysisVO.getTempletName();
                if (!StringUtil.isEmpty(analysisVO.getSecondTempletName())) {
                    templetName = templetName + "-" + analysisVO.getSecondTempletName();
                }
            } else if (!StringUtil.isEmpty(analysisVO.getSecondTempletName())) {
                templetName = analysisVO.getSecondTempletName();
            }
            objs[3] = templetName;
            objs[4] = DateUtils.formatDate(analysisVO.getCreateTime(), DateUtils.DATE_FORMAT_DATETIME);
            objs[5] = analysisVO.getAgentName();
            objs[6] = analysisVO.getChannelName();
            objs[7] = analysisVO.getAdviserName();
            objs[8] = analysisVO.getIsFundSupport() ? "是" : "否";
            objs[9] = analysisVO.getScanCount() == null ? 0 : analysisVO.getScanCount();
            objs[10] = analysisVO.getScanUserCount() == null ? 0 : analysisVO.getScanUserCount();
            objs[11] = analysisVO.getJoinGroupType() == 2 ? "1V1客服机器人" : "普通微信群";
            objs[12] = analysisVO.getClassifyCount() == null ? 0 : analysisVO.getClassifyCount();
            objs[13] = analysisVO.getFriendsCount() == null ? 0 : analysisVO.getFriendsCount();
            objs[14] = analysisVO.getGroupCount() == null ? 0 : analysisVO.getGroupCount();
            objs[15] = analysisVO.getJoinUserCount() == null ? 0 : analysisVO.getJoinUserCount();
            objs[16] = analysisVO.getResourceCount() == null ? 0 : analysisVO.getResourceCount();
            objs[17] = analysisVO.getBrowseCount() == null ? 0 : analysisVO.getBrowseCount();
            objs[18] = analysisVO.getBrowserCount() == null ? 0 : analysisVO.getBrowserCount();
            objs[19] = analysisVO.getPayRate() + "%";
            objs[20] = analysisVO.getSaleAmount();
            objs[21] = analysisVO.getAvgSaleAmount();
            objs[22] = analysisVO.getIsCopyright() ? "是" : "否";
            objs[23] = analysisVO.getGroupQrcodeUrl().replace("oss.5rs.me", "file.5rs.me");
            dataList.add(objs);
        }
        String fileUrl = exportConsr.exportExcel(fileName, rowsName, dataList);
        return fileUrl;
    }
}
