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

import com.google.common.collect.Lists;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.clock.biz.BookClockBiz;
import com.pcloud.book.clock.check.BookClockCheck;
import com.pcloud.book.clock.dao.BookClockInfoDao;
import com.pcloud.book.clock.dao.BookClockKeywordDao;
import com.pcloud.book.clock.dao.BookGroupClockDao;
import com.pcloud.book.clock.dto.BookClockInfoDTO;
import com.pcloud.book.clock.dto.BookClockKeywordDTO;
import com.pcloud.book.clock.dto.BookClockListDTO;
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.enums.OriginTypeEnum;
import com.pcloud.book.clock.enums.UpdateTypeEnum;
import com.pcloud.book.clock.set.BookGroupClockSet;
import com.pcloud.book.clock.vo.response.ListBookGroupClockResponseVO;
import com.pcloud.book.consumer.app.AppConsr;
import com.pcloud.book.consumer.resource.ProductConsr;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.group.dao.BookGroupClassifyDao;
import com.pcloud.book.group.dao.BookGroupDao;
import com.pcloud.book.group.dao.GroupQrcodeDao;
import com.pcloud.book.group.dao.WeixinQrcodeDao;
import com.pcloud.book.group.dto.BookGroupDTO;
import com.pcloud.book.group.dto.BookWxQrcodeDTO;
import com.pcloud.book.group.dto.ClassifyDTO;
import com.pcloud.book.weixinclock.biz.WeixinClockBiz;
import com.pcloud.book.weixinclock.dto.WeixinClockDto;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.page.PageBean;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.string.StringUtil;

import com.pcloud.facade.quartz.service.ScheduleService;
import com.sdk.wxgroup.SendTextMessageVO;
import com.sdk.wxgroup.WxGroupSDK;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
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.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @Author: hzk
 * @Date: 2019/5/24 14:50
 * @Version 1.0
 */
@Component("bookClockBiz")
public class BookClockBizImpl implements BookClockBiz {

    @Autowired
    private BookClockCheck bookClockCheck;
    @Autowired
    private BookGroupClockSet bookGroupClockSet;
    @Autowired
    private BookGroupClockDao bookGroupClockDao;
    @Autowired
    private BookClockInfoDao bookClockInfoDao;
    @Autowired
    private BookClockKeywordDao bookClockKeywordDao;
    @Autowired
    private AppConsr appConsr;
    @Autowired
    private ProductConsr productConsr;
    @Autowired
    private BookGroupDao bookGroupDao;
    @Autowired
    private BookGroupClassifyDao bookGroupClassifyDao;
    @Autowired
    private GroupQrcodeDao groupQrcodeDao;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private ScheduleService scheduleService;
    @Autowired
    private WeixinQrcodeDao weixinQrcodeDao;
    @Autowired
    private WeixinClockBiz weixinClockBiz;


    /**
     * 关联作品/应用及微信群
     * @param bookClockInfo
     */
    @Override
    @ParamLog("关联作品/应用及微信群")
    @Transactional(rollbackFor = Exception.class)
    public Long createBookGroupClock(BookClockInfo bookClockInfo)  throws BizException {
        Long originId = bookClockInfo.getOriginId();
        String originType = bookClockInfo.getOriginType();
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("originId",originId);
        paramMap.put("originType",originType);
        bookClockCheck.checkParam4CreateBookGroupClock(bookClockInfo);
        //校验作品/应用是否创建过
        paramMap.put("adviserId",bookClockInfo.getCreateUser());
        BookClockInfoDTO bookClockInfoDTO = bookClockInfoDao.getBaseInfoByMap(paramMap);
        if(null != bookClockInfoDTO){
            throw new BookBizException(BookBizException.ERROR,"该作品/应用不可重复创建！");
        }
        if(null == bookClockInfo.getIsNotice()){
            bookClockInfo.setIsNotice(false);
        }
        List<Long> bookGroupIdList = bookClockInfo.getBookGroupIdList();
        List<Long> classifyIdList = bookClockInfo.getClassifyIdList();
        //存储微信群打卡基本信息
        bookClockInfoDao.insert(bookClockInfo);
        Long bookClockInfoId = bookClockInfo.getBookClockInfoId();
        //存储关键词
        List<BookClockKeyword> bookClockKeywordList = bookClockInfo.getBookClockKeywordList();
        bookClockCheck.checkBookClockKeyword(bookClockKeywordList,bookClockInfo.getCreateUser(),bookGroupIdList,classifyIdList);
        //获取该作品/应用关键词最大排序值
        Long maxSequence4Keyword = bookClockKeywordDao.getMaxSequence4Keyword(bookClockInfoId);
        maxSequence4Keyword = null == maxSequence4Keyword ? 0L : maxSequence4Keyword;
        bookGroupClockSet.setData4BookClockKeyword(bookClockInfoId,bookClockInfo.getCreateUser(),maxSequence4Keyword,bookClockKeywordList);
        bookClockKeywordDao.batchInsert(bookClockKeywordList);
        //关联社群书
        List<Long> classifyIdsUnderBookGroup = new ArrayList<>();
        List<BookGroupClock> bookGroupClockList = new ArrayList<>();

        if(!ListUtils.isEmpty(bookGroupIdList)){
            List<BookGroupClock> list4BookGroupIds = bookGroupClockSet.setData4BookGroupClock(bookClockInfo, true, bookGroupIdList);
            bookGroupClockList.addAll(list4BookGroupIds);
            //获取社群书下面的所有分类
            classifyIdsUnderBookGroup = bookGroupClassifyDao.getIdByBookGroupIds(bookGroupIdList);
        }
        //关联分类
        if(!ListUtils.isEmpty(classifyIdList)){
            //过滤上面已选取的书下面的分类
            if(!ListUtils.isEmpty(classifyIdsUnderBookGroup)){
                classifyIdList.removeAll(classifyIdsUnderBookGroup);
            }
            List<BookGroupClock> list4ClassifyIds = bookGroupClockSet.setData4BookGroupClock(bookClockInfo, false, classifyIdList);
            bookGroupClockList.addAll(list4ClassifyIds);
        }
        //存储关联关系
        if(!ListUtils.isEmpty(bookGroupClockList)){
            bookGroupClockDao.batchInsert(bookGroupClockList);
        }
        //删除上面关联的书下的分类
        if(!ListUtils.isEmpty(classifyIdsUnderBookGroup)){
            paramMap.put("classifyIds",classifyIdsUnderBookGroup);
            bookGroupClockDao.deleteClassifyIdByBookGroupIds(paramMap);
        }
        if(bookClockInfo.getIsNotice()){
            bookGroupClockSet.createCronQuartz(bookClockInfo);
        }
        return bookClockInfoId;
    }

    /**
     * 修改关联关系
     * @param bookClockInfo
     * @throws BizException
     */
    @Override
    @ParamLog("修改关联关系")
    @Transactional(rollbackFor = Exception.class)
    public void updateBookGroupClock(BookClockInfo bookClockInfo) throws BizException {
        Long bookClockInfoId = bookClockInfo.getBookClockInfoId();
        BookClockInfoDTO bookClockInfoDTO = bookClockInfoDao.getBaseInfoById(bookClockInfoId);
        Long originId = bookClockInfoDTO.getOriginId();
        String originType = bookClockInfoDTO.getOriginType();
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("bookClockInfoId",bookClockInfoId);
        String updateType = bookClockInfo.getUpdateType();
        if(UpdateTypeEnum.APP.value.equalsIgnoreCase(updateType)){
            //修改作品/应用
            BookClockInfo newBookClockInfo = bookClockCheck.checkOriginIdAndOriginType(bookClockInfo);
            Long newOriginId = newBookClockInfo.getOriginId();
            String newOriginType = newBookClockInfo.getOriginType();
            String originTitle = newBookClockInfo.getOriginTitle();
            String originImg = newBookClockInfo.getOriginImg();
            String uniqueNumber = newBookClockInfo.getUniqueNumber();
            paramMap.put("newOriginId",newOriginId);
            paramMap.put("newOriginType",newOriginType);
            paramMap.put("originTitle",originTitle);
            paramMap.put("originImg",originImg);
            paramMap.put("uniqueNumber",uniqueNumber);
            bookClockInfoDao.updateBaseInfo4AppType(paramMap);
        }else if(UpdateTypeEnum.BOOK_GROUP.value.equalsIgnoreCase(updateType)){
            //修改关联的社群码
            List<BookGroupClock> bookGroupClockList = new ArrayList<>();
            List<Long> bookGroupIdList = bookClockInfo.getBookGroupIdList();
            List<Long> classifyIdList = bookClockInfo.getClassifyIdList();
            List<Long> classifyIdsUnderBookGroup = new ArrayList<>();
            if(ListUtils.isEmpty(bookGroupIdList) && ListUtils.isEmpty(classifyIdList)){
                throw new BookBizException(BookBizException.ERROR,"参数有误！");
            }
            //修改社群书
            //删除关联的旧的社群书
            bookGroupClockDao.deleteBookGroupId4AppType(paramMap);
            if(!ListUtils.isEmpty(bookGroupIdList)){
                List<BookGroupClock> list4BookGroupIds = bookGroupClockSet.setData4BookGroupClock(bookClockInfo, true, bookGroupIdList);
                bookGroupClockList.addAll(list4BookGroupIds);
                //获取社群书下面的所有分类
                classifyIdsUnderBookGroup = bookGroupClassifyDao.getIdByBookGroupIds(bookGroupIdList);
            }
            //修改关联的分类
            bookGroupClockDao.deleteClassifyId4AppType(paramMap);
            if(!ListUtils.isEmpty(classifyIdList)){
                if(!ListUtils.isEmpty(classifyIdsUnderBookGroup)){
                    classifyIdList.removeAll(classifyIdsUnderBookGroup);
                }
                List<BookGroupClock> list4ClassifyIds = bookGroupClockSet.setData4BookGroupClock(bookClockInfo, false, classifyIdList);
                bookGroupClockList.addAll(list4ClassifyIds);
            }
            //存储关联关系
            if(!ListUtils.isEmpty(bookGroupClockList)){
                bookGroupClockDao.batchInsert(bookGroupClockList);
            }
        }else if(UpdateTypeEnum.KEYWORD.value.equalsIgnoreCase(updateType)){
            //修改关键词
            List<BookClockKeyword> bookClockKeywordList = bookClockInfo.getBookClockKeywordList();
            //删除旧的关键词
            bookClockKeywordDao.deleteBookClockKeyword(paramMap);
            bookClockCheck.checkBookClockKeyword(bookClockKeywordList,bookClockInfo.getCreateUser(),bookClockInfo.getBookGroupIdList(),bookClockInfo.getClassifyIdList());
            bookGroupClockSet.setData4BookClockKeyword(bookClockInfoId,bookClockInfoDTO.getCreateUser(),0L,bookClockKeywordList);
            bookClockKeywordDao.batchInsert(bookClockKeywordList);
            //修改消息提醒
            if(null != bookClockInfo.getIsNotice() && bookClockInfo.getIsNotice()){
                if(StringUtil.isEmpty(bookClockInfo.getNoticeTime()) || StringUtil.isEmpty(bookClockInfo.getNoticeContent())){
                    throw new BookBizException(BookBizException.ERROR,"修改参数有误！");
                }
            }
            try{
                scheduleService.deleteJob("clockMsgConfig_"+bookClockInfoId,"book");
            }catch (Exception e){
                throw new BookBizException(BookBizException.ERROR,"删除定时任务失败！");
            }
            if(null != bookClockInfo.getIsNotice() && bookClockInfo.getIsNotice()){
                bookGroupClockSet.createCronQuartz(bookClockInfo);
            }
            paramMap.put("isNotice",bookClockInfo.getIsNotice());
            paramMap.put("noticeTime",bookClockInfo.getNoticeTime());
            paramMap.put("noticeContent",bookClockInfo.getNoticeContent());
            bookClockInfoDao.updateBaseInfo4KeywordType(paramMap);
        }else{
            throw new BookBizException(BookBizException.ERROR,"修改参数有误！");
        }
    }

    /**
     * 获取关联的基本信息
     * @param bookClockInfoId
     * @return
     */
    @Override
    public BookClockInfoDTO getBookGroupClockBaseInfo(Long bookClockInfoId) {
        BookClockInfoDTO bookClockInfoDTO = bookClockInfoDao.getBookGroupClockBaseInfo(bookClockInfoId);
        if(null == bookClockInfoDTO){
            return null;
        }
        //获取作品/应用关联的书及分类
        BookClockInfoDTO groupAndClassifyListByOrigin = bookGroupClockSet.getGroupAndClassifyListByInfoIds(Lists.newArrayList(bookClockInfoId));
        bookClockInfoDTO.setBookGroupIdList(groupAndClassifyListByOrigin.getBookGroupIdList());
        bookClockInfoDTO.setBookGroupDTOList(groupAndClassifyListByOrigin.getBookGroupDTOList());
        bookClockInfoDTO.setClassifyIdList(groupAndClassifyListByOrigin.getClassifyIdList());
        bookClockInfoDTO.setClassifyDTOList(groupAndClassifyListByOrigin.getClassifyDTOList());
        //关联的关键词
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("bookClockInfoId",bookClockInfoId);
        List<BookClockKeywordDTO> bookClockKeywordDTOS = bookClockKeywordDao.getKeywordsByInfoId(paramMap);
        bookClockInfoDTO.setBookClockKeywordDTOList(bookClockKeywordDTOS);
        return bookClockInfoDTO;
    }

    /**
     * 获取该编辑已选的超级作者作品及应用
     * @param adviserId
     * @return
     */
    @Override
    public Map<String,List<BookClockInfoDTO>> getAdviserHasSelected(Long adviserId) {
        Map<String,List<BookClockInfoDTO>> result = new HashMap<>();
        List<BookClockInfoDTO> bookClockInfoDTOList = bookClockInfoDao.getOriginIdAndTypeByAdviserId(adviserId);
        List<BookClockInfoDTO> appList = new ArrayList<>();
        List<BookClockInfoDTO> productList = new ArrayList<>();
        if (!ListUtils.isEmpty(bookClockInfoDTOList)) {
            for (BookClockInfoDTO bookClockInfoDTO:bookClockInfoDTOList) {
                BookClockInfoDTO newBookClockInfoDTO = new BookClockInfoDTO();
                if(OriginTypeEnum.APP.value.equals(bookClockInfoDTO.getOriginType())){
                    newBookClockInfoDTO.setBookClockInfoId(bookClockInfoDTO.getBookClockInfoId());
                    newBookClockInfoDTO.setOriginId(bookClockInfoDTO.getOriginId());
                    appList.add(newBookClockInfoDTO);
                }
                if(OriginTypeEnum.PRODUCT.value.equals(bookClockInfoDTO.getOriginType())){
                    newBookClockInfoDTO.setBookClockInfoId(bookClockInfoDTO.getBookClockInfoId());
                    newBookClockInfoDTO.setOriginId(bookClockInfoDTO.getOriginId());
                    productList.add(newBookClockInfoDTO);
                }
            }
            result.put("APP",appList);
            result.put("PRODUCT",productList);
        }
        return result;
    }

    @Override
    public PageBean listBookGroupClock(PageParam pageParam, Map<String, Object> paramMap) {
        //获取群打卡的列表
        PageBean pageBean = bookClockInfoDao.listBookGroupClock(pageParam, paramMap);
        List<Object> dtos = pageBean.getRecordList();
        if(ListUtils.isEmpty(dtos)){
            return new PageBean();
        }
        dtos = dtos.stream().map(o -> {
            BookClockListDTO dto = (BookClockListDTO) o;
            ListBookGroupClockResponseVO vo = ListBookGroupClockResponseVO.valueFromBookClockInfoDTO(dto);
            //社群书id
            List<Long> groupIds = dto.getBookGroupIdList();
            List<Long> groupClassifyIds = new ArrayList<>();
            //TODO 根据社群书ids获取所有的群分类id
            if (!CollectionUtils.isEmpty(groupIds)){
                groupClassifyIds = bookGroupClassifyDao.getIdByBookGroupIds(groupIds);
            }
            //群分类id
            List<Long> classifyIds = dto.getClassifyIdList();
            classifyIds.addAll(groupClassifyIds);
            vo.setClassifyCount(classifyIds.size());
            //TODO 获取二维码总数
            Integer qrcodeCount = 0;
            if (!CollectionUtils.isEmpty(classifyIds)){

                qrcodeCount = groupQrcodeDao.countByClassifyIds(classifyIds);
            }
            vo.setBookGroupQrcodeNum(qrcodeCount);
            return vo;
        }).collect(Collectors.toList());
        pageBean.setRecordList(dtos);
        return pageBean;
    }

    /**
     * 发送微信群打卡群发消息
     * @param map
     */
    @Override
    @ParamLog("发送微信群打卡群发消息")
    public void sendBookClockGroupMessage(Map<String, Object> map) {
        Long bookClockInfoId = ((Integer)map.get("bookClockInfoId")).longValue();
        //获取关键词基本信息
        BookClockInfoDTO bookClockInfoDTO = bookClockInfoDao.getBaseInfoById(bookClockInfoId);
        if(null != bookClockInfoDTO && bookClockInfoDTO.getIsNotice()){
            //获取关联的群
            Map<String,Object> paramMap = new HashMap<>();
            paramMap.put("bookClockInfoId",bookClockInfoId);
            List<BookGroupClockDTO> bookGroupClockDTOS = bookGroupClockDao.getBookGroupClockIds(paramMap);
            List<Long> allClassifyIds = new ArrayList<>();
            if(!ListUtils.isEmpty(bookGroupClockDTOS)){
                List<Long> bookGroupIds = bookGroupClockDTOS.stream().filter(bookGroupClockDTO -> 0 == bookGroupClockDTO.getClassifyId()).map(BookGroupClockDTO::getBookGroupId).collect(Collectors.toList());
                if(!ListUtils.isEmpty(bookGroupIds)){
                    List<Long> classifyIdsUnderBookGroup = bookGroupClassifyDao.getIdByBookGroupIds(bookGroupIds);
                    if(!ListUtils.isEmpty(classifyIdsUnderBookGroup)){
                        allClassifyIds.addAll(classifyIdsUnderBookGroup);
                    }
                }
                List<Long> classifyIds = bookGroupClockDTOS.stream().filter(bookGroupClockDTO -> 0 == bookGroupClockDTO.getBookGroupId()).map(BookGroupClockDTO::getClassifyId).collect(Collectors.toList());
                if(!ListUtils.isEmpty(classifyIds)){
                    allClassifyIds.addAll(classifyIds);
                }
                if(!ListUtils.isEmpty(allClassifyIds)){
                    //获取所有的微信群ID
                    List<String> weixinGroupIds = groupQrcodeDao.getWeixinGroupIdsByClassifyIdList(allClassifyIds);
                    if(!ListUtils.isEmpty(weixinGroupIds)){
                        Map<String, BookWxQrcodeDTO> wxQrcodeDTOMap = weixinQrcodeDao
                                .listByWxGroupIds(weixinGroupIds);
                        for (String weixinGroupId:weixinGroupIds) {
                            //获取机器人微信号
                            String altId = wechatGroupConsr.getRobotIdByGroupId(weixinGroupId);
                            SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
                            sendTextMessageVO.setWxGroupId(weixinGroupId);
                            sendTextMessageVO.setAltId(altId);
                            sendTextMessageVO.setContent(bookClockInfoDTO.getNoticeContent());
                            if(!MapUtils.isEmpty(wxQrcodeDTOMap) && wxQrcodeDTOMap.containsKey(weixinGroupId)){
                                sendTextMessageVO.setIp(wxQrcodeDTOMap.getOrDefault(weixinGroupId,new BookWxQrcodeDTO()).getWechatGroupIp());
                            }
                            WxGroupSDK.sendTextMessage(sendTextMessageVO);
                        }
                    }
                }
            }
        }
    }

    /**
     * 删除关联关系
     * @param bookClockInfoId
     * @param adviserId
     */
    @Override
    @ParamLog("删除关联关系")
    @Transactional(rollbackFor = Exception.class)
    public void deleteBookGroupClock(Long bookClockInfoId, Long adviserId) {
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("bookClockInfoId",bookClockInfoId);
        paramMap.put("adviserId",adviserId);
        //删除对应关联的书及分类
        bookGroupClockDao.deleteBookGroupClock(paramMap);
        //删除对应的关键词
        bookClockKeywordDao.deleteBookClockKeyword(paramMap);
        //删除对应的基本信息
        bookClockInfoDao.deleteBookClockInfo(paramMap);
        //删除定时任务
        try{
            scheduleService.deleteJob("clockMsgConfig_" + bookClockInfoId,"book");
        }catch (Exception e){
            throw new BookBizException(BookBizException.ERROR,"删除定时任务失败！");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dealOldData4WeixinClock() {
        new Thread(() -> {
            WeixinClockDto weixinClockDto = new WeixinClockDto();
            weixinClockDto.setClockGuide("每日打卡，养成良好习惯");
            weixinClockDto.setClockIntroduction("欢迎加入打卡，每天一次，养成良好习惯");
            weixinClockDto.setClockKeyword("每日打卡");
            List<BookClockInfoDTO> clockInfoIds = bookClockInfoDao.getAllClockInfoIds();
            if(!ListUtils.isEmpty(clockInfoIds)){
                for(BookClockInfoDTO bookClockInfoDTO: clockInfoIds){
                    List<Long> list1 = bookGroupClockDao.getClassifyIdsByBookGroupId(bookClockInfoDTO.getBookClockInfoId());
                    List<Long> list2 = bookGroupClockDao.getClassifyIdsByClassfyId(bookClockInfoDTO.getBookClockInfoId());
                    list1.addAll(list2);
                    List<Long> resultList = list1.stream().distinct().collect(Collectors.toList());
                    if(!ListUtils.isEmpty(resultList)) {
                        weixinClockDto.setCreateUser(bookClockInfoDTO.getCreateUser());
                        weixinClockDto.setLastModifiedUser(bookClockInfoDTO.getCreateUser());
                        weixinClockDto.setGroupClassifyIds(resultList);
                        weixinClockBiz.createWeixinClock(weixinClockDto);
                    }
                }
            }
        }).start();
    }
}
