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

import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.copyright.biz.BookAuthUserBiz;
import com.pcloud.book.copyright.dao.BookAuthUserDao;
import com.pcloud.book.copyright.dao.BookClickBuyRecordDao;
import com.pcloud.book.copyright.dto.DateDTO;
import com.pcloud.book.copyright.entity.BookAuthUser;
import com.pcloud.book.copyright.entity.BookClickBuyRecord;
import com.pcloud.book.copyright.tools.CopyrightTools;
import com.pcloud.book.copyright.vo.BookAuthCodeUserVO;
import com.pcloud.book.copyright.vo.BookClickBuyRecordParam;
import com.pcloud.book.copyright.vo.ProvinceTop10VO;
import com.pcloud.book.copyright.vo.SixMonthCountVO;
import com.pcloud.book.copyright.vo.ThirtyDayCountVO;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author lily
 * @date 2018/12/4 15:54
 */
@Component("bookAuthUserBiz")
public class BookAuthUserBizImpl implements BookAuthUserBiz {
    private static final Logger LOGGER = LoggerFactory.getLogger(BookAuthUserBizImpl.class);
    @Autowired
    private BookAuthUserDao bookAuthUserDao;
    @Autowired
    private BookClickBuyRecordDao bookClickBuyRecordDao;

    private static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(4);

    @ParamLog(value = "获取授权用户数量")
    @Override
    public BookAuthCodeUserVO getAuthUserCount(Long bookId, Long channelId, Long adviserId) {
        if (bookId == null || channelId == null || adviserId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "图书不存在");
        }
        BookAuthCodeUserVO bookAuthCodeUserVO = bookAuthUserDao.getAuthUserCount(bookId, channelId, adviserId);
        if (bookAuthCodeUserVO != null) {
            bookAuthCodeUserVO.setCodeUserCount(bookAuthCodeUserVO.getTotalCount() - bookAuthCodeUserVO.getPayUserCount());
        } else {
            bookAuthCodeUserVO = new BookAuthCodeUserVO();
            bookAuthCodeUserVO.setCodeUserCount(0);
            bookAuthCodeUserVO.setPayUserCount(0);
        }
        return bookAuthCodeUserVO;
    }

    @Override
    public BookAuthCodeUserVO getAuthUserCountByMonth(Long bookId, Long channelId, Long adviserId, String monthDate) {
        if (bookId == null || channelId == null || adviserId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "图书不存在");
        }
        BookAuthCodeUserVO bookAuthCodeUserVO = bookAuthUserDao.getAuthUserCountByMonth(bookId, channelId, adviserId, monthDate);
        if (bookAuthCodeUserVO != null && bookAuthCodeUserVO.getTotalCount() != null && bookAuthCodeUserVO.getPayUserCount() != null) {
            bookAuthCodeUserVO.setCodeUserCount(bookAuthCodeUserVO.getTotalCount() - bookAuthCodeUserVO.getPayUserCount());
        }
        return bookAuthCodeUserVO;
    }

    @Override
    public List<ThirtyDayCountVO> listThirtyDay(Long bookId, Long channelId, Long adviserId, String province) {
        DateDTO date = CopyrightTools.getDateByType(30L);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("startDate", date.getStartTime());
        paramMap.put("endDate", date.getEndTime());
        paramMap.put("bookId", bookId);
        paramMap.put("channelId", channelId);
        paramMap.put("adviserId", adviserId);
        paramMap.put("province", province);
        List<ThirtyDayCountVO>  thirtyDayCountVOS = bookAuthUserDao.listThirtyDay(paramMap);
        setZoreRecord(thirtyDayCountVOS, date.getStartTime(), date.getEndTime());
        return thirtyDayCountVOS;
    }

    /**
     * 填充0
     */
    public void setZoreRecord(List<ThirtyDayCountVO> thirtyDayCountVOS, String startDate, String endDate) {
        // 计算开始时间和结束时间相差多少天，含当天所以要+1
        int dateDiff = (int) (DateUtils.getDateDiff(startDate, endDate) + 1);
        List<String> dates = DateUtils.getLastDays(endDate, dateDiff);
        for (String date : dates) {
            boolean bool = false;
            for (ThirtyDayCountVO thirtyDayCountVO : thirtyDayCountVOS) {
                if (date.equals(thirtyDayCountVO.getDate())) {
                    bool = true;
                    thirtyDayCountVO.setCodeUserCount(thirtyDayCountVO.getTotalCount()-thirtyDayCountVO.getPayUserCount());
                }
            }

            if (!bool) {
                ThirtyDayCountVO thirtyDayCountVO = new ThirtyDayCountVO();
                thirtyDayCountVO.setDate(date);
                thirtyDayCountVO.setCodeUserCount(0);
                thirtyDayCountVO.setPayUserCount(0);
                thirtyDayCountVOS.add(thirtyDayCountVO);
            }
        }
        thirtyDayCountVOS
                .sort((ThirtyDayCountVO dto1, ThirtyDayCountVO dto2) -> dto1.getDate().compareTo(dto2.getDate()));
    }

    @Override
    public List<SixMonthCountVO> listSixMonth(Long bookId, Long channelId, Long adviserId, String province) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("bookId", bookId);
        paramMap.put("channelId", channelId);
        paramMap.put("adviserId", adviserId);
        paramMap.put("province", province);
        paramMap.put("months", CopyrightTools.getLast6Months());
        List<SixMonthCountVO> sixMonthCountVOS = bookAuthUserDao.listSixMonth(paramMap);
        setZoreRecord(sixMonthCountVOS);
        return sixMonthCountVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insert(BookAuthUser bookAuthUser) {
        bookAuthUser.setMonths(new SimpleDateFormat("yyyy-MM").format(new Date()));
        bookAuthUserDao.insert(bookAuthUser);
    }

    @Override
    @ParamLog("校验用户是否已经授权")
    public Boolean checkIsHaveAuth(Long bookId, Long channelId, Long adviserId, Long wechatUserId) {
        return bookAuthUserDao.getIsHaveAuth(bookId, channelId, adviserId, wechatUserId);
    }

    @Override
    public BookAuthCodeUserVO getAuthUserTotalCount(List<Long> adviserIds, List<Long> removeAdviserIds) {
        BookAuthCodeUserVO bookAuthCodeUserVO = bookAuthUserDao.getAuthUserTotalCount(adviserIds, removeAdviserIds);
        if(bookAuthCodeUserVO != null){
            bookAuthCodeUserVO.setCodeUserCount(bookAuthCodeUserVO.getTotalCount() - bookAuthCodeUserVO.getPayUserCount());
        }
        return bookAuthCodeUserVO;
    }

    @Override
    @ParamLog("新增点击购买链接记录")
    public void insertClickBuyRecord(BookClickBuyRecordParam bookClickBuyRecordParam, Long channelId, Long wechatUserId) {
        EXECUTOR_SERVICE.execute(() -> {
            try {
                BookClickBuyRecord bookClickBuyRecord = new BookClickBuyRecord();
                bookClickBuyRecord.setChannelId(channelId);
                bookClickBuyRecord.setWechatUserId(wechatUserId);
                BeanUtils.copyProperties(bookClickBuyRecordParam, bookClickBuyRecord);
                bookClickBuyRecordDao.insert(bookClickBuyRecord);
            } catch (Exception e) {
                LOGGER.error("新增点击购买链接记录" + bookClickBuyRecordParam);
            }
        });
    }

    @Override
    @ParamLog("省份排名前10")
    public List<ProvinceTop10VO> listTop10ByBook(Long bookId, Long channelId, Long adviserId, Integer type) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("bookId", bookId);
        paramMap.put("channelId", channelId);
        paramMap.put("adviserId", adviserId);
        if (type != null && type == 0) {
            DateDTO date = CopyrightTools.getDateByType(30L);
            paramMap.put("startDate", date.getStartTime());
            paramMap.put("endDate", date.getEndTime());
        }else if(type != null && type == 1){
            paramMap.put("months", CopyrightTools.getLast6Months());
        }
        List<ProvinceTop10VO> top10ByBook = bookAuthUserDao.listTop10ByBook(paramMap);
        if (!ListUtils.isEmpty(top10ByBook)) {
            for (ProvinceTop10VO provinceTop10VO : top10ByBook) {
                if (provinceTop10VO.getTotalCount() != null && provinceTop10VO.getPayUserCount() != null) {
                    provinceTop10VO.setCodeUserCount(provinceTop10VO.getTotalCount() - provinceTop10VO.getPayUserCount());
                }

            }
        }
        return top10ByBook;
    }

    /**
     * 设置最近6月为空得书
     */
    private void setZoreRecord(List<SixMonthCountVO> sixMonthCountVOS) {
        List<String> last6Months = CopyrightTools.getLast6Months();
        for (String month : last6Months) {
            boolean bool = false;
            for (SixMonthCountVO sixMonthCountVO : sixMonthCountVOS) {
                if (month.equals(sixMonthCountVO.getDate())) {
                    bool = true;
                    sixMonthCountVO.setCodeUserCount(sixMonthCountVO.getTotalCount() - sixMonthCountVO.getPayUserCount());
                }
            }
            if (!bool) {
                SixMonthCountVO sixMonthCountVO = new SixMonthCountVO();
                sixMonthCountVO.setDate(month);
                sixMonthCountVO.setCodeUserCount(0);
                sixMonthCountVO.setPayUserCount(0);
                sixMonthCountVO.setTotalCount(0);
                sixMonthCountVOS.add(sixMonthCountVO);
            }
        }
        sixMonthCountVOS
                .sort((SixMonthCountVO dto1, SixMonthCountVO dto2) -> dto1.getDate().compareTo(dto2.getDate()));
    }

}
