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

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.pcloud.book.base.enums.BookStatusEnum;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.biz.BookBiz;
import com.pcloud.book.book.dto.BookDto;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.common.ExportConsr;
import com.pcloud.book.consumer.user.PartyConsr;
import com.pcloud.book.copyright.biz.BookAuthCodeBiz;
import com.pcloud.book.copyright.biz.BookAuthInfoBiz;
import com.pcloud.book.copyright.biz.BookAuthServeBiz;
import com.pcloud.book.copyright.biz.BookAuthUserBiz;
import com.pcloud.book.copyright.biz.BookExportRecordBiz;
import com.pcloud.book.copyright.constants.CopyrightConstants;
import com.pcloud.book.copyright.dao.BookAuthCodeDao;
import com.pcloud.book.copyright.dao.BookAuthInfoDao;
import com.pcloud.book.copyright.dao.BookAuthUserDao;
import com.pcloud.book.copyright.dao.BookClickBuyRecordDao;
import com.pcloud.book.copyright.dto.BookAuthInfoCountDTO;
import com.pcloud.book.copyright.dto.BookAuthTotalCountDTO;
import com.pcloud.book.copyright.dto.HaveUsedAuthCode;
import com.pcloud.book.copyright.entity.BookAuthCode;
import com.pcloud.book.copyright.entity.BookAuthInfo;
import com.pcloud.book.copyright.entity.BookExportRecord;
import com.pcloud.book.copyright.enums.AuthBookTypeEnum;
import com.pcloud.book.copyright.tools.CopyrightTools;
import com.pcloud.book.copyright.vo.AuthOpenVO;
import com.pcloud.book.copyright.vo.BookAuthCodeUserVO;
import com.pcloud.book.copyright.vo.BookAuthInfoAndServesVO;
import com.pcloud.book.copyright.vo.BookAuthInfoVO;
import com.pcloud.book.copyright.vo.BookAuthInfoWechatVO;
import com.pcloud.book.copyright.vo.GetAuthInfoParam;
import com.pcloud.book.copyright.vo.HaveSetAuthBook;
import com.pcloud.book.copyright.vo.ListHaveAuthBookParam;
import com.pcloud.book.copyright.vo.ListHaveAuthGroupBookParam;
import com.pcloud.book.copyright.vo.ServeVO;
import com.pcloud.book.copyright.vo.SetAuthOpenParam;
import com.pcloud.book.copyright.vo.SetAuthStatusParam;
import com.pcloud.book.copyright.vo.SetLocationDescVO;
import com.pcloud.book.util.common.ThreadPoolUtils;
import com.pcloud.channelcenter.qrcode.dto.QrcodeSceneDto;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.core.biz.MessageBiz;
import com.pcloud.common.core.constant.SystemCode;
import com.pcloud.common.core.dto.SendNotifyDto;
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.usercenter.party.common.vo.PartyIdListVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

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

import cn.hutool.core.util.ObjectUtil;

/**
 * @author lily
 * @date 2018/12/3 11:39
 */
@Component("bookAuthInfoBiz")
public class BookAuthInfoBizImpl implements BookAuthInfoBiz {

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


    @Autowired
    private BookAuthInfoDao bookAuthInfoDao;

    @Autowired
    private BookAuthServeBiz bookAuthServeBiz;

    @Autowired
    private BookAuthCodeBiz bookAuthCodeBiz;

    @Autowired
    private QrcodeSceneConsr qrcodeSceneConsr;

    @Autowired
    private MessageBiz messageBiz;

    @Autowired
    private BookBiz bookBiz;

    @Autowired
    private BookExportRecordBiz bookExportRecordBiz;

    @Autowired
    private ExportConsr exportConsr;

    @Autowired
    private BookAuthUserBiz bookAuthUserBiz;

    @Autowired
    private BookClickBuyRecordDao bookClickBuyRecordDao;

    @Autowired
    private PartyConsr partyConsr;

    @Autowired
    private BookAuthUserDao bookAuthUserDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setBookAuthOpen(SetAuthOpenParam setAuthOpenParam, Long adviserId) {
        checkIsCanExport(setAuthOpenParam, adviserId);
        BookAuthInfoVO bookAuthInfoVO = bookAuthInfoDao.getInfoByBook(setAuthOpenParam.getBookId(), setAuthOpenParam.getChannelId(), adviserId,
                setAuthOpenParam.getAuthBookType());
        BookAuthInfo bookAuthInfo = new BookAuthInfo();
        BeanUtils.copyProperties(setAuthOpenParam, bookAuthInfo);
        if (bookAuthInfoVO == null) {
            this.setAuthBookType(bookAuthInfo, setAuthOpenParam.getAuthBookType());
            bookAuthInfo.setAdviserId(adviserId);
            try {
                bookAuthInfoDao.insert(bookAuthInfo);
            } catch (DataIntegrityViolationException e) {
                LOGGER.error("您已经设置过这本图书！"+e.getMessage(), e);
                throw new BookBizException(BookBizException.DB_DML_FAIL, "您已经设置过这本图书！");
            }
        } else {
            bookAuthInfo.setId(bookAuthInfoVO.getId());
            bookAuthInfo.setAdviserId(adviserId);
            bookAuthInfoDao.updateBaseInfo(bookAuthInfo);
        }
        if(setAuthOpenParam.getAuthBookType() == null || AuthBookTypeEnum.PAPER_BOOK.value.equals(setAuthOpenParam.getAuthBookType())) {
            //设置图书服务(现代纸书)
            bookAuthServeBiz.setBookAuthServes(setAuthOpenParam.getServes(), setAuthOpenParam.getBookId(), setAuthOpenParam.getChannelId(), adviserId);
        }
         //异步生成条形码并导出
        asynExport(setAuthOpenParam.getBookId(), setAuthOpenParam.getChannelId(), adviserId, setAuthOpenParam.getCodeCount(), setAuthOpenParam.getIsHaveBarCode(),setAuthOpenParam.getAuthBookType());
        Integer authBookType = setAuthOpenParam.getAuthBookType() == null ? 0 : setAuthOpenParam.getAuthBookType();
        String key = CopyrightConstants.BOOK_AUTH_INFO + bookAuthInfo.getBookId() + "-" + bookAuthInfo.getChannelId() + "-" + adviserId + "-" + authBookType;
        BookAuthInfoVO bookAuth = bookAuthInfoDao.getInfoByBook(setAuthOpenParam.getBookId(), setAuthOpenParam.getChannelId(), adviserId, setAuthOpenParam.getAuthBookType());
        JedisClusterUtils.setJson(key, bookAuth);
    }

    /**
     * 校验是否能导出
     */
    private void checkIsCanExport(SetAuthOpenParam setAuthOpenParam, Long adviserId) {
        Integer codeCount = setAuthOpenParam.getCodeCount();
        if (codeCount == null || codeCount == 0) {
            return;
        }
        Boolean isHaveExport = isHaveExport(setAuthOpenParam.getBookId(), setAuthOpenParam.getChannelId(), adviserId);// TODO
        if (isHaveExport) {
            throw new BookBizException(BookBizException.ERROR, "您有正在导出的授权码，请不要重复点击导出。导出之后系统会有站内信通知，请留意下右上角的消息中心!");
        }
    }

    @ParamLog("异步导出")
    private void asynExport(Long bookId, Long channelId, Long adviserId, Integer codeCount, Integer isHaveBarCode, Integer authBookType) {
        ThreadPoolUtils.EXPORT_THREAD_POOL.execute(() -> {
            String  commitTime = DateUtils.formatDate(new Date());
            String  num = "";
            try {
                if(codeCount == null || codeCount == 0) {
                    return;
                }
                //获取批次号
                Integer batchNum = bookAuthCodeBiz.getMaxBatchNum(bookId, channelId, adviserId, authBookType);// TODO
                num = String.format("%04d", batchNum);
                //新增导出记录
                insertExportRecord(bookId, channelId, adviserId, num,codeCount,isHaveBarCode);
                //获取图书名称
                BookDto bookDto = bookBiz.getBaseById(bookId);
                if (bookDto == null) {
                    return;
                }
                //获取随机数
                List<String> uuids = CopyrightTools.createShortUuidByCount(codeCount);
                List<BookAuthCode> bookAuthCodes = new ArrayList<>();
                for (String uuid : uuids) {
                    BookAuthCode bookAuthCode = new BookAuthCode();
                    if(authBookType == null || AuthBookTypeEnum.PAPER_BOOK.value.equals(authBookType)) {
                        bookAuthCode.setIsPaperBook(1);
                        bookAuthCode.setIsGroupBook(0);
                    } else {
                        bookAuthCode.setIsPaperBook(0);
                        bookAuthCode.setIsGroupBook(1);
                    }
                    bookAuthCode.setAdviserId(adviserId);
                    bookAuthCode.setChannelId(channelId);
                    bookAuthCode.setBookId(bookId);
                    bookAuthCode.setAuthCode(uuid);
                    bookAuthCode.setFullCode(num+uuid);
                    bookAuthCode.setBatchNum(num);
                    bookAuthCode.setCreateType(0);
                    bookAuthCode.setCreatedUser(adviserId);
                    bookAuthCodes.add(bookAuthCode);
                }
                bookAuthCodeBiz.insert(bookAuthCodes);
                String noticeUrl;
                if(isHaveBarCode == null || isHaveBarCode.equals(0)){
                    String url = generateExcel(bookAuthCodes, bookDto.getBookName());
                    String zipUrl = CopyrightTools.generateBar4Zip(bookAuthCodes, bookDto.getBookName(), url);
                    noticeUrl = zipUrl;
                }else if(isHaveBarCode.equals(2)){
                    String url = generateExcel(bookAuthCodes, bookDto.getBookName());
                    String zipUrl = CopyrightTools.generateQrcode4Zip(bookAuthCodes, bookDto.getBookName(), url);
                    noticeUrl = zipUrl;
                } else {
                    String url = generateExcel(bookAuthCodes, bookDto.getBookName());
                    noticeUrl = url;
                }
                 //发送站内信
                sendLetter(adviserId, bookDto.getBookName(), noticeUrl, commitTime);
                //新增导出记录
                updateSuccessRecord(bookId, channelId, adviserId, num, noticeUrl);
                LOGGER.info("url" + noticeUrl);
            } catch (Exception e) {
                LOGGER.error("导出条形码失败" + e.getMessage(), e);
                updateExportRecord(bookId, channelId, adviserId, num, BookStatusEnum.BookExportStatus.FAIL.value); //TODO
            }
        });
    }

    @ParamLog("设置导出成功记录")
    private void updateSuccessRecord(Long bookId, Long channelId, Long adviserId, String num, String noticeUrl) {
        BookExportRecord bookExportRecord = new BookExportRecord();
        bookExportRecord.setBookId(bookId);
        bookExportRecord.setAdviserId(adviserId);
        bookExportRecord.setChannelId(channelId);
        bookExportRecord.setLastModifiedUser(adviserId);
        bookExportRecord.setExportStatus(BookStatusEnum.BookExportStatus.SUCCESS.value);
        bookExportRecord.setDownloadUrl(noticeUrl);
        bookExportRecord.setBatchNum(num);
        bookExportRecordBiz.updateRecord(bookExportRecord);
    }

    @ParamLog(value = "生成excel", isBefore = false)
    private String generateExcel(List<BookAuthCode> bookAuthCodes, String bookName) {
        List<Object[]> dataList = new ArrayList<Object[]>();
        for (int i = 0, size = bookAuthCodes.size(); i < size; i++) {
            BookAuthCode bookAuthCode = bookAuthCodes.get(i);
            Object[] data = new Object[2];
            data[0] = i + 1;
            data[1] = bookAuthCode.getFullCode();
            dataList.add(data);
        }
        return createExcel(dataList, bookName);
    }

    @ParamLog(value = "生成excel", isBefore = false)
    public String createExcel(List<Object[]> dataList, String bookName) {
        String[] rowsName = {"编号", "正版授权码"};
        String fileTitle = StringUtil.addBracket(bookName) + "正版授权码-" + DateUtils.getStrFormTime("yyyyMMdd", new Date());
        String fileUrl = exportConsr.exportExcel(fileTitle, rowsName, dataList);
        return fileUrl;
    }

    @ParamLog("新增导出记录")
    private void insertExportRecord(Long bookId, Long channelId, Long adviserId, String num,Integer codeCount, Integer isHaveBarCode) {
        BookExportRecord bookExportRecord = new BookExportRecord();
        bookExportRecord.setBookId(bookId);
        bookExportRecord.setAdviserId(adviserId);
        bookExportRecord.setChannelId(channelId);
        bookExportRecord.setBatchNum(num);
        bookExportRecord.setCodeCount(codeCount);
        bookExportRecord.setIsHaveBarCode(isHaveBarCode);
        bookExportRecordBiz.insertRecord(bookExportRecord);
    }

    @ParamLog("修改导出记录")
    private void updateExportRecord(Long bookId, Long channelId, Long adviserId, String num, Integer exportStatus) {
        if(StringUtil.isEmpty(num)) {
            return;
        }
        BookExportRecord bookExportRecord = new BookExportRecord();
        bookExportRecord.setBookId(bookId);
        bookExportRecord.setAdviserId(adviserId);
        bookExportRecord.setBatchNum(num);
        bookExportRecord.setChannelId(channelId);
        bookExportRecord.setLastModifiedUser(adviserId);
        bookExportRecord.setExportStatus(exportStatus);
        bookExportRecordBiz.updateRecordStatus(bookExportRecord);
    }

    @ParamLog("发送站内信")
    @Override
    public void sendLetter(Long adviserId, String bookName, String url, String commitTime) {
        SendNotifyDto sendNotifyDto = new SendNotifyDto();
        sendNotifyDto.setCreatedTime(new Date());
        JSONObject content = new JSONObject();
        content.put("commitTime", commitTime);
        content.put("type", StringUtil.addBracket(bookName));
        sendNotifyDto.setNotifyContent(content.toJSONString());
        sendNotifyDto.setToId(adviserId);
        sendNotifyDto.setFromId(adviserId);
        sendNotifyDto.setSystemCode(SystemCode.adviser.code);
        sendNotifyDto.setTypeCode("genuine_qrcord_download");
        sendNotifyDto.setFileName(bookName);
        sendNotifyDto.setResourceId(url);
        messageBiz.sendLetter(sendNotifyDto);
    }


 /*   *//**
     * 生成word并打包成zip
     *//*
    private String generateWordAndZip(List<BookAuthCode> bookAuthCodes, String fileName) {
        List<String[]> wordUrls = new ArrayList<>();
        List<WordPO> wordPOs = Lists.newArrayList();
        // 调用导出word
        int num = 1;
        for (int i = 0; i < bookAuthCodes.size(); i++) {
            BookAuthCode bookAuthCode = bookAuthCodes.get(i);
            //生成条形码
            String code = bookAuthCode.getFullCode();
            String codeUrl = CopyrightTools.generateBarCode128Local(code, String.valueOf(0.5), String.valueOf(30));
            wordPOs.add(new WordImagePO(OssUtils.urlAddKeyLong(codeUrl),
                    ParagraphAlignment.LEFT.getValue(), 120, 360, null, "    " + code));
            if (5000 == num || i == bookAuthCodes.size() - 1) {// 每5000个生成一个word
                String outPath = "";
                try {
                    outPath = WordUtils.create2(wordPOs);
                } catch (Exception e) {
                    LOGGER.error(e.getMessage(), e);
                }
                if (StringUtils.isEmpty(outPath)) {
                    return null;
                }
                // 将word上传到oss文件服务器上
                UploadResultInfo uploadLocalFile = OssUtils.uploadLocalFile(outPath, fileName);
                String wordUrl = uploadLocalFile.getUrl();// 删除文件
                FileUtils.deleteFolder(outPath);

                String[] url = {fileName, wordUrl};
                wordUrls.add(url);
                wordPOs.clear();
                num = 0;
            }
            num++;
        }
        UploadResultInfo zipUrlInfo = CompressUtils.zip(wordUrls, fileName);
        return zipUrlInfo != null ? zipUrlInfo.getUrl() : null;

    }*/

//    private String generateZip(List<BookAuthCode> bookAuthCodes, String fileName, String excelUrl) {
//        // 调用导出word
//        List<String[]> picUrls = new ArrayList<>();
//        String[] excel = {fileName, excelUrl};
//        picUrls.add(excel);
//        for (int i = 0; i < bookAuthCodes.size(); i++) {
//            BookAuthCode bookAuthCode = bookAuthCodes.get(i);
//            //生成条形码
//            String codeUrl = CopyrightTools.generateBarCode128Local(bookAuthCode.getFullCode(), String.valueOf(0.5), String.valueOf(30));
//            String[] code = {bookAuthCode.getFullCode(), codeUrl};
//            picUrls.add(code);
//        }
//        UploadResultInfo zipUrlInfo = CompressUtils.zipNoSuffix(picUrls, fileName);
//        return zipUrlInfo != null ? zipUrlInfo.getUrl() : null;
//    }

    @Override
    @ParamLog("设置授权后付费查看")
    public void setBookAuthPay(SetAuthStatusParam setAuthStatusParam, Long adviserId) {
        Long bookId = setAuthStatusParam.getBookId();
        Long channelId = setAuthStatusParam.getChannelId();
        Integer isAuthorizedPay = setAuthStatusParam.getIsAuthorizedPay();
        Integer authBookType = setAuthStatusParam.getAuthBookType();
        if (bookId == null || channelId == null || adviserId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "图书不存在");
        }
        BookAuthInfoVO bookAuthInfo = bookAuthInfoDao.getInfoByBook(bookId, channelId, adviserId, authBookType);
        if (bookAuthInfo == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "图书未开启版权保护");
        }
        bookAuthInfo.setIsAuthorizedPay(isAuthorizedPay);
        bookAuthInfoDao.updateAuthorizedPay(bookAuthInfo.getId(), isAuthorizedPay, adviserId);
        if(authBookType == null) {
            authBookType = 0;
        }
        String key = CopyrightConstants.BOOK_AUTH_INFO + bookAuthInfo.getBookId() + "-" + bookAuthInfo.getChannelId() + "-" + adviserId + "-" + authBookType;
        JedisClusterUtils.setJson(key, bookAuthInfo);
    }

    @Override
    @ParamLog("设置版权保护状态")
    public void setAuthStatus(SetAuthStatusParam setAuthStatusParam, Long adviserId) {
        Long bookId = setAuthStatusParam.getBookId();
        Long channelId = setAuthStatusParam.getChannelId();
        Integer bookStatus = setAuthStatusParam.getBookStatus();
        Integer authBookType = setAuthStatusParam.getAuthBookType();
        if (bookId == null || channelId == null || adviserId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "图书不存在");
        }
        BookAuthInfoVO bookAuthInfo = bookAuthInfoDao.getInfoByBook(bookId, channelId, adviserId, authBookType);
        if (bookAuthInfo == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "图书未开启版权保护");
        }
        bookAuthInfo.setBookStatus(bookStatus);
        bookAuthInfoDao.updateBookStatus(bookAuthInfo.getId(), bookStatus, adviserId);
        if(authBookType == null) {
            authBookType = 0;
        }
        String key = CopyrightConstants.BOOK_AUTH_INFO + bookAuthInfo.getBookId() + "-" + bookAuthInfo.getChannelId() + "-" + adviserId + "-" + authBookType;
        JedisClusterUtils.setJson(key, bookAuthInfo);
    }

    @Override
    @ParamLog("更新印码位置描述信息")
    public void setBookLocationDesc(SetLocationDescVO setLocationDesc, Long adviserId) {
        BookAuthInfo bookAuthInfo = new BookAuthInfo();
        BeanUtils.copyProperties(setLocationDesc, bookAuthInfo);
        this.setAuthBookType(bookAuthInfo, setLocationDesc.getAuthBookType());
        bookAuthInfo.setAdviserId(adviserId);
        bookAuthInfoDao.updateLocationDesc(bookAuthInfo);
        Integer authBookType = setLocationDesc.getAuthBookType() == null ? 0 : setLocationDesc.getAuthBookType();
        String key = CopyrightConstants.BOOK_AUTH_INFO + bookAuthInfo.getBookId() + "-" + bookAuthInfo.getChannelId() + "-" + adviserId + "-" + authBookType;
        BookAuthInfoVO bookAuthInfoVO = bookAuthInfoDao.getInfoByBook(bookAuthInfo.getBookId(), bookAuthInfo.getChannelId(), adviserId, setLocationDesc.getAuthBookType());
        JedisClusterUtils.setJson(key, bookAuthInfoVO);
    }

    @Override
    @ParamLog("获取编辑是否有设置正版授权书")
    public Boolean getIsHaveAuthBook(Long adviserId) {
        Boolean isHaveBook = bookAuthInfoDao.getIsHaveAuthBook(adviserId);
        return isHaveBook;
    }

    @Override
    @ParamLog("获取正版授权书基本信息(REDIS)")
    public BookAuthInfoVO getInfoByBook(Long bookId, Long channelId, Long adviserId, Integer authBookType) {
        if(authBookType == null) {
            authBookType = 0;
        }
        String key = CopyrightConstants.BOOK_AUTH_INFO + bookId + "-" + channelId + "-" + adviserId + "-" + authBookType;
        BookAuthInfoVO bookAuthInfoVO = JedisClusterUtils.getJson(key, BookAuthInfoVO.class);
        if (bookAuthInfoVO == null) {
            bookAuthInfoVO = bookAuthInfoDao.getInfoByBook(bookId, channelId, adviserId, authBookType);
            JedisClusterUtils.setJson(key, bookAuthInfoVO);
        }
        return bookAuthInfoVO;
    }

    @Override
    @ParamLog("获取正版授权书基本信息与服务")
    public BookAuthInfoAndServesVO getInfoAndServesByBook(Long bookId, Long channelId, Long adviserId, Integer authBookType) {
        BookAuthInfoVO bookAuthInfoVO = getInfoByBook(bookId, channelId, adviserId, authBookType);
        if(bookAuthInfoVO == null) {
            return null;
        }

        BookAuthInfoAndServesVO bookAuthInfoAndServesVO = new BookAuthInfoAndServesVO();
        BeanUtils.copyProperties(bookAuthInfoVO, bookAuthInfoAndServesVO);
        if(authBookType == null || AuthBookTypeEnum.PAPER_BOOK.value.equals(authBookType)) {
            //获取配置得服务
            List<ServeVO> serves = bookAuthServeBiz.listServesByBook(bookId, channelId, adviserId);
            removeNotInbook(serves, bookId, channelId, adviserId);
            bookAuthInfoAndServesVO.setServes(serves);
        }

        List<HaveUsedAuthCode> result = bookAuthUserDao.checkHaveUsedAuthCode(Lists.newArrayList(bookAuthInfoAndServesVO.getBookId()));
        if(result != null && result.size() == 1){
            bookAuthInfoAndServesVO.setHaveUsedAuthCode(result.get(0).getHaveUsedAuthCode() != 0);
        }
        else{
            bookAuthInfoAndServesVO.setHaveUsedAuthCode(false);
        }

        return bookAuthInfoAndServesVO;
    }

    private void removeNotInbook(List<ServeVO> serves, Long bookId, Long channelId, Long adviserId) {
        if (ListUtils.isEmpty(serves)) {
            return;
        }
        List<Long> serveIds = new ArrayList<>();
        for (ServeVO serveVO : serves) {
            serveIds.add(serveVO.getServeId());
        }
        Map<String, Boolean> serveMap = qrcodeSceneConsr.listIsInBook(bookId, channelId, adviserId, serveIds);
        for (ServeVO serveVO : serves) {
            serveIds.add(serveVO.getServeId());
        }
        if(serveMap == null){
            serves.clear();
        }else{
            serves.removeIf(vo -> serveMap.get(vo.getServeType() + vo.getServeId()) == null);
        }
    }


    @Override
    @ParamLog("获取设置过正版授权的图书")
    public PageBeanNew listHaveSetAuthBook(ListHaveAuthBookParam listHaveAuthBookParam, Long adviserId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("adviserId", adviserId);
        paramMap.put("bookStatus", listHaveAuthBookParam.getBookStatus());
        paramMap.put("isMainEditor", listHaveAuthBookParam.getIsMainEditor());
        paramMap.put("isFundSupport", listHaveAuthBookParam.getIsFundSupport());
        paramMap.put("channelId", listHaveAuthBookParam.getChannelId());
        paramMap.put("name", listHaveAuthBookParam.getName() != null && "".equals(listHaveAuthBookParam.getName().trim()) ? null : listHaveAuthBookParam.getName());
        if(!StringUtil.isEmpty(listHaveAuthBookParam.getName())){
            String [] nameList = listHaveAuthBookParam.getName().trim().split("\\s+");
            paramMap.put("nameList", Lists.newArrayList(nameList));
        }
        paramMap.put("typeCode", listHaveAuthBookParam.getTypeCode() != null && "".equals(listHaveAuthBookParam.getTypeCode().trim()) ? null : listHaveAuthBookParam.getTypeCode());
        paramMap.put("templetId", listHaveAuthBookParam.getTempletId());
        paramMap.put("secondTempletIds", Optional.ofNullable(listHaveAuthBookParam.getSecondTempletId()).map(Lists::newArrayList).orElse(Lists.newArrayList()));
        PageParam pageParam = new PageParam(listHaveAuthBookParam.getCurrentPage(), listHaveAuthBookParam.getNumPerPage());
        PageBeanNew<HaveSetAuthBook> pageBean = bookAuthInfoDao.listPageNew(pageParam, paramMap, "listHaveSetAuthBook");
        if (pageBean == null || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBeanNew<>(listHaveAuthBookParam.getCurrentPage(), listHaveAuthBookParam.getNumPerPage(), new ArrayList<>());
        }
        setHaveUseAuthCode(pageBean);
        return pageBean;
    }

    private void setHaveUseAuthCode(PageBeanNew<HaveSetAuthBook> pageBean){
        List<Long> bookIds = pageBean.getRecordList().stream().map(HaveSetAuthBook::getBookId).collect(Collectors.toList());
        List<HaveUsedAuthCode> result = bookAuthUserDao.checkHaveUsedAuthCode(bookIds);

        for(HaveSetAuthBook book: pageBean.getRecordList()){
            book.setHaveUsedAuthCode(false);
            for(HaveUsedAuthCode code: result){
                if(code.getBookId().equals(book.getBookId())){
                    book.setHaveUsedAuthCode(code.getHaveUsedAuthCode() != 0);
                    break;
                }
            }
        }
    }

    @Override
    @ParamLog("获取设置过正版授权的社群书")
    public PageBeanNew listHaveSetAuthGroupBook(ListHaveAuthGroupBookParam listHaveAuthGroupBookParam, Long adviserId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("adviserId", adviserId);
        paramMap.put("bookStatus", listHaveAuthGroupBookParam.getBookStatus());
        paramMap.put("channelId", listHaveAuthGroupBookParam.getChannelId());
        paramMap.put("name", listHaveAuthGroupBookParam.getName() != null && "".equals(listHaveAuthGroupBookParam.getName().trim()) ? null : listHaveAuthGroupBookParam.getName());
        paramMap.put("typeCode", listHaveAuthGroupBookParam.getTypeCode() != null && "".equals(listHaveAuthGroupBookParam.getTypeCode().trim()) ? null : listHaveAuthGroupBookParam.getTypeCode());
        paramMap.put("templetId", listHaveAuthGroupBookParam.getTempletId());
        paramMap.put("secondTempletIds", Optional.ofNullable(listHaveAuthGroupBookParam.getSecondTempletId()).map(Lists::newArrayList).orElse(Lists.newArrayList()));
        PageParam pageParam = new PageParam(listHaveAuthGroupBookParam.getCurrentPage(), listHaveAuthGroupBookParam.getNumPerPage());
        PageBeanNew pageBean = bookAuthInfoDao.listPageNew(pageParam, paramMap, "listHaveSetAuthGroupBook");
        if (pageBean == null || ListUtils.isEmpty(pageBean.getRecordList())) {
            return new PageBeanNew(listHaveAuthGroupBookParam.getCurrentPage(), listHaveAuthGroupBookParam.getNumPerPage(), new ArrayList<>());
        }
        return pageBean;
    }


    @Override
    @ParamLog("获取设置过版权保护书刊的价格")
    public BigDecimal getBookAuthPrice(Long bookId, Long channelId, Long adviserId, Integer authBookType) {
        BookAuthInfoVO authInfoVO = bookAuthInfoDao.getInfoByBook(bookId, channelId, adviserId, authBookType);
        if (authInfoVO != null) {
            return authInfoVO.getPrice();
        }
        return null;
    }

    @Override
    @ParamLog("获取授权图书信息（客户端）")
    public BookAuthInfoWechatVO getInfoByBook4Wechat(GetAuthInfoParam getAuthInfoParam, Long channelId) {
        BookAuthInfoWechatVO  bookAuthInfoWechatVO = new BookAuthInfoWechatVO();
        Long bookId =getAuthInfoParam.getBookId();
        Long adviserId = getAuthInfoParam.getAdviserId();
        Long sceneId = getAuthInfoParam.getSceneId();
        if(null!=getAuthInfoParam.getChannelId()){
            channelId=getAuthInfoParam.getChannelId();
        }
        BookAuthInfoVO authBookInfo = getAuthBookInfo(bookId, channelId, adviserId, sceneId, getAuthInfoParam.getAuthBookType());
        if (authBookInfo != null) {
            BeanUtils.copyProperties(authBookInfo, bookAuthInfoWechatVO);
            //获取图书基本信息
            BookDto bookDto = bookBiz.getBaseById(authBookInfo.getBookId());
            bookAuthInfoWechatVO.setBookName(bookDto == null ? "" : bookDto.getBookName());
            bookAuthInfoWechatVO.setCoverImg(bookDto == null ? "" : bookDto.getCoverImg());
        }
        return bookAuthInfoWechatVO;
    }

    @Override
    @ParamLog("获取授权图书信息")
    public BookAuthInfoVO getAuthBookInfo(Long bookId, Long channelId, Long adviserId, Long sceneId, Integer authBookType){
        if(bookId == null && adviserId == null && sceneId == null){
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "图书不存在");
        }
        if(null != sceneId){
            //通过二维码获取图书信息
            QrcodeSceneDto qrcodeSceneDto = qrcodeSceneConsr.getById(sceneId);
            if(qrcodeSceneDto == null){
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "图书不存在");
            }
            bookId = qrcodeSceneDto.getAdviserBookId();
            adviserId = qrcodeSceneDto.getCreatedByUserLogin();
        }
        if(bookId == null){
            return null;
        }
        return getInfoByBook(bookId, channelId, adviserId, authBookType);
    }

    @Override
    public BookAuthInfoCountDTO getBookAuthInfoCount(Long bookId, Long channelId, Long adviserId, String monthDate) {
        BookAuthInfoCountDTO bookAuthInfoCountDTO = bookAuthInfoDao.getBookAuthCount(bookId, channelId, adviserId); //TODO
        if (bookAuthInfoCountDTO == null) {
            return null;
        }
        BookAuthCodeUserVO authUserCount = bookAuthUserBiz.getAuthUserCountByMonth(bookId, channelId, adviserId, monthDate);
        if (authUserCount != null) {
            BeanUtils.copyProperties(authUserCount, bookAuthInfoCountDTO);
        }
        return bookAuthInfoCountDTO;
    }

    @Override
    public BookAuthTotalCountDTO getBookAuthTotalCount(List<Long> adviserIds) { //TODO
        //获取出版社下的编辑
        PartyIdListVO partyIdList4Test = partyConsr.getPartyIdList4Test();
        List<Long> removeAdviserIds = partyIdList4Test == null ? null : partyIdList4Test.getAdviserIds();
        BookAuthTotalCountDTO bookAuthTotalCountDTO = new BookAuthTotalCountDTO();
        //获取开启正版授权图书的总数
        Integer openCount = bookAuthInfoDao.getTotalNum(adviserIds, removeAdviserIds);
        if(openCount == null || openCount == 0){
            setZeroData(bookAuthTotalCountDTO);
            return bookAuthTotalCountDTO;
        }else {
            bookAuthTotalCountDTO.setOpenCount(openCount);
        }
        BookAuthCodeUserVO authUserTotalCount = bookAuthUserBiz.getAuthUserTotalCount(adviserIds, removeAdviserIds);
        if(authUserTotalCount!=null){
            BeanUtils.copyProperties(authUserTotalCount, bookAuthTotalCountDTO);
        }
        //获取点击链接总数
        Integer count = bookClickBuyRecordDao.getClickBuyRecordCount(adviserIds, removeAdviserIds);
        bookAuthTotalCountDTO.setClickBuyCount(count);
        return bookAuthTotalCountDTO;
    }

    @Override
    @ParamLog("是否有正在导出的")
    public Boolean isHaveExport(Long bookId, Long channelId, Long adviserId) {
        Boolean isCanExport = bookExportRecordBiz.isHaveExport(bookId, channelId, adviserId);//TODO
        return isCanExport;
    }

    private void setZeroData(BookAuthTotalCountDTO bookAuthTotalCountDTO) {
        bookAuthTotalCountDTO.setCodeUserCount(0);
        bookAuthTotalCountDTO.setOpenCount(0);
        bookAuthTotalCountDTO.setPayUserCount(0);
        bookAuthTotalCountDTO.setTotalCount(0);
        bookAuthTotalCountDTO.setClickBuyCount(0);
    }

    private void setAuthBookType(BookAuthInfo bookAuthInfo, Integer authBookType) {
        if(null == authBookType || AuthBookTypeEnum.PAPER_BOOK.value.equals(authBookType)) {
            bookAuthInfo.setIsPaperBook(1);
            bookAuthInfo.setIsGroupBook(0);
        } else {
            bookAuthInfo.setIsPaperBook(0);
            bookAuthInfo.setIsGroupBook(1);
        }
    }

    @Override
    public void setBookCodeAuth(AuthOpenVO authOpenVO, Long adviserId) {
        if(ObjectUtil.hasEmpty(authOpenVO,authOpenVO.getBookId(),authOpenVO.getChannelId())){
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少参数");
        }
        BookAuthInfoVO bookAuthInfoVO = bookAuthInfoDao.getInfoByBook(authOpenVO.getBookId(), authOpenVO.getChannelId(), adviserId,
                authOpenVO.getAuthBookType());
        BookAuthInfo bookAuthInfo = new BookAuthInfo();
        bookAuthInfo.setBookId(authOpenVO.getBookId());
        bookAuthInfo.setChannelId(authOpenVO.getChannelId());
        bookAuthInfo.setAuthType(2);
        if (bookAuthInfoVO == null) {
            this.setAuthBookType(bookAuthInfo, authOpenVO.getAuthBookType());
            bookAuthInfo.setAdviserId(adviserId);
            try {
                bookAuthInfoDao.insert(bookAuthInfo);
            } catch (DataIntegrityViolationException e) {
                LOGGER.error("您已经设置过这本图书！"+e.getMessage(), e);
                throw new BookBizException(BookBizException.DB_DML_FAIL, "您已经设置过这本图书！");
            }
        } else {
            bookAuthInfo.setId(bookAuthInfoVO.getId());
            bookAuthInfo.setAdviserId(adviserId);
            bookAuthInfoDao.updateBaseInfo(bookAuthInfo);
        }
        Integer authBookType = authOpenVO.getAuthBookType() == null ? 0 : authOpenVO.getAuthBookType();
        String key = CopyrightConstants.BOOK_AUTH_INFO + bookAuthInfo.getBookId() + "-" + bookAuthInfo.getChannelId() + "-" + adviserId + "-" + authBookType;
        BookAuthInfoVO bookAuth = bookAuthInfoDao.getInfoByBook(authOpenVO.getBookId(), authOpenVO.getChannelId(), adviserId, authOpenVO.getAuthBookType());
        JedisClusterUtils.setJson(key, bookAuth);
    }
}
