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

import java.math.BigDecimal;
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;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.pcloud.book.base.dto.CountDto;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.biz.BookAdviserBiz;
import com.pcloud.book.book.biz.BookBiz;
import com.pcloud.book.book.constant.BookConstant;
import com.pcloud.book.book.dao.BookAdviserDao;
import com.pcloud.book.book.dto.AdviserBookInfoDTO;
import com.pcloud.book.book.dto.AdviserManageDto;
import com.pcloud.book.book.dto.AviserBookInfoParam;
import com.pcloud.book.book.dto.BookAdviserDto;
import com.pcloud.book.book.dto.BookCountAndAdviserIdDTO;
import com.pcloud.book.book.dto.BookCountByAdvisersDto;
import com.pcloud.book.book.dto.BookCountDto;
import com.pcloud.book.book.dto.BookDto;
import com.pcloud.book.book.entity.Book;
import com.pcloud.book.book.entity.BookAdviser;
import com.pcloud.book.book.set.BookSet;
import com.pcloud.book.book.vo.ErpAdviserBookVO;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.message.TemplateConsr;
import com.pcloud.book.consumer.raystask.MainLineConsr;
import com.pcloud.book.consumer.settlement.BookConsr;
import com.pcloud.book.consumer.user.AdviserConsr;
import com.pcloud.book.consumer.user.BookcaseConsr;
import com.pcloud.book.consumer.user.ChannelConsr;
import com.pcloud.book.group.biz.BookGroupBiz;
import com.pcloud.book.group.dao.BookGroupDao;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.core.constant.SceneCode;
import com.pcloud.common.core.constant.SendType;
import com.pcloud.common.core.constant.SystemCode;
import com.pcloud.common.exceptions.BizException;
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.string.StringUtil;
import com.pcloud.raystask.entity.AdviserDefault;

/**
 * @描述：编辑管理书籍逻辑层接口实现类
 * @作者：songx
 * @创建时间：2016年12月30日,下午5:23:32 @版本：1.0
 */
@Service("bookAdviserBiz")
public class BookAdviserBizImpl implements BookAdviserBiz {

	/**
	 *
	 */
	private static final Logger LOGGER = LoggerFactory.getLogger(BookAdviserBizImpl.class);

	@Autowired
	private BookAdviserDao bookAdviserDao;

	@Autowired
	private BookBiz bookBiz;

	@Autowired
	private BookSet bookSet;

	@Autowired
	private QrcodeSceneConsr qrcodeSceneConsr;

	@Autowired
	private TemplateConsr templateConsr;

	@Autowired
	private AdviserConsr adviserConsr;

	@Autowired
	private MainLineConsr mainLineConsr;

	@Autowired
	private BookcaseConsr bookcaseConsr;

	@Autowired
	private BookConsr bookConsr;

	@Autowired
	private ChannelConsr channelConsr;

    @Autowired
    private BookGroupBiz bookGroupBiz;

    @Autowired
    private BookGroupDao bookGroupDao;

    @Override
    public List<BookDto> listByAdviserId(Long adviserId) {
		if(null == adviserId) {
			return Lists.newArrayList();
		}
		final List<Long> bookIds = bookAdviserDao.listBookIdsByAdviser(adviserId);
		if(CollectionUtils.isEmpty(bookIds)) {
			return Lists.newArrayList();
		}
		final Map<Long, BookDto> map = bookBiz.listBaseByIds(bookIds);
		if(CollectionUtils.isEmpty(map)) {
			return Lists.newArrayList();
		}
		return Lists.newArrayList(map.values());
    }

    /**
	 * 创建编辑管理书籍关系
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void create(BookAdviser bookAdviser) throws BizException {
		LOGGER.info("创建编辑与书籍关联关系【START】bookAdviser=" + bookAdviser);
		checkParam(bookAdviser);
		// 验证渠道编辑是否为一个出版社
		checkIsSameAgent(bookAdviser.getChannelId(), bookAdviser.getAdviserId());

		// 判断编辑是否已经设置过该书籍的推广信息
		BookAdviserDto bookAdviserDto = this.getByAdviserContainsDelete(bookAdviser);
		if (bookAdviserDto != null && BookConstant.BOOK_ADVISER_NO_DELETE.equals(bookAdviserDto.getIsDelete())) {
			return;
		}

		if (bookAdviserDto != null && BookConstant.BOOK_ADVISER_DELETE.equals(bookAdviserDto.getIsDelete())) { // 编辑之前设置过，但是已经删除，走恢复流程
			// 20190723-刘娜【ID1001264】社群书删除后，再创建时不要自动恢复
			recoverBook4Adviser(bookAdviser.getBookId(), bookAdviser.getAdviserId(), bookAdviser.getChannelId(),
					bookAdviser.getTempletId(), bookAdviser.getSecondTempletId(),
					bookAdviser.getGraLabelId(), bookAdviser.getSubLabelId(), bookAdviser.getVerLabelId(), bookAdviser.getAreaLabelId(),
					false);
		} else {
			// 判断是否配置过该书籍推广信息
			checkIsHaveOtherAdviser(bookAdviser.getBookId(), bookAdviser.getChannelId(), bookAdviser.getAdviserId());
			try {
				LOGGER.info("【书籍-编辑】编辑设置书籍推广信息,<START>.[bookAdviser]=" + bookAdviser.toString());
				// 默认是主编辑
				bookAdviser.setIsMainEditor(true);
				bookAdviserDao.insert(bookAdviser);
			} catch (DataIntegrityViolationException e) {
				throw new BookBizException(BookBizException.DB_DML_FAIL, "该书刊已经被别的编辑添加过");
			} catch (Exception e) {
				LOGGER.error("【书籍-编辑】编辑设置书籍推广信息,<ERROR>.[BookAdviserDao.insert]" + e.getMessage(), e);
				throw new BookBizException(BookBizException.DB_DML_FAIL, "设置书刊推广信息失败");
			}

			// 周任务书刊埋点
			mainLineConsr.sendAddBookTask(bookAdviser.getBookId(), bookAdviser.getAdviserId());
		}
		LOGGER.info("创建编辑与书籍关联关系【END】");
	}

	/**
	 * 是否有其他编辑加过这本书
	 * @param bookId 图书标识
	 * @param channelId 运营标识
	 */
	void  checkIsHaveOtherAdviser(Long bookId, Long channelId, Long adviserId) throws BizException{
		LOGGER.info("是否有其他编辑加过这本书bookId="+bookId+"channelId="+channelId);
		if (bookId == null || channelId == null) {
			throw new BookBizException(BookBizException.PARAM_IS_ERROR, "图书不存在！");
		}
		List<BookAdviserDto> advisers = bookAdviserDao.getAdvisers(bookId);
		if(ListUtils.isEmpty(advisers)){
			return;
		}
		Boolean isHaveOtherChannel = false;
		Boolean isMySelf = false;
		for(BookAdviserDto bookAdviserDto : advisers){
			if(!channelId.equals(bookAdviserDto.getChannelId())){
				isHaveOtherChannel = true;
			}
			if(bookAdviserDto.getAdviserId().equals(adviserId)) {
				isMySelf = true;
			}
		}
		if(isHaveOtherChannel){
			throw new BookBizException(BookBizException.DB_SELECT_MORE, "已在其它运营平台存在");
		}else{
			if (!isMySelf || advisers.size() > 1) {
				throw new BookBizException(BookBizException.DB_SELECT_MORE, "已被其它编辑增加成功");
			}
		}
	}

	/**
	 * 校验是否同一出版社
	 *
	 * @param channelId
	 *            运营标识
	 * @param adviserId
	 *            编辑标识
	 */
	private void checkIsSameAgent(Long channelId, Long adviserId) {
		if (!channelConsr.judgeChannelAdviserRelationship(channelId, adviserId)) {
			throw new BookBizException(BookBizException.PARAM_IS_ERROR, "渠道编辑非同一出版社，不能创建书籍");
		}
	}

	/**
	 * 校验参数
	 * @param bookAdviser
	 */
	private void checkParam(BookAdviser bookAdviser) {
		if (bookAdviser.getBookId() == null) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
		}
		if (bookAdviser.getChannelId() == null) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择运营平台");
		}
		if (bookAdviser.getAdviserId() == null) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "会话失效,请重新登录");
		}
	}

	/**
	 * 删除编辑和书籍的推广信息
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteByBook(Long bookId) throws BizException {
		if (bookId == null) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
		}
		LOGGER.info("【书籍-编辑】删除编辑和书籍的推广信息,<START>.[bookId]=" + bookId);
		bookAdviserDao.deleteByBook(bookId);
	}

	/**
	 * 批量删除编辑和书籍的推广信息
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteByBooks(List<Long> bookIds) throws BizException {
		if (bookIds == null || bookIds.isEmpty()) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
		}

		try {
			LOGGER.info("【书籍-编辑】批量删除书刊的推广信息,<START>.[bookIds]=" + bookIds.toString());
			bookAdviserDao.deleteByBooks(bookIds);
		} catch (Exception e) {
			LOGGER.error("【书籍-编辑】批量删除书刊的推广信息,<ERROR>.[bookAdviserDao.deleteByBooks]" + e.getMessage(), e);
			throw new BookBizException(BookBizException.DB_DML_FAIL, "批量删除书刊的推广信息失败");
		}
	}

	/**
	 * 获取编辑设置的书籍推广信息
	 */
	@Override
	public BookAdviserDto getByAdviser(BookAdviser bookAdviser) throws BizException {
		if (bookAdviser == null) {
			return null;
		}
		if (StringUtils.isEmpty(bookAdviser.getSerialNumber())) {
			bookAdviser.setSerialNumber(null);
		}
		return bookAdviserDao.getByAdviser(bookAdviser);
	}

	/**
	 * 获取编辑设置的书籍推广信息
	 */
	@Override
	public BookAdviserDto getBase(Long bookId, Long channelId, Long adviserId) throws BizException {
		return bookAdviserDao.getBase(bookId, channelId, adviserId);
	}


	/**
	 * 获取编辑设置的书籍推广信息(包含删除或未删除的)
	 */
	private BookAdviserDto getByAdviserContainsDelete(BookAdviser bookAdviser) throws BizException {
		return bookAdviserDao.getByAdviserContainsDelete(bookAdviser);
	}

	/**
	 * 统计编辑推广的图书总数
	 */
	@Override
	public Map<Long, BookAdviserDto> getCountByAdvisers(List<Long> adviserIds) throws BizException {
		try {
			return bookAdviserDao.getCountByAdvisers(adviserIds);
		} catch (Exception e) {
			LOGGER.error("【书籍-代理】统计推广的书刊总数,<ERROR>.[BookAdviserDao.getCountByAdvisers]" + e.getMessage(), e);
			throw new BookBizException(BookBizException.DB_DML_FAIL, "统计推广的书刊总数失败");
		}
	}

	/**
	 * 根据ISBN获取书刊信息
	 */
	public BookAdviserDto getByIsbnEx(String isbn, Long channelId) throws BizException {
		LOGGER.info("【编辑书刊】根据ISBN获取书刊信息,<START>.[isbn]=" + isbn);
		if (StringUtil.isEmpty(isbn)) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
		}
		try {
			Map<String, Object> paramMap = Maps.newHashMap();
			paramMap.put("isbn", isbn);
			paramMap.put("channelId", channelId);
			return bookAdviserDao.getByIsbn(paramMap);
		} catch (Exception e) {
			LOGGER.error("【书刊基础】根据ISBN获取书刊信息,<ERROR>.[getByIsbn]:" + e.getMessage(), e);
			throw BizException.DB_SELECT_IS_FAIL;
		}
	}

	/**
	 * 根据ISBN获取书刊信息
	 */
	@Override
	public BookAdviserDto getByIsbn(String isbn, Long channelId) throws BizException {
		LOGGER.info("【编辑书刊】根据ISBN获取书刊信息,<START>.[isbn]=" + isbn);
		if (StringUtil.isEmpty(isbn)) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
		}
		BookAdviserDto bookAdviserDto = null;
		try {
			Map<String, Object> paramMap = Maps.newHashMap();
			paramMap.put("isbn", isbn);
			paramMap.put("channelId", channelId);
			bookAdviserDto = bookAdviserDao.getByIsbn(paramMap);
			return bookAdviserDto;
		} catch (Exception e) {
			LOGGER.error("【书刊基础】根据ISBN获取书刊信息,<ERROR>.[getByIsbn]:" + e.getMessage(), e);
			throw BizException.DB_SELECT_IS_FAIL;
		}
	}

	/**
	 * 获取配置过书籍的编辑top1
	 */
	@Override
	public Long getAdviserTop1(Long bookId, Long channelId) {
		LOGGER.info("【编辑书刊】获取配置过书籍的编辑top1,<START>.[bookId]=" + bookId + ",[channelId]");
		try {
			Map<String, Object> paramMap = Maps.newHashMap();
			paramMap.put("bookId", bookId);
			paramMap.put("channelId", channelId);
			return bookAdviserDao.getAdviserTop1(paramMap);
		} catch (Exception e) {
			LOGGER.error("【编辑书刊】获取配置过书籍的编辑top1,<ERROR>.[getByIsbn]:" + e.getMessage(), e);
			throw BizException.DB_SELECT_IS_FAIL;
		}
	}

	/**
	 * 根据书籍和渠道删除书籍编辑关联信息
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteByBookAndChannel(Long bookId, Long channelId) throws BizException {
		LOGGER.info("【编辑书刊】根据书籍和渠道删除书籍编辑关联信息,<START>.[bookId]=" + bookId + ",[channelId]=" + channelId);
		try {
			Map<String, Object> paramMap = Maps.newHashMap();
			paramMap.put("bookId", bookId);
			paramMap.put("channelId", channelId);
			bookAdviserDao.deleteByBookAndChannel(paramMap);
		} catch (Exception e) {
			LOGGER.error("【编辑书刊】根据书籍和渠道删除书籍编辑关联信息,<ERROR>.[deleteByBookAndChannel]:" + e.getMessage(), e);
			throw new BookBizException(BookBizException.DB_DML_FAIL, "根据书籍和渠道删除书籍编辑关联信息失败");
		}
	}

	/**
	 * 根据图书信息获取主编辑ID
	 */
	@Override
	public Long getMainAdviserId(Long bookId, Long channelId) {
		LOGGER.info("根据图书信息获取主编辑ID,<START>.[bookId]=" + bookId + ",[channelId]=" + channelId);
		if (null == bookId || null == channelId) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "书刊信息缺失！");
		}
		try {
			Long mainAdviserId = bookAdviserDao.getMainAdviserId(bookId, channelId);
			return mainAdviserId;
		} catch (Exception e) {
			LOGGER.error("根据图书信息获取主编辑ID,<ERROR>.[getMainAdviserId]:" + e.getMessage(), e);
			throw BizException.DB_SELECT_IS_FAIL;
		}

	}

	/**
	 * 编辑管理--获取编辑列表（平台端）
	 */
	@Override
	public List<AdviserManageDto> getAdviserList(Long bookId) {
		LOGGER.info("【书刊管理-编辑管理】编辑管理--获取编辑列表（平台端）,<START>.[bookId]=" + bookId);
		List<AdviserManageDto> adviserManageDtos = bookAdviserDao.getAdviserList(bookId);
		List<Long> adviserIds = bookAdviserDao.getAdviserIdsByBookId(bookId);
		bookSet.setAdviserDetailInfo(adviserManageDtos, adviserIds);
		return adviserManageDtos;
	}

	/**
	 * 编辑管理--删除副编辑
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delViceAdviser(List<BookAdviser> bookAdvisers) {
		if (ListUtils.isEmpty(bookAdvisers)) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "书刊信息缺失！");
		}
		LOGGER.info("编辑管理--删除副编辑,<START>.[bookAdvisers]=" + bookAdvisers.toString());
		// 删除副编辑
		bookAdviserDao.delViceAdviser(bookAdvisers);
		BookDto bookDto = bookBiz.getBaseById(bookAdvisers.get(0).getBookId());
		for (BookAdviser bookAdviser : bookAdvisers) {
				// 删除副编辑二维码关联关系
			qrcodeSceneConsr.deleteAdviserBookQrRelation(bookAdviser.getAdviserId(), bookAdviser.getBookId());
		    sendBookDeleteTemplate(bookAdviser.getAdviserId(), bookDto.getBookName());
		}
	}

	/**
	 * 发送书刊移除模板消息
	 * @param adviserId 编辑标识
	 * @param bookName 图书名称
	 */
	void sendBookDeleteTemplate(Long adviserId, String bookName) {
		try {
			// 发送模板消息
			Long agentId = adviserConsr.getAgentIdByAdviser(adviserId);
			Map<String, String> temParam = new HashMap<>();
			temParam.put("first", "编辑变更");
			temParam.put("keyword1", "RAYS编辑");
			temParam.put("keyword2", "您的书刊" + StringUtil.addBracket(bookName) + "已被移除，请知悉");
			temParam.put("remark", "请抽空处理");
			templateConsr.sendManage(SceneCode.PROJECT_TASK_SCENE.value, agentId, adviserId,
					SystemCode.adviser.code, "", temParam, SendType.SEND_BY_PARTY_ID.value, false);
		} catch (Exception e) {
			LOGGER.error("编辑管理--删除副编辑,发送模板消息失败<ERROR>"+e.getMessage());
		}
	}

	/**
	 * 创建默认图书与编辑的关系
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Long createDefaultBook(Long channelId, Long adviserId) {
		if (channelId == null) {
			//获取默认运营
			channelId = adviserConsr.getDefaultChannel(adviserId);
		}
		if(channelId == null) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "运营不存在");
		}
		if (adviserId == null) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "编辑不存在");
		}
		BookAdviser bookAdviser = new BookAdviser();
		// 获取bookId
		BookDto book = bookBiz.getByIsbn(BookConstant.DEFAULT_BOOK_ISBN, null);
		if (book == null) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
		}
		bookAdviser.setBookId(book.getBookId());
		bookAdviser.setChannelId(channelId);
		bookAdviser.setAdviserId(adviserId);
		bookAdviser.setIsMainEditor(false);
		try {
			LOGGER.info("【书籍-编辑】编辑设置书籍推广信息,<START>.[bookAdviser]=" + bookAdviser.toString());
			// 默认是主编辑
			bookAdviserDao.insert(bookAdviser);
		} catch (Exception e) {
			LOGGER.warn("【书籍-编辑】编辑设置书籍推广信息,<ERROR>.[BookAdviserDao.insert]" + e.getMessage(), e);
		}
		AdviserDefault adviserDefault = new AdviserDefault();
		adviserDefault.setAdviserId(adviserId);
		adviserDefault.setBookId(book.getBookId());
		mainLineConsr.sendDefaultId(adviserDefault);
		return book.getBookId();
	}

	/**
	 * 获取默认创建的图书
	 */
	@Override
	public BookAdviserDto getDefaultBook(Long channelId, Long adviserId) {
		BookAdviser bookAdviser = new BookAdviser();
		// 获取bookId
		BookDto book = bookBiz.getByIsbn("9787507600000", null);
		if (book == null) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择书刊");
		}
		bookAdviser.setBookId(book.getBookId());
		bookAdviser.setChannelId(channelId);
		bookAdviser.setAdviserId(adviserId);
		BookAdviserDto bookAdviserDto = this.getByAdviser(bookAdviser);
		if (bookAdviserDto != null) {
			BookDto bookDto = bookBiz.getBaseById(bookAdviserDto.getBookId());
			bookAdviserDto.setBookDto(bookDto);
		}
		return bookAdviserDto;
	}

	/**
	 * 出版社下编辑的所有书刊的数目
	 */
	@Override
	public Integer getBookCount(Long agentId) {
		LOGGER.info("出版社下编辑的所有书刊的数目,<START>.[agentId]=" + agentId);
		List<Long> adviserIds = adviserConsr.getByAgentId(agentId);
		Integer bookCount = null;
		try {
			if (!ListUtils.isEmpty(adviserIds)) {
				bookCount = bookAdviserDao.getBookCount(adviserIds);
			}
		} catch (Exception e) {
			LOGGER.error("出版社下编辑的所有书刊的数目,<ERROR>.[getBookCount]:" + e.getMessage(), e);
			throw BizException.DB_SELECT_IS_FAIL;
		}
		return bookCount;
	}

	/**
	 * 更新图书模板
	 */
	@ParamLog("更新图书模板")
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateBookTemplet(Book book) {
		BookAdviser bookAdviser = new BookAdviser();
		bookAdviser.setBookId(book.getBookId());
		bookAdviser.setTempletId(book.getTempletId());
		bookAdviser.setAdviserId(book.getLastModifiedUser());
		bookAdviser.setChannelId(book.getChannelId());
		bookAdviser.setSecondTempletId(book.getSecondTempletId());
		bookAdviser.setGraLabelId(book.getGraLabelId());
		bookAdviser.setSubLabelId(book.getSubLabelId());
		bookAdviser.setAreaLabelId(book.getAreaLabelId());
		bookAdviser.setVerLabelId(book.getVerLabelId());
		bookAdviserDao.updateBookTemplet(bookAdviser);
	}

	/**
	 * 每日新增书刊数-出版
	 */
	@Override
	public List<BookCountDto> listBookCountByDate4Agent(Long agentId) {
		LOGGER.info("每日新增书刊数-出版<START>.[agentId]=" + agentId);
		// 获取所有编辑
		List<Long> adviserIds = adviserConsr.getByAgentId(agentId);
		List<BookCountDto> bookCounts = null;
		String startDate = DateUtils.getShortDateStr(DateUtils.addDay(new Date(), -14));
		String endDate = DateUtils.getShortDateStr(DateUtils.addDay(new Date(), -1));
		if (!ListUtils.isEmpty(adviserIds)) {
			Map<String, Object> paramMap = new HashMap<>();
			paramMap.put("adviserIds", adviserIds);
			paramMap.put("startDate", startDate);
			paramMap.put("endDate", endDate);
			bookCounts = bookAdviserDao.listBookCountByDate4Agent(paramMap);
		}
		this.setZoreRecord(bookCounts, startDate, endDate);
		return bookCounts;
	}

	/**
	 * 填充不存在的日期中的值为0
	 *
	 * @param bookCounts
	 * @param startTime
	 * @param endTime
	 * @throws BizException
	 */
	public void setZoreRecord(List<BookCountDto> bookCounts, String startTime, String endTime) throws BizException {
		if (!ListUtils.isEmpty(bookCounts)) {
			// 计算开始时间和结束时间相差多少天，含当天所以要+1
			int dateDiff = (int) (DateUtils.getDateDiff(endTime, startTime) + 1);
			List<String> dates = DateUtils.getLastDays(endTime, dateDiff);
			for (String date : dates) {
				boolean bool = false;
				for (BookCountDto bookCountDto : bookCounts) {
					if (date.equals(bookCountDto.getDate())) {
						bool = true;
					}
				}
				if (!bool) {
					BookCountDto bookCount = new BookCountDto();
					bookCount.setDate(date);
					bookCount.setBookCount(0);
					bookCounts.add(bookCount);
				}
			}
			bookCounts.sort((BookCountDto dto1, BookCountDto dto2) -> dto1.getDate().compareTo(dto2.getDate()));
		}
	}

	/**
	 * 删除书籍（编辑端）
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteBook4Adviser(Long bookId, Long adviserId, Long channelId) {
		LOGGER.info("删除书籍（编辑端）<START>.[bookId]=" + bookId + ",[adviserId]=" + adviserId + ",channelId=" + channelId);
		Map<String, Long> paramMap = new HashMap<>();
		paramMap.put("bookId", bookId);
		paramMap.put("adviserId", adviserId);
		paramMap.put("channelId", channelId);
		// 查询当前编辑是否是主编辑
		Boolean isMainAdviser = bookAdviserDao.isMainAdviser4Book(paramMap);
		if (isMainAdviser) {
			deleteBook4MainAdviser(bookId,adviserId,channelId);
		} else {
			deleteBook4ViceAdviser(bookId,adviserId,channelId);
		}

	}

	/**
	 * 删除主编辑书籍
	 * @param bookId 图书标识
	 * @param adviserId 编辑标识
	 * @param channelId 运营标识
	 */
	@Transactional(rollbackFor = Exception.class)
	public void deleteBook4MainAdviser(Long bookId, Long adviserId, Long channelId) {
		LOGGER.info("删除主编辑书籍<START>.[bookId]=" + bookId + ",[adviserId]=" + adviserId + ",channelId=" + channelId);
		// 查询是否有收益
		BigDecimal bookIncome = bookConsr.getBookIncomeInfo(bookId, channelId, adviserId);
		// 没有收益，删除主编辑的书，同时删除副编辑的书以及副编辑下所有关联内容
		if (bookIncome != null && bookIncome.compareTo(new BigDecimal(0))==1) {
			throw new BookBizException(BookBizException.NO_DELETE_ERROR, "该图书已产生收益,不能被删除！");
		} else {
			// 删除图书关联二维码
			qrcodeSceneConsr.deleteByBook(bookId, channelId, null);
			// 删除书籍编辑的状态
			updateBookAdviserStatus(bookId, null, channelId, null,null, null, null, null, null, BookConstant.BOOK_ADVISER_DELETE, null);
			// 删除读者端的书架的书籍
			bookcaseConsr.deleteBookForAdviser(bookId, channelId, adviserId);
		}
	}

	/**
	 * 删除副编辑书籍（编辑端）
	 *
	 * @param bookId
	 *            图书标识
	 * @param adviserId
	 *            编辑标识
	 * @param channelId
	 *            运营标识
	 */
	@Transactional(rollbackFor = Exception.class)
	public void deleteBook4ViceAdviser(Long bookId, Long adviserId, Long channelId) {
		LOGGER.info("删除副编辑书籍<START>.[bookId]=" + bookId + ",[adviserId]=" + adviserId + ",channelId=" + channelId);
		// 删除图书关联二维码
		qrcodeSceneConsr.deleteByBook(bookId, channelId, adviserId);
		// 删除书籍编辑的状态
		updateBookAdviserStatus(bookId, adviserId, channelId, null,null, null, null, null, null, BookConstant.BOOK_ADVISER_DELETE, null);
		// 删除读者端的书架的书籍
		bookcaseConsr.deleteBookForAdviser(bookId, channelId, adviserId);
	}

	/**
	 * 恢复书籍-编辑
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void recoverBook4Adviser(Long bookId, Long adviserId, Long channelId, Long templetId,Long secondTempletId,
									Long graLabelId, Long subLabelId, Long verLabelId, Long areaLabelId,
									Boolean recoverScene) {
		LOGGER.info("恢复书籍-编辑 <START>.[bookId]=" + bookId + ",adviserId=" + adviserId + ",channelId=" + channelId + " templetId= " + templetId + "secondTempletId=" + secondTempletId);
		checkIsHaveOtherAdviser(bookId, channelId, adviserId);
		// 恢复书籍编辑的状态
		updateBookAdviserStatus(bookId, adviserId, channelId, templetId, secondTempletId, graLabelId, subLabelId, verLabelId, areaLabelId, BookConstant.BOOK_ADVISER_NO_DELETE,BookConstant.MAIN_ADVISER);
		// 恢复图书关联的二维码 20190723-刘娜【ID1001264】社群书删除后，再创建时不要自动恢复
		if (recoverScene) {
			bookGroupBiz.recoverByBookId(bookId, channelId, adviserId);
			qrcodeSceneConsr.recoverByBook(bookId, channelId, adviserId);
		}

	}

	/**
	 * 修改书籍编辑的状态（删除或者恢复）
	 * @param bookId 圖書標識
	 * @param adviserId 编辑标识
	 * @param channelId 运营标识
	 * @param deleteStatus 删除状态
	 * @param isMainAdviser
	 * @param secondTempletId 第二级标题id
	 */
	private void updateBookAdviserStatus(Long bookId, Long adviserId, Long channelId, Long templetId,Long secondTempletId,
										 Long graLabelId, Long subLabelId, Long verLabelId, Long areaLabelId,
										 Integer deleteStatus, Integer isMainAdviser) {
		LOGGER.info("修改书籍编辑的状态（删除或者恢复） <START>.[bookId]=" + bookId + ",adviserId=" + adviserId + ",channelId="
				+ channelId + ",deleteStatus=" + deleteStatus+",isMainAdviser="+isMainAdviser+"templetId"+templetId);
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("bookId", bookId);
		paramMap.put("adviserId", adviserId);
		paramMap.put("channelId", channelId);
		paramMap.put("isMainAdviser", isMainAdviser);
		paramMap.put("status", deleteStatus);
		paramMap.put("templetId", templetId);
		paramMap.put("secondTempletId",secondTempletId);
		paramMap.put("graLabelId",graLabelId);
		paramMap.put("subLabelId",subLabelId);
		paramMap.put("verLabelId",verLabelId);
		paramMap.put("areaLabelId",areaLabelId);
		bookAdviserDao.updateBook4Adviser(paramMap);
		if (BookConstant.BOOK_ADVISER_DELETE.equals(deleteStatus)) {
            bookGroupBiz.deleteByBookId(bookId, channelId, adviserId);
        }
	}

	/**
	 * 获取编辑的图书总数
	 */
	@Override
	public CountDto getAdviserBookCount(Long adviserId) {
		LOGGER.info("获取编辑的图书总数 <START>.[adviserId]=" + adviserId);
		CountDto countDto = new CountDto();
		Integer count = bookAdviserDao.getAdviserBookCount(adviserId);
		countDto.setCount(count);
        Integer bookGroupCount = bookGroupDao.getBookGroupCount(adviserId);
        countDto.setBookGroupCount(bookGroupCount);
		return countDto;
	}

	/**
	 * 设置图书使用模板
	 */
	@Override
	public void setBookTemplet(BookAdviser bookAdviser) {
		LOGGER.info("设置图书使用模板【START】bookAdviser="+bookAdviser);
		bookAdviserDao.updateBookTemplet(bookAdviser);
	}
	@Override
	@ParamLog(value = "获取图书基本信息", isBefore = false, isAfterReturn = false)
	public Map<String, AdviserBookInfoDTO> listAdviserBookInfo(AviserBookInfoParam aviserBookInfoParam) {
		if (ListUtils.isEmpty(aviserBookInfoParam.getBookIds())) return null;
		List<AdviserBookInfoDTO> adviserBookInfoDTOS = bookAdviserDao.listAdviserBookInfo(aviserBookInfoParam);
		if (ListUtils.isEmpty(adviserBookInfoDTOS)) return null;
		Map<String, AdviserBookInfoDTO> adviserBookInfoDTOMap = new HashMap<>();
		for (AdviserBookInfoDTO adviserBookInfoDTO : adviserBookInfoDTOS) {
			adviserBookInfoDTOMap.put(adviserBookInfoDTO.getBookId() + "-" + adviserBookInfoDTO.getChannelId() + "-" + adviserBookInfoDTO.getAdviserId(), adviserBookInfoDTO);
		}
		return adviserBookInfoDTOMap;
	}

	@Override
	public Map<Long, BookCountAndAdviserIdDTO> getBookCountByAdviserId(BookCountByAdvisersDto bookCountByAdvisersDto) {
		return bookAdviserDao.getBookCountByAdviserId(bookCountByAdvisersDto);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void refactorData(Long parentId,Long originTempletId, Long secondTempletId) {
		LOGGER.info("begin refactorData");
		int effectRows = bookAdviserDao.updateBookBySecondTempletId(parentId,originTempletId,secondTempletId);
		LOGGER.info("refactorData effect rows : {}",effectRows);
		LOGGER.info("end refactorData");
	}

	@Override
	@ParamLog("获取编辑书刊列表(ERP项目用)")
	public PageBeanNew<ErpAdviserBookVO> listAdviserBook4Erp(String isbn, String uniqueNumber, String adviserName, Integer currentPage, Integer numPerPage) {
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("isbn", isbn);
		paramMap.put("uniqueNumber", uniqueNumber);
		if(!StringUtil.isEmpty(adviserName)) {
			List<Long> adviserIds = adviserConsr.getAdviserIdsByName(adviserName);
			if(CollectionUtils.isEmpty(adviserIds)) {
				return new PageBeanNew<>(currentPage, numPerPage, new ArrayList<>());
			}
			paramMap.put("adviserIds", adviserIds);
		}
		PageBeanNew<ErpAdviserBookVO> pageBeanNew = bookAdviserDao.listPageNew(new PageParam(currentPage, numPerPage), paramMap, "listAdviserBook4Erp");
		List<ErpAdviserBookVO> bookVOS = pageBeanNew.getRecordList();
		if(!CollectionUtils.isEmpty(bookVOS)) {
			List<Long> adviserIds = bookVOS.stream().filter(s -> s.getAdviserId() != null).map(ErpAdviserBookVO::getAdviserId).distinct().collect(Collectors.toList());
			Map<Long, String> adviserNameMap = adviserConsr.getNames(adviserIds);
			for (ErpAdviserBookVO bookVO : bookVOS) {
				Long adviserId = bookVO.getAdviserId();
				if(adviserId != null && adviserNameMap.containsKey(adviserId)) {
					bookVO.setAdviserName(adviserNameMap.get(adviserId));
				}
			}
		}
		return pageBeanNew;
	}

    /**
     * 设置书刊是否已下印状态
     */
	@Override
	public void setIsPrint(BookAdviser bookAdviser) throws BizException {
        if (null == bookAdviser.getBookId() || null == bookAdviser.getIsPrint()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "参数有误！");
        }
        bookAdviserDao.setIsPrint(bookAdviser);
    }
}
