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

import com.google.common.collect.Lists;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.clock.dao.BookGroupClockDao;
import com.pcloud.book.clock.dto.BookClockInfoDTO;
import com.pcloud.book.clock.dto.BookGroupClockDTO;
import com.pcloud.book.clock.entity.BookClockInfo;
import com.pcloud.book.clock.entity.BookClockKeyword;
import com.pcloud.book.clock.entity.BookGroupClock;
import com.pcloud.book.clock.set.BookGroupClockSet;
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.util.common.CommonUtils;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.facade.quartz.entity.CallBackParam;
import com.pcloud.facade.quartz.entity.ScheduleJob;
import com.pcloud.facade.quartz.service.ScheduleService;
import com.pcloud.message.config.exception.ConfigBizException;
import org.codehaus.jackson.JsonParseException;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: hzk
 * @Date: 2019/5/27 10:40
 * @Version 1.0
 */
@Component("bookGroupClockSet")
public class BookGroupClockSetImpl implements BookGroupClockSet {

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

    @Autowired
    private BookGroupClockDao bookGroupClockDao;
    @Autowired
    private BookGroupDao bookGroupDao;
    @Autowired
    private BookGroupClassifyDao bookGroupClassifyDao;
    @Autowired
    private ScheduleService scheduleService;

    /**
     * 封装bookGroupClock对象
     * @param bookClockInfo
     * @param isBookGroupId
     * @param ids
     * @return
     */
    @Override
    @ParamLog("封装bookGroupClock对象")
    public List<BookGroupClock> setData4BookGroupClock(BookClockInfo bookClockInfo, Boolean isBookGroupId, List<Long> ids) {
        List<BookGroupClock> bookGroupClockList = new ArrayList<>();
        for (Long id:ids) {
            BookGroupClock newBookGroupClock = new BookGroupClock();
            newBookGroupClock.setBookClockInfoId(bookClockInfo.getBookClockInfoId());
            newBookGroupClock.setChannelId(bookClockInfo.getChannelId());
            if(isBookGroupId){
                newBookGroupClock.setBookGroupId(id);
                newBookGroupClock.setClassifyId(0L);
            }else{
                newBookGroupClock.setBookGroupId(0L);
                newBookGroupClock.setClassifyId(id);
            }
            newBookGroupClock.setCreateUser(bookClockInfo.getCreateUser());
            newBookGroupClock.setUpdateUser(bookClockInfo.getUpdateUser());
            bookGroupClockList.add(newBookGroupClock);
        }
        return bookGroupClockList;
    }

    /**
     * 封装关键词对象
     * @param bookClockInfoId
     * @param sequence
     * @param bookClockKeywordList
     */
    @Override
    @ParamLog("封装关键词对象")
    public void setData4BookClockKeyword(Long bookClockInfoId,Long adviserId, Long sequence,List<BookClockKeyword> bookClockKeywordList) {
        for (BookClockKeyword bookClockKeyword:bookClockKeywordList) {
            if(StringUtil.isEmpty(bookClockKeyword.getOperation()) || StringUtil.isEmpty(bookClockKeyword.getKeyword())
                    || StringUtil.isEmpty(bookClockKeyword.getGuide())){
                throw new BookBizException(BookBizException.ERROR,"关键词参数有误！");
            }
            bookClockKeyword.setBookClockInfoId(bookClockInfoId);
            bookClockKeyword.setSequenceNum(++sequence);
            bookClockKeyword.setCreateUser(adviserId);
            bookClockKeyword.setUpdateUser(adviserId);
        }
    }

    /**
     * 根据作品/应用获取关联的社群书及分类集合
     * @param bookClockInfoIds
     * @return
     */
    @Override
    @ParamLog("根据作品/应用获取关联的社群书及分类集合")
    public BookClockInfoDTO getGroupAndClassifyListByInfoIds(List<Long> bookClockInfoIds) {
        BookClockInfoDTO bookClockInfoDTO = new BookClockInfoDTO();
        //关联的社群码
        List<BookGroupClockDTO> bookGroupClockDTOS = bookGroupClockDao.getInfoByInfoIds(bookClockInfoIds);
        if(!ListUtils.isEmpty(bookGroupClockDTOS)){
            List<Long> bookGroupIds = bookGroupClockDTOS.stream().filter(bookGroupClockDTO -> 0 == bookGroupClockDTO.getClassifyId()).map(BookGroupClockDTO::getBookGroupId).collect(Collectors.toList());
            if(!ListUtils.isEmpty(bookGroupIds)){
                bookClockInfoDTO.setBookGroupIdList(bookGroupIds);
                List<BookGroupDTO> bookGroupDTOS = bookGroupDao.getBookBaseInfoByIds(bookGroupIds);
                bookClockInfoDTO.setBookGroupDTOList(bookGroupDTOS);
            }
            List<Long> classifyIds = bookGroupClockDTOS.stream().filter(bookGroupClockDTO -> 0 == bookGroupClockDTO.getBookGroupId()).map(BookGroupClockDTO::getClassifyId).collect(Collectors.toList());
            if(!ListUtils.isEmpty(classifyIds)){
                bookClockInfoDTO.setClassifyIdList(classifyIds);
                List<ClassifyDTO> classifyDTOS = bookGroupClassifyDao.getNameWithBookNameByIds(classifyIds);
                bookClockInfoDTO.setClassifyDTOList(classifyDTOS);
            }
        }
        return bookClockInfoDTO;
    }

    /**
     * 创建定时任务
     * @param bookClockInfo
     */
    @Override
    @ParamLog("创建定时任务")
    public void createCronQuartz(BookClockInfo bookClockInfo) {
        try {
            ScheduleJob job = new ScheduleJob();
            String jobName = "clockMsgConfig_" + bookClockInfo.getBookClockInfoId();
            StringBuffer cron = new StringBuffer();
            try {
                String noticeTime = bookClockInfo.getNoticeTime();
                int hour = Integer.parseInt(noticeTime.substring(0,2));
                int minute = Integer.parseInt(noticeTime.substring(3,5));
                int second = Integer.parseInt(noticeTime.substring(6,8));
                cron.append(second).append(" ").append(minute).append(" ").append(hour)
                        .append(" ").append("*").append(" ").append("*").append(" ").append("?").append(" ").append("*");
            } catch (Exception e) {
                throw new BookBizException(BookBizException.ERROR, "时间格式错误");
            }
            //定时器任务
            job.setJobName(jobName);
            //cron表达式
            job.setCronExpression(cron.toString());
            //定时器分组
            job.setJobGroup("book");
            CallBackParam param = new CallBackParam();
            //service名称
            param.setBeanName("bookClockInfoService");
            //回调内部接口方法名称
            param.setMethodName("sendBookClockGroupMessage");
            //设置回调参数
            Map<String, Object> map = new HashMap<>();
            map.put("bookClockInfoId", bookClockInfo.getBookClockInfoId());
            param.setParamMap(map);
            Map<String, Object> scheduleMap = new HashMap<>();
            scheduleMap.put("scheduleJob", job);
            scheduleMap.put("callBackParam", param);
            scheduleService.addCronJob(scheduleMap);
        } catch (JsonParseException e) {
            LOGGER.error("----------调用定时器方法【addCronJob】出现异常:" + e.getMessage(), e);
            throw new ConfigBizException(ConfigBizException.FAIL, "操作失败!");
        } catch (SchedulerException e) {
            LOGGER.error("----------调用定时器方法【addCronJob】出现异常:" + e.getMessage(), e);
            throw new ConfigBizException(ConfigBizException.FAIL, "操作失败!");
        }
    }

    /**
     * 获取书集合与分类集合的重复部分
     * @param bookGroupIds
     * @param classifyIds
     * @param returnBookId
     * @return
     */
    @Override
    public List<Long> getSameClassifyUnderBookGroup(List<Long> bookGroupIds, List<Long> classifyIds, boolean returnBookId) {
        if(ListUtils.isEmpty(bookGroupIds)){
            return null;
        }
        if(ListUtils.isEmpty(classifyIds)){
            return null;
        }
        List<Long> result = new ArrayList<>();
        //获取书下分类集合
        for (Long bookGroupId:bookGroupIds) {
            List<Long> idByBookGroupIds = bookGroupClassifyDao.getIdByBookGroupIds(Lists.newArrayList(bookGroupId));
            List<Long> sameEle = CommonUtils.getSameEle(idByBookGroupIds, classifyIds);
            if(!ListUtils.isEmpty(sameEle)){
                if(returnBookId){
                    result.add(bookGroupId);
                }else{
                    result.addAll(sameEle);
                }
            }
        }
        return result;
    }
}
