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

import com.pcloud.book.applet.biz.AppletResourceApplyBiz;
import com.pcloud.book.applet.biz.AppletThirdResourcesBiz;
import com.pcloud.book.applet.contants.AppletConstants;
import com.pcloud.book.applet.contants.AppletResourceApplyConstants;
import com.pcloud.book.applet.dao.AppletLinkClickDao;
import com.pcloud.book.applet.dao.AppletNewsDao;
import com.pcloud.book.applet.dao.AppletThirdResourcesClickDao;
import com.pcloud.book.applet.dao.AppletThirdResourcesDao;
import com.pcloud.book.applet.dto.AddResourceApplyDTO;
import com.pcloud.book.applet.dto.AppletChartDateDTO;
import com.pcloud.book.applet.dto.AppletThirdResourcesDTO;
import com.pcloud.book.applet.dto.PvuvDTO;
import com.pcloud.book.applet.dto.ThirdResourceRecordDTO;
import com.pcloud.book.applet.entity.AppletThirdResources;
import com.pcloud.book.applet.entity.AppletThirdResourcesClick;
import com.pcloud.book.applet.entity.AppletThirdResourcesPic;
import com.pcloud.book.applet.enums.DataRecordTypeEnum;
import com.pcloud.book.applet.enums.DataTypeEnum;
import com.pcloud.book.applet.mapper.AppletThirdResourcesPicMapper;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.consumer.reader.ReaderConsr;
import com.pcloud.book.consumer.user.AdviserConsr;
import com.pcloud.book.group.biz.BizMaterialBiz;
import com.pcloud.book.group.enums.UseTypeEnum;
import com.pcloud.common.core.aspect.ParamLog;
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.cache.redis.JedisClusterUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.readercenter.wechat.entity.WechatUser;

import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service("appletThirdResourcesBiz")
public class AppletThirdResourcesBizImpl implements AppletThirdResourcesBiz {

    @Autowired
    private AppletThirdResourcesDao thirdResourcesDao;
    @Autowired
    private AppletLinkClickDao appletLinkClickDao;
    @Autowired
    private AppletThirdResourcesClickDao thirdResourcesClickDao;
    @Autowired
    private AppletNewsDao appletNewsDao;
    @Autowired
    private BizMaterialBiz bizMaterialBiz;
    @Autowired
    private ReaderConsr readerConsr;
    @Autowired
    private AdviserConsr adviserConsr;
    @Autowired
    private AppletThirdResourcesPicMapper appletThirdResourcesPicMapper;
    @Autowired
    private AppletResourceApplyBiz appletResourceApplyBiz;

    @Override
    public PageBeanNew<AppletThirdResourcesDTO> getListThirdResourcesAnalysis(String keyValue, String source,
            String resourcesType, Integer browseQty, Integer clickQty, Integer currentPage, Integer numPerPage) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("keyValue", keyValue);
        paramMap.put("source", source);
        paramMap.put("resourcesType", resourcesType);

        PageBeanNew<AppletThirdResourcesDTO> pageBeanNew = thirdResourcesDao.listPageNew(
                new PageParam(currentPage, numPerPage), paramMap, "getListThirdResourcesAnalysis");

        if (null == pageBeanNew || ListUtils.isEmpty(pageBeanNew.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
        }

        //填充浏览量点击量信息
        fillBrowseAndClickQty(pageBeanNew.getRecordList(), browseQty, clickQty);

        //填充配置点信息
        fillConfigPoint(pageBeanNew.getRecordList());

        return pageBeanNew;
    }

    private void fillConfigPoint(List<AppletThirdResourcesDTO> recordList) {
        if (ListUtils.isEmpty(recordList)) {
            return;
        }

        for (AppletThirdResourcesDTO dto : recordList) {
            if (dto != null && !StringUtil.isEmpty(dto.getNewsNumber())) {
                String[] points = dto.getNewsNumber().split(",");
                dto.setConfigPointList(points);
            }
        }
    }

    private void fillBrowseAndClickQty(List<AppletThirdResourcesDTO> recordList, Integer browseQty, Integer clickQty) {
        if (ListUtils.isEmpty(recordList)) {
            return;
        }
        if (null != browseQty && browseQty.intValue() > 1) {  //等于1 值查询当天数据。大于1时，从昨天开始倒推7天，所以要+1
            browseQty += 1;
        }
        if (null != clickQty && clickQty.intValue() > 1) {
            clickQty += 1;
        }
        List<Long> ids = recordList.stream().filter(s -> s != null).map(AppletThirdResourcesDTO::getId).distinct()
                .collect(Collectors.toList());
        Map<Long, PvuvDTO> clickMap = thirdResourcesClickDao
                .mapPVUV(DataTypeEnum.news.code, DataRecordTypeEnum.click.code, ids, clickQty);
        Map<Long, PvuvDTO> browseMap = thirdResourcesClickDao
                .mapPVUV(DataTypeEnum.news.code, DataRecordTypeEnum.browse.code, ids, browseQty);
        for (AppletThirdResourcesDTO dto : recordList) {
            Long thirdResourcesId = dto.getId();
            if (!MapUtils.isEmpty(clickMap) && clickMap.containsKey(thirdResourcesId)) {
                PvuvDTO pvuvDTO = clickMap.get(thirdResourcesId);
                dto.setClickPVUV(pvuvDTO.getPv() + "/" + pvuvDTO.getUv());
                dto.setClickCount(pvuvDTO.getPv());
            } else {
                dto.setClickPVUV("0/0");
                dto.setClickCount(0);
            }
            if (!MapUtils.isEmpty(browseMap) && browseMap.containsKey(thirdResourcesId)) {
                PvuvDTO pvuvDTO = browseMap.get(thirdResourcesId);
                dto.setBrowsePVUV(pvuvDTO.getPv() + "/" + pvuvDTO.getUv());
            } else {
                dto.setBrowsePVUV("0/0");
            }
        }
    }

    @Override
    public void addServiceRecord(AppletThirdResourcesClick thirdResourcesClick) {
        thirdResourcesClickDao.insert(thirdResourcesClick);
    }

    @Override
    public AppletThirdResourcesDTO getAnalysisDetail(Long thirdResourcesId) {
        AppletThirdResourcesDTO thirdResourcesDTO = new AppletThirdResourcesDTO();

        List<AppletChartDateDTO> checkList = thirdResourcesClickDao
                .mapPVUVByMonth(DataRecordTypeEnum.click.code, thirdResourcesId);
        List<AppletChartDateDTO> browseList = thirdResourcesClickDao
                .mapPVUVByMonth(DataRecordTypeEnum.browse.code, thirdResourcesId);

        thirdResourcesDTO.setClickList(checkList);
        thirdResourcesDTO.setBrowseList(browseList);

        return thirdResourcesDTO;
    }

    @Override
    public AppletThirdResourcesDTO getNewsTrendChart(Long newsId) {
        AppletThirdResourcesDTO thirdResourcesDTO = new AppletThirdResourcesDTO();

        List<AppletChartDateDTO> checkList = appletLinkClickDao
                .mapPVUVByMonth(DataTypeEnum.news.code, DataRecordTypeEnum.click.code, newsId);
        List<AppletChartDateDTO> browseList = appletLinkClickDao
                .mapPVUVByMonth(DataTypeEnum.news.code, DataRecordTypeEnum.browse.code, newsId);

        thirdResourcesDTO.setClickList(checkList);
        thirdResourcesDTO.setBrowseList(browseList);

        return thirdResourcesDTO;
    }

    @Override
    public PageBeanNew<AppletThirdResources> getThirdResources(Long type, String source, String keyValue,
            Integer currentPage, Integer numPerPage) {
        Map<String, Object> map = new HashMap<>();

        map.put("type", type);
        map.put("source", source);
        map.put("keyValue", keyValue);
        PageBeanNew<AppletThirdResources> pageBeanNew = thirdResourcesDao.listPageNew(new PageParam(currentPage, numPerPage), map, "getThirdResources");
        if (ListUtils.isEmpty(pageBeanNew.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, pageBeanNew.getTotalCount(), new ArrayList<>());
        }
        //推送图片类型
        List<Long> thirdResourceIds = pageBeanNew.getRecordList().stream().filter(s->s.getType()==2)
                .map(AppletThirdResources::getId).collect(Collectors.toList());
        if (!ListUtils.isEmpty(thirdResourceIds)) {
            List<AppletThirdResourcesPic> picList = appletThirdResourcesPicMapper.getPicListByResourceIds(thirdResourceIds);
            Map<Long, List<String>> picMap = picList.stream().collect(Collectors.groupingBy(AppletThirdResourcesPic::getThirdResourcesId,
                    Collectors.mapping(AppletThirdResourcesPic::getPicUrl, Collectors.toList())));
            if (!MapUtils.isEmpty(picMap)) {
                for (AppletThirdResources resources:pageBeanNew.getRecordList()) {
                    if (picMap.containsKey(resources.getId())) {
                        List<String> picUrlList = picMap.get(resources.getId());
                        resources.setPicUrlList(picUrlList);
                    }
                }
            }
        }
        return pageBeanNew;
    }

    @Override
    public void deleteAppletsById(Long id) {
        thirdResourcesDao.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateThirdResources(AppletThirdResourcesDTO thirdResourcesDTO) {
        AppletThirdResources thirdResources = new AppletThirdResources();
        if (thirdResourcesDTO.getType() == 2 && ListUtils.isEmpty(thirdResourcesDTO.getPicUrlList())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少推送图片");
        }
        Boolean exist = appletNewsDao.newsSourceExist(thirdResourcesDTO.getSource(),0L);
        if (!exist) {
            appletNewsDao.insertSource(thirdResourcesDTO.getSource(),0L);
        }

        if (!StringUtil.isEmpty(thirdResourcesDTO.getNumber())) {
            AppletThirdResources existThirdResources = thirdResourcesDao
                    .exitThirResources(thirdResourcesDTO.getNumber());
            if (existThirdResources != null && existThirdResources.getId() != null
                    && Long.compare(existThirdResources.getId(), thirdResourcesDTO.getId()) != 0) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "编号重复");
            }
        }

        // 链接发生变化，更新素材
        if (Objects.nonNull(thirdResourcesDTO.getRouteCode()) && thirdResourcesDTO.getRouteCode() == 1){
            AppletThirdResources byId = thirdResourcesDao.getById(thirdResourcesDTO.getId());
            boolean exists = bizMaterialBiz.materialExists(byId.getId(), UseTypeEnum.THIRD_GROUP.value);
            exists = !(exists && StrUtil.equals(byId.getUrl(), thirdResourcesDTO.getUrl()) && StrUtil.equals(byId.getName(), thirdResourcesDTO.getName()));
            if (exists){
                bizMaterialBiz.createMaterial4ThirdResource(thirdResourcesDTO.getName(), thirdResourcesDTO.getUrl(), Math.toIntExact(thirdResourcesDTO.getId()));
            }
        }

        BeanUtils.copyProperties(thirdResourcesDTO, thirdResources);
        thirdResourcesDao.update(thirdResources);
        //推送图片设置
        if (thirdResourcesDTO.getType() == 2) {
            addPicResources(thirdResourcesDTO.getId(), thirdResourcesDTO.getPicUrlList());
        }
        this.updateResourceApply(thirdResources.getId(), thirdResourcesDTO.getCrowdTypeList(), thirdResourcesDTO.getContentTypeList());
    }

    /**
     * 推送图片设置
     * @author：zhuyajie
     * @date：2021/3/10 19:08
     *  * @param null
     */
    private void addPicResources(Long thirdResourcesId, List<String> picList) {
        if (ListUtils.isEmpty(picList) || null == thirdResourcesId) {
            return;
        }
        appletThirdResourcesPicMapper.deleteByThirdResourcesId(thirdResourcesId);
        List<AppletThirdResourcesPic> pics = new ArrayList<>();
        for (String pic :picList) {
            AppletThirdResourcesPic resourcesPic = new AppletThirdResourcesPic();
            resourcesPic.setPicUrl(pic);
            resourcesPic.setThirdResourcesId(thirdResourcesId);
            pics.add(resourcesPic);
        }
        appletThirdResourcesPicMapper.batchInsert(pics);
    }

    @Override
    public AppletThirdResources getAppletsById(Long id) {
        AppletThirdResources appletThirdResources = thirdResourcesDao.getById(id);
        if (null == appletThirdResources) {
            return new AppletThirdResources();
        }
        appletThirdResources.setCrowdTypeList(appletResourceApplyBiz.getCrowdTypeList(id,
                AppletResourceApplyConstants.TargetTypeEnum.THIRD_RESOURCE.getValue()));
        appletThirdResources.setContentTypeList(appletResourceApplyBiz.getContentTypeList(id,
                AppletResourceApplyConstants.TargetTypeEnum.THIRD_RESOURCE.getValue()));
        return appletThirdResources;
    }

    @Override
    public List<AppletThirdResources> getAppletsByIds(List<Long> ids) {
        return thirdResourcesDao.getAppletsByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createThirdResources(AppletThirdResourcesDTO thirdResourcesDTO) {
        AppletThirdResources thirdResources = new AppletThirdResources();
        if (thirdResourcesDTO.getType() == 2 && ListUtils.isEmpty(thirdResourcesDTO.getPicUrlList())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少推送图片");
        }
        Boolean exist = appletNewsDao.newsSourceExist(thirdResourcesDTO.getSource(),0L);
        if (!exist) {
            appletNewsDao.insertSource(thirdResourcesDTO.getSource(),0L);
        }

        if (!StringUtil.isEmpty(thirdResourcesDTO.getNumber())) {
            AppletThirdResources existThirdResources = thirdResourcesDao
                    .exitThirResources(thirdResourcesDTO.getNumber());
            if (existThirdResources != null && existThirdResources.getId() != null) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "编号重复");
            }
        }

        BeanUtils.copyProperties(thirdResourcesDTO, thirdResources);
        thirdResourcesDao.insert(thirdResources);
        if (Objects.nonNull(thirdResourcesDTO.getRouteCode())&&thirdResourcesDTO.getRouteCode()==1&& StrUtil.isNotBlank(thirdResourcesDTO.getUrl())){
            bizMaterialBiz.createMaterial4ThirdResource(thirdResourcesDTO.getName(),thirdResourcesDTO.getUrl(), Math.toIntExact(thirdResources.getId()));
        }
        //推送图片设置
        if (thirdResourcesDTO.getType() == 2) {
            addPicResources(thirdResources.getId(), thirdResourcesDTO.getPicUrlList());
        }
        this.updateResourceApply(thirdResources.getId(), thirdResourcesDTO.getCrowdTypeList(), thirdResourcesDTO.getContentTypeList());
    }

    /**
     * 更新适用人群
     * @author：zhuyajie
     * @date：2021/5/8 16:02
     *  * @param null
     */
    private void updateResourceApply(Long id, List<Integer> crowdTypeList, List<Integer> contentTypeList) {
        AddResourceApplyDTO addResourceApplyDTO = new AddResourceApplyDTO();
        addResourceApplyDTO.setTargetId(id);
        addResourceApplyDTO.setTargetType(AppletResourceApplyConstants.TargetTypeEnum.THIRD_RESOURCE.getValue());
        addResourceApplyDTO.setCrowdTypeList(crowdTypeList);
        addResourceApplyDTO.setContentTypeList(contentTypeList);
        appletResourceApplyBiz.addResourceApply(addResourceApplyDTO);
    }

    @Override
    @ParamLog("第三方资源列表")
    public PageBeanNew<ThirdResourceRecordDTO> listThirdResourceRecord(String queryName, Integer currentPage, Integer numPerPage, String wechatUser, Long thirdResourceId, Integer recordType) {
        Map<String, Object> paramMap = new HashMap<>();
        if (!StringUtil.isEmpty(queryName)) {
            paramMap.put("queryName", queryName);
        }
        List<Long> wechatUserIds = null;
        if (!StringUtil.isEmpty(wechatUser)) {
            wechatUserIds = readerConsr.getWechatUserByNameOrId(wechatUser);
            if (ListUtils.isEmpty(wechatUserIds)) {
                return  new PageBeanNew<>(currentPage, numPerPage,new ArrayList<>());
            }
        }
        if (!ListUtils.isEmpty(wechatUserIds)) {
            paramMap.put("wechatUserIds", wechatUserIds);
        }
        if (null != recordType) {
            paramMap.put("recordType", recordType);
        }
        paramMap.put("thirdResourceId", thirdResourceId);
        PageBeanNew<ThirdResourceRecordDTO> pageBeanNew = thirdResourcesClickDao.listPageNew(new PageParam(currentPage, numPerPage), paramMap, "listThirdResourceRecord");
        if (null == pageBeanNew || ListUtils.isEmpty(pageBeanNew.getRecordList())) {
            return  new PageBeanNew<>(currentPage, numPerPage,new ArrayList<>());
        }
        List<ThirdResourceRecordDTO> recordList = pageBeanNew.getRecordList();
        List<Long> adviserIds = recordList.stream().map(e -> e.getAdviserId()).collect(Collectors.toList());
        List<Long> wechatUserIdList = recordList.stream().map(e -> e.getWechatUserId()).collect(Collectors.toList());
        Map<Long, String> adviserNameMap = new HashMap<>();
        Map<Long, WechatUser> userMap = new HashMap<>();
        if (!ListUtils.isEmpty(adviserIds)) {
            adviserNameMap = adviserConsr.getNames(adviserIds);
        }
        if (!ListUtils.isEmpty(wechatUserIdList)) {
            userMap = readerConsr.getUserList(wechatUserIdList);
        }
        for (ThirdResourceRecordDTO thirdResourceRecordDTO : recordList) {
            if (MapUtils.isNotEmpty(adviserNameMap) && null != adviserNameMap.get(thirdResourceRecordDTO.getAdviserId())) {
                thirdResourceRecordDTO.setAdviserName(adviserNameMap.get(thirdResourceRecordDTO.getAdviserId()));
            }
            if (MapUtils.isNotEmpty(userMap) && null != userMap.get(thirdResourceRecordDTO.getWechatUserId())) {
                thirdResourceRecordDTO.setWechatUserName(userMap.get(thirdResourceRecordDTO.getWechatUserId()).getWechatUserNickname());
                thirdResourceRecordDTO.setPhone(userMap.get(thirdResourceRecordDTO.getWechatUserId()).getPhoneNumber());
            }
        }
        return pageBeanNew;
    }

    @Override
    public Map<Long, AppletThirdResources> getAppletMapByIds(List<Long> list) {
        if (ListUtils.isEmpty(list)) {
            return new HashMap<>();
        }
        List<AppletThirdResources> appletsByIds = thirdResourcesDao.getAppletsByIds(list);
        if (ListUtils.isEmpty(appletsByIds)) {
            return new HashMap<>();
        }
        //推送图片类型
        setResourcesPic(appletsByIds);
        Map<Long, AppletThirdResources> appletThirdResourcesMap =
                appletsByIds.stream().collect(Collectors.toMap(e ->e.getId(), Function.identity(),(key1,key2) -> key2));
        return appletThirdResourcesMap;
    }

    private void setResourcesPic(List<AppletThirdResources> thirdResourcesList) {
        if (ListUtils.isEmpty(thirdResourcesList)) {
            return;
        }
        //推送图片类型
        List<Long> thirdResourceIds = thirdResourcesList.stream().filter(s -> s.getType() == 2)
                .map(AppletThirdResources::getId).collect(Collectors.toList());
        if (!ListUtils.isEmpty(thirdResourceIds)) {
            List<AppletThirdResourcesPic> picList = appletThirdResourcesPicMapper.getPicListByResourceIds(thirdResourceIds);
            Map<Long, List<String>> picMap = picList.stream().collect(Collectors.groupingBy(AppletThirdResourcesPic::getThirdResourcesId,
                    Collectors.mapping(AppletThirdResourcesPic::getPicUrl, Collectors.toList())));
            if (!MapUtils.isEmpty(picMap)) {
                for (AppletThirdResources resources : thirdResourcesList) {
                    if (picMap.containsKey(resources.getId())) {
                        List<String> picUrlList = picMap.get(resources.getId());
                        resources.setPicUrlList(picUrlList);
                    }
                }
            }
        }
    }
    @Override
    public List<AppletThirdResources> getThirdResourcesByNewsId(Long newsId) {
        return thirdResourcesDao.getThirdResourcesByNewsId(newsId);
    }

    @Override
    public PageBeanNew<AppletThirdResources> getThirdResourcesByGradeLabel4ResourcePage(Long gradeLabelId, Integer currentPage, Integer numPerPage) {
        String startDate = DateUtils.formatDate(DateUtils.addDay(new Date(), -7), DateUtils.DATE_FORMAT_DATEONLY);
        Integer crowdType = gradeLabelId.intValue();
        String key = AppletConstants.H5_THIRD_RESOURCE_REDIS+startDate;
        String field = gradeLabelId.toString();
        //前6条缓存中取
        if (currentPage == 0 && numPerPage == 6) {
            List<AppletThirdResources> resourcesList = JedisClusterUtils.hgetJson2List(key, field, AppletThirdResources.class);
            if (!ListUtils.isEmpty(resourcesList)) {
                Integer count = thirdResourcesDao.countResourceIdByGradeLabel(crowdType);
                return new PageBeanNew<>(currentPage, numPerPage, count, resourcesList);
            }
        }
        //根据标签查询，按照近7天浏览量排序
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("startDate", startDate);
        paramMap.put("crowdType", crowdType);
        PageBeanNew<Long> idPageBean = thirdResourcesDao.listPageNew(new PageParam(currentPage, numPerPage), paramMap, "listResourceIdByGradeLabelAndClickCount","countResourceIdByGradeLabel");
        if (ListUtils.isEmpty(idPageBean.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, idPageBean.getTotalCount(), new ArrayList<>());
        }
        //资源详情
        List<AppletThirdResources> thirdResources = thirdResourcesDao.getAppletsByIds(idPageBean.getRecordList());
        //推送图片类型
        setResourcesPic(thirdResources);
        if (currentPage == 0 && numPerPage == 6 && !ListUtils.isEmpty(thirdResources)) {
            JedisClusterUtils.hset2Json(key, field, thirdResources);
            JedisClusterUtils.expire(key, 2*60*60);
        }
        return new PageBeanNew<>(currentPage, numPerPage, idPageBean.getTotalCount(), thirdResources);
    }

}
