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

import com.pcloud.book.base.enums.ProxyModeEnum;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.biz.BookFreezeBiz;
import com.pcloud.book.book.biz.BookFundBiz;
import com.pcloud.book.book.dao.BookFreezeDao;
import com.pcloud.book.book.dto.BookFreezeDto;
import com.pcloud.book.book.entity.BookFreeze;
import com.pcloud.book.book.entity.BookFund;
import com.pcloud.book.book.entity.ThawEarning;
import com.pcloud.book.book.vo.BookFreezeFilterVO;
import com.pcloud.book.book.vo.BookFreezeInfoDto;
import com.pcloud.book.consumer.erp.ErpConsr;
import com.pcloud.common.core.constant.MQTopicProducer;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.string.StringUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import cn.hutool.core.date.DateUtil;

/**
 * 图书冻结业务层实现类
 * 
 * @author lili
 * @date 2018/1/18 18:15
 */
@Component("bookFreezeBiz")
public class BookFreezeBizImpl implements BookFreezeBiz {

	/**
	 * 日志
	 */
	private static final Logger LOGGER = LoggerFactory.getLogger(BookFreezeBizImpl.class);
	@Autowired
	private BookFreezeDao bookFreezeDao;
	@Autowired
	private BookFundBiz bookFundBiz;
	@Autowired
	private AmqpTemplate amqpTemplate;
	@Autowired
	private ErpConsr erpConsr;

	/**
	 * 获取图书是否被冻结
	 */
	@Override
	public Boolean isFreeze(Long bookId) {
		LOGGER.info("获取图书是否被冻结参数：bookId=" + bookId);
		Boolean isFreeze = bookFreezeDao.isFreeze(bookId);
		return isFreeze;
	}

	/**
	 * 冻结收益
	 */
	@Override
	public void create(BookFreeze bookFreeze) {
		LOGGER.info("【图书收益冻结管理(平台端)】冻结收益,<START>.[bookFreeze]=" + bookFreeze.toString());
		// 校验冻结参数
		this.checkFundParam(bookFreeze);
		BookFreezeDto bookFreezeDto = this.getBaseById(bookFreeze.getBookId());
		if (bookFreezeDto != null) {
			throw new BookBizException(BookBizException.ERROR, "该图书已有冻结记录！");
		}
		try {
			bookFreezeDao.insert(bookFreeze);
			//同步到erp
			erpConsr.freezeFund(bookFreeze.getBookId(),bookFreeze.getFreezetime());
		} catch (Exception e) {
			LOGGER.error("【图书收益冻结管理(平台端)】冻结收益,<ERROR>.[bookFreezeDao.insert]" + e.getMessage(), e);
			throw new BookBizException(BookBizException.DB_DML_FAIL, "冻结收益失败！");
		}
	}

	/**
	 * 获取冻结信息
	 */
	@Override
	public BookFreezeDto getBaseById(Long bookId) {
		LOGGER.info("【图书收益冻结管理(平台端)】获取冻结信息,<START>.[bookId]=" + bookId);
		BookFreezeDto bookFreezeDto = new BookFreezeDto();
		try {
			bookFreezeDto = bookFreezeDao.getBaseById(bookId);
		} catch (Exception e) {
			LOGGER.error("【图书收益冻结管理(平台端)】获取冻结信息,<ERROR>.[bookFreezeDao.getBaseById]" + e.getMessage(), e);
			throw new BookBizException(BookBizException.DB_DML_FAIL, "获取冻结信息失败！");
		}
		return bookFreezeDto;
	}

	/**
	 * 解冻收益
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void thaw(ThawEarning thawEarning, Long partyId) {
		LOGGER.info("【图书收益冻结管理(平台端)】解冻收益,<START>.[thawEarning]=" + thawEarning);
		BookFreezeDto bookFreezeDto = this.getBaseById(thawEarning.getBookId());
		if (bookFreezeDto == null) {
			throw new BookBizException(BookBizException.ERROR, "该图书收益没有被冻结！");
		}
		BookFund bookFund = thawEarning.getBookFund();
		if (thawEarning.getIsFund().equals(1)) {// 被基金购买
			// 校验参数
			bookFund.setFromErp(thawEarning.getFromErp());
			this.checkFundParam(bookFund, bookFreezeDto.getFreezetime());
			bookFund.setProxyMode(bookFreezeDto.getProxyMode());
			bookFund.setTransferor(bookFreezeDto.getTransferor());
			bookFund.setCreatedUser(partyId);
			bookFund.setBookId(thawEarning.getBookId());
			bookFundBiz.create(bookFund);
		}
		Long bookFundId = bookFund == null ? null : bookFund.getBookFundId();
		try {
			bookFreezeDao.thaw(bookFundId,thawEarning.getBookId(), partyId);
			erpConsr.thawFund(thawEarning.getBookId(), DateUtil.now());
		} catch (Exception e) {
			LOGGER.error("【图书收益冻结管理(平台端)】解冻收益,<ERROR>.[bookFreezeDao.thaw]" + e.getMessage(), e);
			throw new BookBizException(BookBizException.DB_DML_FAIL, "解冻收益失败！");
		}
		thawEarning.setFreezetime(bookFreezeDto.getFreezetime());
		amqpTemplate.convertAndSend(MQTopicProducer.EXCHAGE, MQTopicProducer.BOOK_THAW, thawEarning);

	}

	/**
	 * 校验冻结收益实体的参数
	 *
	 * @param bookFreeze
	 */
	private void checkFundParam(BookFreeze bookFreeze) {
		if (null == bookFreeze.getBookId()) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "图书标识不能为空！");
		}
		if (null == bookFreeze.getFreezetime()) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "冻结时间不能为空！");
		}
		if(null == bookFreeze.getProxyMode()){
			bookFreeze.setProxyMode(ProxyModeEnum.NON_AGENT.value);
		}
		if(ProxyModeEnum.PROXY_MODE.value.equals(bookFreeze.getProxyMode())){
			if(StringUtil.isEmpty(bookFreeze.getTransferor())){
				throw new BookBizException(BookBizException.PARAM_IS_NULL, "转让方不能为空！");
			}else{
				if(bookFreeze.getTransferor().length()>30){
					throw new BookBizException(BookBizException.PARAM_IS_ERROR, "转让方名字长度过长！");
				}
			}

		}
		Date freezeDate = null;
		try {
			freezeDate = DateUtils.StringToDateTime(bookFreeze.getFreezetime());
		} catch (Exception e) {
			throw new BookBizException(BookBizException.TIME_FORMAT_ERROR, "日期格式不合法！");
		}
		if (freezeDate.before(new Date())) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "冻结时间必须大于当前日期！");
		}
	}

	/**
	 * 校验书刊基金参数
	 *
	 * @param bookFund
	 */
	private void checkFundParam(BookFund bookFund, Date freezetime) {
		if (bookFund.getFundName() == null) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "基金名称不能为空！");
		}
		if (bookFund.getPurchaseMoney() == null) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "购买金额不能为空！");
		}
		if (bookFund.getStartTime() == null || bookFund.getEndTime() == null) {
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "开始时间和结束时间均不能为空！");
		}
		if(ProxyModeEnum.IS_TRANSFEREE.value.equals(bookFund.getIsTransferor())){
			bookFund.setTransferor(bookFund.getFundName());
		}
		Date fundStartTime = null;
		try {
			fundStartTime = DateUtils.StringToDateTime(bookFund.getStartTime());
		} catch (Exception e) {
			throw new BookBizException(BookBizException.TIME_FORMAT_ERROR, "基金开始日期格式不合法！");
		}
		if (fundStartTime.before(freezetime)) {
			throw new BookBizException(BookBizException.PARAM_IS_ERROR, "基金开始日期必须大于冻结开始日期！");
		}
		if(null!=bookFund.getFromErp()){
			return;
		}
		if(StringUtil.isEmpty(bookFund.getContractNo())){
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "挂牌/合同编号不能为空！");
		}
		if(StringUtil.isEmpty(bookFund.getBatchNumber())){
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "批次号不能为空！");
		}
		if(bookFund.getContractNo().length()>30){
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "挂牌/合同编号不能超过30个字符！");
		}
		if(bookFund.getBatchNumber().length()>30){
			throw new BookBizException(BookBizException.PARAM_IS_NULL, "批次号不能超过30个字符！");
		}
	}

	/**
	 * 该书刊当前和以后基金冻结信息
	 */
	@Override
	public List<BookFreezeDto> getFreezeInfo(Long bookId) {
		LOGGER.info("【图书收益冻结】该书刊当前和以后基金冻结信息,<START>.[bookId]=" + bookId);
		if (bookId == null) {
			throw new BookBizException(BookBizException.FILED_NULL, "图书标识不能为空~");
		}
		List<BookFreezeDto> bookFundList = bookFreezeDao.getFreezeInfo(bookId);
		if (bookFundList == null) {
			bookFundList = new ArrayList<>();
		}
		return bookFundList;
	}

	/**
	 * 批量获取书刊当前和以后基金冻结信息
	 */
	@Override
	public List<BookFreezeDto> listFreezeInfo(List<Long> bookIds) {
		LOGGER.info("【图书收益冻结】批量获取书刊当前和以后基金冻结信息,<START>.[bookIds]=" + bookIds);
		if (ListUtils.isEmpty(bookIds)) {
			throw new BookBizException(BookBizException.FILED_NULL, "图书标识不能为空~");
		}
		List<BookFreezeDto> bookFundList = bookFreezeDao.listFreezeInfo(bookIds);
		if (bookFundList == null) {
			bookFundList = new ArrayList<>();
		}
		return bookFundList;
	}

	@Override
	public BookFreezeDto getById(Long bookId) {
		return bookFreezeDao.getInfoById(bookId);
	}

	@Override
	public Boolean setBookFreeze(Long bookId) {
		if (null == bookId) {
			return false;
		}
		BookFreezeDto bookFreezeDto = this.getBaseById(bookId);
		if (bookFreezeDto != null) {
			LOGGER.info("该图书已有冻结记录"+bookId);
			return true;
		}
		BookFreeze bookFreeze = new BookFreeze();
		bookFreeze.setBookId(bookId);
		Date tomorrow = DateUtils.getDayStart(DateUtils.addDay(new Date(), 1));
		bookFreeze.setFreezetime(DateUtils.formatDate(tomorrow, DateUtils.DATE_FORMAT_DATETIME));
		bookFreeze.setCreatedUser(0L);
		// 校验冻结参数
		this.checkFundParam(bookFreeze);
		try {
			bookFreezeDao.insert(bookFreeze);
			//同步到erp
			erpConsr.freezeFund(bookFreeze.getBookId(),bookFreeze.getFreezetime());
		} catch (Exception e) {
			LOGGER.error("【图书收益冻结(ERP)】冻结收益,<ERROR>.[bookFreezeDao.insert]" + e.getMessage(), e);
			return false;
		}
		return true;
	}

	@Override
	public List<Long> filterFreezeBook(List<Long> bookIds) {
		if (CollectionUtils.isEmpty(bookIds)) {
			return Collections.emptyList();
		}
		return bookFreezeDao.filterFreezeBook(bookIds);
	}

    @Override
	public List<Long> filterBook4Erp(BookFreezeFilterVO bookFreezeFilterVO) {
		Integer bookFreeze = bookFreezeFilterVO.getBookFreeze();
		String bookFreezeTimeBegin = bookFreezeFilterVO.getBookFreezeTimeBegin();
		String bookFreezeTimeEnd = bookFreezeFilterVO.getBookFreezeTimeEnd();
		if (bookFreeze == null && StringUtils.isAllBlank(bookFreezeTimeBegin, bookFreezeTimeEnd)) {
			return Collections.emptyList();
		}
		return bookFreezeDao.filterBook4Erp(bookFreeze, bookFreezeTimeBegin, bookFreezeTimeEnd);
	}

	@Override
	public List<BookFreezeInfoDto> listBookFreezeInfo(List<Long> bookIds) {
		return bookFreezeDao.listBookFreezeInfo(bookIds);
	}
}
