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

import com.pcloud.book.advertising.biz.LinkRevertBiz;
import com.pcloud.book.advertising.dao.AdvertisingBrandDao;
import com.pcloud.book.advertising.dao.AdvertisingGroupTagDao;
import com.pcloud.book.advertising.dao.AdvertisingLinkClickDao;
import com.pcloud.book.advertising.dao.AdvertisingLinkRevertDao;
import com.pcloud.book.advertising.dao.AdvertisingLinkSendDao;
import com.pcloud.book.advertising.dto.AdvertisingBrandDTO;
import com.pcloud.book.advertising.dto.LinkRevertRecordDTO;
import com.pcloud.book.advertising.entity.AdvertisingLinkClick;
import com.pcloud.book.advertising.entity.AdvertisingLinkRevert;
import com.pcloud.book.advertising.entity.AdvertisingLinkSend;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.consumer.common.ExportConsr;
import com.pcloud.book.consumer.message.MessageConsr;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.util.common.ThreadPoolUtils;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.core.constant.SystemCode;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.httpclient.UrlUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.wechatgroup.message.dto.LinkGroupParamDTO;

import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @描述：链接转换
 * @作者：zhuyajie
 * @创建时间：16:58 2019/10/10
 * @版本：1.0
 */
@Component("linkRevertBiz")
public class LinkRevertBizImpl implements LinkRevertBiz {

    @Value("${wechat.group.link.prefix}")
    private String wechatGroupLinkPrefix;
    @Autowired
    private AdvertisingLinkRevertDao advertisingLinkRevertDao;
    @Autowired
    private AdvertisingBrandDao advertisingBrandDao;
    @Autowired
    private ExportConsr exportConsr;
    @Autowired
    private MessageConsr messageConsr;
    @Autowired
    private AdvertisingLinkClickDao advertisingLinkClickDao;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private AdvertisingGroupTagDao advertisingGroupTagDao;
    @Autowired
    private AdvertisingLinkSendDao advertisingLinkSendDao;

    @Override
    public Long addRevertRecord(AdvertisingLinkRevert advertisingLinkRevert) {
        advertisingLinkRevertDao.insert(advertisingLinkRevert);
        Long id = advertisingLinkRevert.getId();
        String revertLink = wechatGroupLinkPrefix + "/linkRevert?link_id=" + id;
        String shortLink = UrlUtils.getShortUrl4Own(wechatGroupLinkPrefix + "/link?url=" + URLEncoder.encode(revertLink));
        if (StringUtil.isEmpty(shortLink)) {
            throw new BookBizException(BookBizException.ERROR, "短链接转换失败");
        }
        AdvertisingLinkRevert revert = new AdvertisingLinkRevert();
        revert.setId(id);
        revert.setRevertLink(revertLink);
        revert.setShortLink(shortLink);
        advertisingLinkRevertDao.update(revert);
        return id;
    }

    @Override
    public void deleteRevertRecordById(Long id) {
        advertisingLinkRevertDao.deleteById(id);
    }

    @Override
    public PageBeanNew<LinkRevertRecordDTO> listPageRevertRecord(Long brandId, Integer currentPage, Integer numPerPage) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("brandId", brandId);
        PageBeanNew<LinkRevertRecordDTO> pageBean = advertisingLinkRevertDao.listPageNew(new PageParam(currentPage, numPerPage), paramMap, "listRevertRecord");
        if (null == pageBean || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
        }
        List<LinkRevertRecordDTO> list = pageBean.getRecordList();
        //今日之前发送次数,因耗时不统计今天的20200106bug1019123
        List<Long> linkIds = list.stream().filter(s -> s.getLink() != null).map(LinkRevertRecordDTO::getId).distinct().collect(Collectors.toList());
        Map<Long, LinkRevertRecordDTO> sendCountMap = advertisingLinkSendDao.mapSendCount(linkIds);
        for (LinkRevertRecordDTO revertRecordDTO : list) {
            AdvertisingBrandDTO brandDTO = advertisingBrandDao.getBrandById(revertRecordDTO.getBrandId());
            revertRecordDTO.setBrandName(null == brandDTO ? "" : brandDTO.getBrandName());
            LinkRevertRecordDTO clickStatistic = advertisingLinkClickDao.getCountByLink(revertRecordDTO.getShortLink());
            revertRecordDTO.setClickCount(null == clickStatistic ? 0 : clickStatistic.getClickCount());
            revertRecordDTO.setClickUserCount(null == clickStatistic ? 0 : clickStatistic.getClickUserCount());
            Integer sendCount = 0;
            if (!MapUtils.isEmpty(sendCountMap) && sendCountMap.containsKey(revertRecordDTO.getId())) {
                sendCount = sendCountMap.get(revertRecordDTO.getId()).getSendCount();
            }
            revertRecordDTO.setSendCount(sendCount);
        }
        return pageBean;
    }

    @Override
    public void exportRevertRecordList(Long brandId, Long partyId) {
        List<LinkRevertRecordDTO> list = advertisingLinkRevertDao.listRevertRecord(brandId);
        if (ListUtils.isEmpty(list)) {
            return;
        }
        ThreadPoolUtils.EXPORT_THREAD_POOL.execute(() -> {
            String[] rowsName = {"序号", "品牌方", "外链", "短链", "链接发送次数", "浏览量", "浏览人数", "生成时间"};
            List<Object[]> dataList = new ArrayList<Object[]>();
            //今日之前发送次数
            List<Long> linkIds = list.stream().filter(s -> s.getLink() != null).map(LinkRevertRecordDTO::getId).distinct().collect(Collectors.toList());
            Map<Long, LinkRevertRecordDTO> sendCountMap = advertisingLinkSendDao.mapSendCount(linkIds);
            for (int i = 0, size = list.size(); i < size; i++) {
                LinkRevertRecordDTO revertRecordDTO = list.get(i);
                Object[] obj = new Object[rowsName.length];
                obj[0] = i + 1;
                AdvertisingBrandDTO brandDTO = advertisingBrandDao.getBrandById(revertRecordDTO.getBrandId());
                obj[1] = null == brandDTO ? "" : brandDTO.getBrandName();
                obj[2] = revertRecordDTO.getLink();
                obj[3] = revertRecordDTO.getShortLink();
                Integer sendCount = 0;
                if (!MapUtils.isEmpty(sendCountMap) && sendCountMap.containsKey(revertRecordDTO.getId())) {
                    sendCount = sendCountMap.get(revertRecordDTO.getId()).getSendCount();
                }

                obj[4] = sendCount;
                LinkRevertRecordDTO clickStatistic = advertisingLinkClickDao.getCountByLink(revertRecordDTO.getShortLink());
                obj[5] = null == clickStatistic ? 0 : clickStatistic.getClickCount();
                obj[6] = null == clickStatistic ? 0 : clickStatistic.getClickUserCount();
                obj[7] = DateUtils.formatDate(revertRecordDTO.getCreateTime(), DateUtils.DATE_FORMAT_DATETIME);
                dataList.add(obj);
            }
            String fileName = "外链转换统计-" + DateUtils.getStrFormTime("yyyyMMdd", new Date());
            String fileUrl = exportConsr.exportExcel(fileName, rowsName, dataList);
            String content = String.format("{\"commitTime\":\"%s\",\"type\":\"%s\"}", DateUtils.formatDate(new Date()), fileName);
            messageConsr.sendLetter(partyId, partyId, content, SystemCode.pcloud.code, "pcloud_book_download", fileUrl, fileName, null, null);
        });
    }

    @Override
    public void addClickRecord(AdvertisingLinkClick advertisingLinkClick) {
        advertisingLinkClickDao.insert(advertisingLinkClick);
    }

    @Override
    public AdvertisingLinkRevert getById(Long id) {
        return advertisingLinkRevertDao.getById(id);
    }

    @Override
    @ParamLog("统计昨日链接发送次数")
    public void addYesterdaySendStatistic() {
        new Thread() {
            @Override
            public void run() {
                List<AdvertisingLinkRevert> list = advertisingLinkRevertDao.getAll();
                if (ListUtils.isEmpty(list)) {
                    return;
                }
                List<Long> brandIds = list.stream().filter(s -> s.getBrandId() != null).map(AdvertisingLinkRevert::getBrandId).distinct().collect(Collectors.toList());
                Map<Long, List<String>> groupMap = new HashMap<>();
                for (Long brandId : brandIds) {
                    List<String> groupIds = advertisingGroupTagDao.getTagWxGroupIdsByBrandId(brandId);
                    groupMap.put(brandId, groupIds);
                }
                List<LinkGroupParamDTO> paramDTOS = new ArrayList<>();
                for (AdvertisingLinkRevert linkRevert : list) {
                    LinkGroupParamDTO paramDTO = new LinkGroupParamDTO();
                    paramDTO.setLink(linkRevert.getShortLink());
                    paramDTO.setWxGroupIds(groupMap.get(linkRevert.getBrandId()));
                    paramDTO.setDate(DateUtils.getYesterday());
                    paramDTOS.add(paramDTO);
                }
                Map<String, Integer> sendCountMap = wechatGroupConsr.getLinkSendCount(paramDTOS);
                List<AdvertisingLinkSend> sendList = new ArrayList<>();
                for (AdvertisingLinkRevert linkRevert : list) {
                    AdvertisingLinkSend linkSend = new AdvertisingLinkSend();
                    linkSend.setLinkId(linkRevert.getId());
                    Integer sendCount = 0;
                    if (!MapUtils.isEmpty(sendCountMap) && sendCountMap.containsKey(linkRevert.getShortLink())) {
                        sendCount = sendCountMap.get(linkRevert.getShortLink());
                    }
                    linkSend.setSendCount(sendCount);
                    linkSend.setCreateTime(new Date());
                    linkSend.setStatisticDate(DateUtils.addDay(new Date(), -1));
                    sendList.add(linkSend);
                }
                advertisingLinkSendDao.insert(sendList);
            }
        }.start();
    }

    @Override
    public void updateLinkBrandData(AdvertisingLinkRevert linkRevert) {
        advertisingLinkRevertDao.updateLinkBrandData(linkRevert);
    }

}
