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

import com.google.common.collect.Lists;
import com.pcloud.appcenter.app.dto.AppDto;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.clock.biz.BookClockKeywordBiz;
import com.pcloud.book.clock.dao.BookClockInfoDao;
import com.pcloud.book.clock.dao.BookClockKeywordDao;
import com.pcloud.book.clock.dao.BookGroupClockDao;
import com.pcloud.book.clock.dto.*;

import com.pcloud.book.clock.eneity.BookClockKeywordCheckParam;
import com.pcloud.book.clock.eneity.CancelSelectedParam;
import com.pcloud.book.clock.enums.OriginTypeEnum;
import com.pcloud.book.clock.set.BookGroupClockSet;
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.wechatgroup.WechatGroupConsr;
import com.pcloud.book.group.biz.BookGroupClassifyBiz;
import com.pcloud.book.group.biz.impl.BookGroupClassifyBizImpl;
import com.pcloud.book.group.dao.BookGroupClassifyDao;
import com.pcloud.book.group.dao.BookGroupDao;
import com.pcloud.book.group.dto.BookGroupDTO;
import com.pcloud.book.group.dto.ClassifyDTO;
import com.pcloud.book.mq.producer.BookMQProducer;
import com.pcloud.book.util.common.CommonUtils;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.page.PageBean;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.resourcecenter.product.dto.ProductDto;
import org.apache.commons.collections4.SetUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

/**
 * @Author: hzk
 * @Date: 2019/5/24 14:50
 * @Version 1.0
 */
@Component("bookClockKeywordBiz")
public class BookClockKeywordBizImpl implements BookClockKeywordBiz {

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

    @Autowired
    private BookClockKeywordDao bookClockKeywordDao;
    @Autowired
    private BookGroupClockDao bookGroupClockDao;
    @Autowired
    private BookGroupDao bookGroupDao;
    @Autowired
    private BookGroupClassifyDao bookGroupClassifyDao;
    @Autowired
    private BookGroupClockSet bookGroupClockSet;
    @Autowired
    private BookGroupClassifyBiz bookGroupClassifyBiz;
    @Autowired
    private BookClockInfoDao bookClockInfoDao;
    @Autowired
    private BookMQProducer bookMQProducer;
    @Autowired
    private AppConsr appConsr;
    @Autowired
    private ProductConsr productConsr;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private ReaderConsr readerConsr;



    /**
     * 获取该关键词已关联的书及分类
     * @param bookClockKeywordCheckParam
     * @return
     */
    @Override
    @ParamLog("获取该关键词已关联的书及分类")
    public BookClockKeywordDTO getKeywordBookClockList(BookClockKeywordCheckParam bookClockKeywordCheckParam) {
        Long adviserId = bookClockKeywordCheckParam.getAdviserId();
        String keyword = bookClockKeywordCheckParam.getKeyword();
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("adviserId",adviserId);
        paramMap.put("keyword",keyword);
        List<Long> bookClockInfoIdList = bookClockKeywordDao.getInfoIdByKeyword(paramMap);
        if(ListUtils.isEmpty(bookClockInfoIdList)){
            return new BookClockKeywordDTO();
        }
        Long bookClockInfoId = bookClockKeywordCheckParam.getBookClockInfoId();
        if(null != bookClockInfoId){
            bookClockInfoIdList.remove(bookClockInfoId);
        }
        if(ListUtils.isEmpty(bookClockInfoIdList)){
            return new BookClockKeywordDTO();
        }
        //关联的社群码
        BookClockKeywordDTO bookClockKeywordDTO = new BookClockKeywordDTO();
        BookClockInfoDTO bookClockInfoDTO = bookGroupClockSet.getGroupAndClassifyListByInfoIds(bookClockInfoIdList);
        if(null == bookClockInfoDTO){
            return bookClockKeywordDTO;
        }
        //判断关键词对应的书及分类与选取的书及分类有无重复
        Set<Long> bookGroupIdSet = new HashSet<>();
        Set<Long> classifyIdSet = new HashSet<>();
        List<Long> oldBookGroupIdList = bookClockInfoDTO.getBookGroupIdList();
        List<Long> oldClassifyIdList = bookClockInfoDTO.getClassifyIdList();
        List<Long> newBookGroupIdList = bookClockKeywordCheckParam.getBookGroupIdList();
        List<Long> newClassifyIdList = bookClockKeywordCheckParam.getClassifyIdList();
        //校验书,分类有无重复
        List<Long> sameBookGroupIds = CommonUtils.getSameEle(oldBookGroupIdList, newBookGroupIdList);
        if(!ListUtils.isEmpty(sameBookGroupIds)){
            bookGroupIdSet.addAll(sameBookGroupIds);
        }
        List<Long> sameClassifyIds = CommonUtils.getSameEle(oldClassifyIdList, newClassifyIdList);
        if(!ListUtils.isEmpty(sameClassifyIds)){
            classifyIdSet.addAll(sameClassifyIds);
        }
        //校验旧书与新分类有无重复
        List<Long> bookGroupIdContainClassify = bookGroupClockSet.getSameClassifyUnderBookGroup(oldBookGroupIdList, newClassifyIdList, true);
        if(!ListUtils.isEmpty(bookGroupIdContainClassify)){
            bookGroupIdSet.addAll(bookGroupIdContainClassify);
        }
        //校验新书与旧分类
        List<Long> sameClassifyUnderBookGroup = bookGroupClockSet.getSameClassifyUnderBookGroup(newBookGroupIdList, oldClassifyIdList, false);
        if(!ListUtils.isEmpty(sameClassifyUnderBookGroup)){
            classifyIdSet.addAll(sameClassifyUnderBookGroup);
        }
        List<Long> bookGroupIdList = new ArrayList<>();
        bookGroupIdList.addAll(bookGroupIdSet);
        List<Long> classifyIdList = new ArrayList<>();
        classifyIdList.addAll(classifyIdSet);
        if(!ListUtils.isEmpty(bookGroupIdList)){
            List<BookGroupDTO> bookGroupDTOS = bookGroupDao.getBookBaseInfoByIds(bookGroupIdList);
            bookClockKeywordDTO.setBookGroupDTOList(bookGroupDTOS);
        }
        if(!ListUtils.isEmpty(classifyIdList)){
            List<ClassifyDTO> classifyDTOS = bookGroupClassifyDao.getNameWithBookNameByIds(classifyIdList);
            bookClockKeywordDTO.setClassifyDTOList(classifyDTOS);
        }
        return bookClockKeywordDTO;
    }

    /**
     * 发送关键词信息
     * @param bookClockInfoDTO
     * @param userWxId
     * @return
     */
    @Override
    @ParamLog("为微信群打卡关键词，发送关键词信息")
    public Boolean sendKeywordMessage(BookClockInfoDTO bookClockInfoDTO, String userWxId, String wechatGroupId,
            String wxId) {
        //发送TOPIC进行相关操作
        Long originId = bookClockInfoDTO.getOriginId();
        String originType = bookClockInfoDTO.getOriginType();
        PushBookClockKeywordDTO pushBookClockKeywordDTO = new PushBookClockKeywordDTO();
        pushBookClockKeywordDTO.setOriginId(bookClockInfoDTO.getOriginId());
        pushBookClockKeywordDTO.setOriginType(bookClockInfoDTO.getOriginType());
        pushBookClockKeywordDTO.setUserWxId(userWxId);
        pushBookClockKeywordDTO.setOperation(bookClockInfoDTO.getOperation());
        pushBookClockKeywordDTO.setChannelId(bookClockInfoDTO.getChannelId());
        pushBookClockKeywordDTO.setWechatGroupId(wechatGroupId);
        pushBookClockKeywordDTO.setGroupQrcodeId(bookClockInfoDTO.getGroupQrcodeId());
        pushBookClockKeywordDTO.setBookGroupId(bookClockInfoDTO.getBookGroupId());
        pushBookClockKeywordDTO.setClassifyId(bookClockInfoDTO.getClassifyId());
        pushBookClockKeywordDTO.setAdviserId(bookClockInfoDTO.getCreateUser());
        pushBookClockKeywordDTO.setBookClockInfoId(bookClockInfoDTO.getBookClockInfoId());
        // 收发一体--20190716-HZK
        //String robotId = wechatGroupConsr.getRobotIdByGroupId(wechatGroupId);
        
        Long wechatUserId = readerConsr.getWechatUserId(userWxId, bookClockInfoDTO.getChannelId());
        pushBookClockKeywordDTO.setWechatUserId(wechatUserId);
        pushBookClockKeywordDTO.setRobotId(wxId);
        if(OriginTypeEnum.APP.value.equalsIgnoreCase(originType)){
            AppDto appDto = appConsr.getBaseById(originId);
            if(null == appDto){
                throw new BookBizException(BookBizException.ERROR,"该应用不存在！");
            }
            pushBookClockKeywordDTO.setTypeCode(appDto.getTypeCode());
        }
        if(OriginTypeEnum.PRODUCT.value.equalsIgnoreCase(originType)){
            ProductDto productDto = productConsr.getProBaseById(originId);
            if(null == productDto){
                throw new BookBizException(BookBizException.ERROR,"该作品不存在！");
            }
            pushBookClockKeywordDTO.setTypeCode(productDto.getProductTypeDto().getTypeCode());
        }
        LOGGER.info("为微信群打卡关键词，发送关键词信息TOPIC,pushBookClockKeywordDTO="+pushBookClockKeywordDTO);
        bookMQProducer.pushBookClockKeyword(pushBookClockKeywordDTO);
        return true;
    }

    /**
     * 获取微信群某一动作动作关键词
     * @param bookClockInfoId
     * @param operation
     * @return
     */
    @Override
    public BookGroupClockKeywordDTO getBookClockKeyword4Clock(Long bookClockInfoId, String operation) {
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("bookClockInfoId",bookClockInfoId);
        paramMap.put("operation",operation);
        return bookClockKeywordDao.getBookClockKeyword4Clock(paramMap);
    }

    /**
     * 获取重复的书及分类
     * @param bookClockKeywordCheckParam
     * @return
     */
    @Override
    @ParamLog("获取该关键词已关联的书及分类(分页)")
    public PageBean getKeywordBookClockList4HasSelected(BookClockKeywordCheckParam bookClockKeywordCheckParam) {
        Integer currentPage = bookClockKeywordCheckParam.getCurrentPage();
        Integer numPerPage = bookClockKeywordCheckParam.getNumPerPage();

        Long adviserId = bookClockKeywordCheckParam.getAdviserId();
        String keyword = bookClockKeywordCheckParam.getKeyword();
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("adviserId",adviserId);
        paramMap.put("keyword",keyword);
        List<Long> bookClockInfoIdList = bookClockKeywordDao.getInfoIdByKeyword(paramMap);
        if(ListUtils.isEmpty(bookClockInfoIdList)){
            return new PageBean();
        }

        Boolean isBookGroup = bookClockKeywordCheckParam.getIsBookGroup();
        List<Object> objectList = new ArrayList<>();
        List<Long> bookGroupIdList = new ArrayList<>();
        List<Long> classifyIdList = new ArrayList<>();
        List<Long> newBookGroupIdList = bookClockKeywordCheckParam.getBookGroupIdList();
        List<Long> newClassifyIdList = bookClockKeywordCheckParam.getClassifyIdList();
        Map<String,Object> idMap = new HashMap<>();
        for (Long bookClockInfoId:bookClockInfoIdList) {
            idMap.put("bookClockInfoId",bookClockInfoId);
            BookClockInfoDTO bookClockInfoDTO = bookClockInfoDao.getBaseInfoById(bookClockInfoId);
            //获取该作品下所有的书及分类
            List<BookGroupClockDTO> bookGroupClockDTOS = bookGroupClockDao.getInfoByInfoIds(Lists.newArrayList(bookClockInfoId));
            if(ListUtils.isEmpty(bookGroupClockDTOS)){
                continue;
            }
            if(isBookGroup){
                //与书校验(新书与旧书，新分类与旧书)
                List<Long> oldBookGroupIdList = bookGroupClockDTOS.stream().filter(bookGroupClockDTO -> 0 == bookGroupClockDTO.getClassifyId()).map(BookGroupClockDTO::getBookGroupId).collect(Collectors.toList());
                List<Long> sameEle4BookGroupIds = CommonUtils.getSameEle(oldBookGroupIdList, newBookGroupIdList);
                if(!ListUtils.isEmpty(sameEle4BookGroupIds)){
                    bookGroupIdList.addAll(sameEle4BookGroupIds);
                }
                //新分类与旧书
                List<Long> bookGroupId4SameClassifyList = bookGroupClockSet.getSameClassifyUnderBookGroup(oldBookGroupIdList, newClassifyIdList, true);
                if(!ListUtils.isEmpty(bookGroupId4SameClassifyList)){
                    bookGroupIdList.addAll(bookGroupId4SameClassifyList);
                }
                if(!ListUtils.isEmpty(bookGroupIdList)){
                    idMap.put("bookGroupIdList",bookGroupIdList);
                    List<BookGroupDTO> bookGroupDTOS = bookGroupDao.getBookInfoByIdsWithBookClockInfoId(idMap);
                    objectList.addAll(bookGroupDTOS);
                }
            }else{
                //与分类校验(新分类与旧分类，旧分类与新书)
                List<Long> oldClassifyIds = bookGroupClockDTOS.stream().filter(bookGroupClockDTO -> 0 == bookGroupClockDTO.getBookGroupId()).map(BookGroupClockDTO::getClassifyId).collect(Collectors.toList());
                List<Long> sameEle4ClassifyIds = CommonUtils.getSameEle(oldClassifyIds, newClassifyIdList);
                if(!ListUtils.isEmpty(sameEle4ClassifyIds)){
                    classifyIdList.addAll(sameEle4ClassifyIds);
                }
                //旧分类与新书
                List<Long> classifyIds4SameBookGroup = bookGroupClockSet.getSameClassifyUnderBookGroup(newBookGroupIdList, oldClassifyIds, false);
                if(!ListUtils.isEmpty(classifyIds4SameBookGroup)){
                    classifyIdList.addAll(classifyIds4SameBookGroup);
                }
                if(!ListUtils.isEmpty(classifyIdList)){
                    idMap.put("classifyIdList",classifyIdList);
                    List<ClassifyDTO> classifyDTOS = bookGroupClassifyDao.getNameWithBookClockInfoIdByIds(idMap);
                    objectList.addAll(classifyDTOS);
                }
            }
            bookGroupIdList.clear();
            classifyIdList.clear();
        }
        if(!ListUtils.isEmpty(objectList)){
            return new PageBean(currentPage,numPerPage,objectList.size(),objectList);
        }
        return new PageBean();
    }

    /**
     * 取消关联
     * @param cancelSelectedParam
     */
    @Override
    @ParamLog("取消关联")
    public void cancelSelected(CancelSelectedParam cancelSelectedParam) {
        Long bookClockInfoId = cancelSelectedParam.getBookClockInfoId();
        Long bookGroupId = cancelSelectedParam.getBookGroupId();
        Long classifyId = cancelSelectedParam.getClassifyId();
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("bookClockInfoId",bookClockInfoId);
        if(null != bookGroupId && 0 != bookGroupId){
            classifyId = 0L;
        }else{
            bookGroupId = 0L;
        }
        paramMap.put("bookGroupId",bookGroupId);
        paramMap.put("classifyId",classifyId);
        bookGroupClockDao.cancelSelected(paramMap);
    }
}
