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

import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.clock.check.BookClockCheck;
import com.pcloud.book.clock.dao.BookClockKeywordDao;
import com.pcloud.book.clock.dto.BookClockKeywordDTO;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.resource.ProductConsr;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.group.biz.BookGroupClassifyBiz;
import com.pcloud.book.group.biz.GroupQrcodeBiz;
import com.pcloud.book.group.dao.AppTouchRecordDao;
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.dto.BookGroupDTO;
import com.pcloud.book.group.dto.GroupClassifyQrcodeDTO;
import com.pcloud.book.group.dto.PushAddUserMessageDTO;
import com.pcloud.book.group.entity.AppTouchRecord;
import com.pcloud.book.group.entity.GroupQrcode;
import com.pcloud.book.group.enums.TouchTypeEnum;
import com.pcloud.book.group.tools.SendWeixinRequestTools;
import com.pcloud.book.group.vo.GroupQrcodeBaseInfoVO;
import com.pcloud.book.keywords.biz.BookGuideBiz;
import com.pcloud.book.keywords.biz.BookKeywordBiz;
import com.pcloud.book.keywords.dao.BookGuideDao;
import com.pcloud.book.keywords.dao.BookGuideReplyDao;
import com.pcloud.book.keywords.dto.GuideDTO;
import com.pcloud.book.keywords.dto.KeywordDTO;
import com.pcloud.book.keywords.entity.BookGuide;
import com.pcloud.book.keywords.entity.BookGuideReply;
import com.pcloud.book.keywords.enums.ReplyTypeEnum;
import com.pcloud.book.keywords.vo.GuideVO;
import com.pcloud.book.keywords.vo.ReplyMessageVO;
import com.pcloud.book.keywords.vo.SetGuideVO;
import com.pcloud.book.keywords.vo.UpdateGuideVO;
import com.pcloud.channelcenter.wechat.dto.AccountSettingDto;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.string.StringUtil;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
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 lombok.extern.slf4j.Slf4j;

/**
 * @author lily
 * @date 2019/4/23 15:47
 */
@Slf4j
@Component("bookGuideBiz")
public class BookGuideBizImpl implements BookGuideBiz {
    @Autowired
    private BookGuideDao bookGuideDao;
    @Autowired
    private BookGroupDao bookGroupDao;
    @Autowired
    private BookGuideReplyDao bookGuideReplyDao;
    @Autowired
    private BookGroupClassifyBiz bookGroupClassifyBiz;
    @Autowired
    private QrcodeSceneConsr qrcodeSceneConsr;
    @Autowired
    private BookKeywordBiz bookKeywordBiz;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private ProductConsr productConsr;
    @Autowired
    private GroupQrcodeBiz groupQrcodeBiz;
    @Autowired
    private AppTouchRecordDao appTouchRecordDao;
    @Autowired
    private BookClockCheck bookClockCheck;
    @Autowired
    private BookClockKeywordDao bookClockKeywordDao;
    @Autowired
    private GroupQrcodeDao groupQrcodeDao;
    @Autowired
    private BookGroupClassifyDao bookGroupClassifyDao;

    @Override
    @ParamLog("新增欢迎语")
    @Transactional(rollbackFor = Exception.class)
    public void insertGuide(SetGuideVO setGuideVO, Long partyId) {
        if (setGuideVO.getClassifyId() == null) {
            setGuideVO.setClassifyId(0L);
        }
        checkReplyParam(setGuideVO.getReplyMessages());
        //获取图书相关信息
        BookGroupDTO bookGroupDTO = bookGroupDao.getDTOById(setGuideVO.getBookGroupId());
        if (bookGroupDTO == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "该社群码不存在！");
        }
        BookGuide bookGuide = new BookGuide();
        BeanUtils.copyProperties(setGuideVO, bookGuide);
        // 如果设置类型为按书设置则讲分类信息置空
        if (0 == setGuideVO.getSetType()) {
            setGuideVO.setClassifyId(0L);
        }
        bookGuide.setBookId(bookGroupDTO.getBookId());
        bookGuide.setChannelId(bookGroupDTO.getChannelId());
        bookGuide.setCreateUser(partyId);
        try {
            bookGuideDao.insert(bookGuide);
        } catch (DataIntegrityViolationException e) {
            throw new BookBizException(BookBizException.DB_DML_FAIL, "请勿重复设置！");
        }
        List<BookGuideReply> bookGuideReplies = setToBookGuideReply(setGuideVO.getReplyMessages(), bookGuide.getId(), partyId, bookGroupDTO.getChannelId());
        bookGuideReplyDao.insert(bookGuideReplies);
    }

    @ParamLog("设置回复参数")
    private List<BookGuideReply> setToBookGuideReply(List<ReplyMessageVO> replyMessages, Long bookGuideId, Long createUser, Long channelId) {
        List<BookGuideReply> bookGuideReplies = new ArrayList<>();
        List<Long> productIds = new ArrayList<>();
        for (ReplyMessageVO replyMessageVO : replyMessages) {
            BookGuideReply bookGuideReply = new BookGuideReply();
            BeanUtils.copyProperties(replyMessageVO, bookGuideReply);
            bookGuideReply.setBookGuideId(bookGuideId);
            bookGuideReply.setCreateUser(createUser);
            bookGuideReplies.add(bookGuideReply);
            if(ReplyTypeEnum.APP.value.equals(replyMessageVO.getReplyType()) && "PRODUCT".equalsIgnoreCase(replyMessageVO.getServeType())){
                productIds.add(replyMessageVO.getServeId());
            }
        }
        productConsr.productAutoOnShelves(channelId, productIds);
        return bookGuideReplies;
    }

    @ParamLog("校验参数")
    private void checkReplyParam(List<ReplyMessageVO> replyMessages) {
        if (ListUtils.isEmpty(replyMessages)) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "请设置入群欢迎语");
        }
        if (replyMessages.size() > 5) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "入群欢迎语超出5个限制");
        }
    }

    @Override
    @ParamLog("更新欢迎语")
    @Transactional(rollbackFor = Exception.class)
    public void updateGuide(UpdateGuideVO updateGuideVO, Long partyId) {
        List<ReplyMessageVO> replyMessages = updateGuideVO.getReplyMessages();
        if (ListUtils.isEmpty(replyMessages)) {
            //删除欢迎语回复
            bookGuideReplyDao.deleteByGuideId(updateGuideVO.getId());
            //删除欢迎语
            bookGuideDao.deleteById(updateGuideVO.getId());
        }else{
            if (replyMessages.size() > 5) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "入群欢迎语超出5个限制");
            }
            checkReplyParam(updateGuideVO.getReplyMessages());
            //获取欢迎语基本信息
            BookGuide bookGuideOld = bookGuideDao.getById(updateGuideVO.getId());
            if(bookGuideOld == null){
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "欢迎语不存在");
            }
            BookGuide bookGuide = new BookGuide();
            BeanUtils.copyProperties(updateGuideVO, bookGuide);
            bookGuideDao.update(bookGuide);
            //更新回复消息
            bookGuideReplyDao.deleteByGuideId(updateGuideVO.getId());
            List<BookGuideReply> bookGuideReplies = setToBookGuideReply(updateGuideVO.getReplyMessages(), bookGuide.getId(), partyId, bookGuideOld.getChannelId());
            bookGuideReplyDao.insert(bookGuideReplies);
        }
    }

    @Override
    @ParamLog("根据社群码获取欢迎语")
    public GuideVO getGuideByBookGroup(Long bookGroupId) {
        GuideVO guideVO = bookGuideDao.getGuideByBookGroup(bookGroupId);
        if (guideVO == null) {
            return new GuideVO();
        }
        //获取社群码回复内容
        List<ReplyMessageVO> messages = bookGuideReplyDao.getReplyMessage(guideVO.getId());
        guideVO.setReplyMessages(messages);
        return guideVO;
    }

    @Override
    @ParamLog("根据分类获取欢迎语")
    public GuideVO getGuideByClassify(Long classifyId) {
        GuideVO guideVO = bookGuideDao.getGuideByClassify(classifyId);
        if (guideVO == null) {
            return new GuideVO();
        }
        //获取社群码回复内容
        List<ReplyMessageVO> messages = bookGuideReplyDao.getReplyMessage(guideVO.getId());
        guideVO.setReplyMessages(messages);
        return guideVO;
    }


    @Override
    @ParamLog("推送欢迎语消息")
    public void sendGuideMessage(PushAddUserMessageDTO pushAddUserMessageDTO) {
        final String weixinGroupId = pushAddUserMessageDTO.getWeixinGroupId();
        //通过群id获取对应基本信息
        GroupClassifyQrcodeDTO classifyQrcodeInfo = bookGroupClassifyBiz.getClassifyQrcodeInfo(weixinGroupId);
        if(classifyQrcodeInfo == null){
            return;
        }
        //获取该书是否设置推送公众号
        GuideDTO bookGuide = getBaseInfo(null, classifyQrcodeInfo.getBookGroupId());
        //获取该分类是否设置过欢迎语
        GuideDTO classifyGuide = getBaseInfo(classifyQrcodeInfo.getClassifyId(), classifyQrcodeInfo.getBookGroupId());
        //获取推送消息机器人
        String robotId = pushAddUserMessageDTO.getRobotId();
        if(StringUtil.isBlank(robotId)) {
            log.info("[关键词消息回复] robotId is null robotId:{},weixinGroupId:{}", robotId, weixinGroupId);
            robotId = wechatGroupConsr.getRobotIdByGroupId(weixinGroupId);
        }
        //String robotId = "wxid_e6zsl8oohcnl22";
        // 判断是否需要发送
//        boolean canSend = false;
//        // 查看群成员
//        GroupInfoVO groupInfoVO = WxGroupSDK.getGroupInfo(weixinGroupId, robotId);
//        log.info("[查看群成员] : groupInfoVO:{}",groupInfoVO);
//        if (!CollectionUtils.isEmpty(groupInfoVO.getIdList())) {
//            // 查看该用户weixinid
//            final List<String> nickName = wechatGroupConsr.getWxUserIdsByNickName(pushAddUserMessageDTO.getNickName());
//            log.info("[查看该用户weixinid] : nickName:{}",nickName);
//            if(!CollectionUtils.isEmpty(nickName)) {
//                final Map<String, Boolean> map = Maps.newHashMap();
//                for (String s : groupInfoVO.getIdList()) {
//                    map.put(s, true);
//                }
//                for (String s : nickName) {
//                    if (null != map.get(s) && map.get(s)) {
//                        // 若在群设置true
//                        canSend = true;
//                        break;
//                    }
//                }
//            }
//        }
        // 判断是否黑名单
        final Boolean kickUser = wechatGroupConsr.isKickUser(pushAddUserMessageDTO.getNickName(), weixinGroupId);
//        log.info("[推送欢迎语消息]:pushAddUserMessageDTO:{},kickUser：{},canSend:{}", pushAddUserMessageDTO, kickUser,canSend);
        log.info("[推送欢迎语消息]:pushAddUserMessageDTO:{},kickUser：{}", pushAddUserMessageDTO, kickUser);
        // 在群，且非黑名单
//        canSend = canSend && !kickUser;
        if (kickUser) {
            log.info("[推送欢迎语消息]:不推送");
            return;
        }
        List<ReplyMessageVO> replyMessages = null;
        if (classifyGuide != null) {
            replyMessages = bookGuideReplyDao.getReplyMessage(classifyGuide.getId());
        } else if (bookGuide != null) {
            replyMessages = bookGuideReplyDao.getReplyMessage(bookGuide.getId());
        }
        //获取公众号基本信息
        AccountSettingDto wechatInfo = qrcodeSceneConsr.getWechatInfo(classifyQrcodeInfo.getChannelId());
        //获取关键词信息（改成10个了）
        List<KeywordDTO> keywords = bookKeywordBiz.listFiveKeyword(classifyQrcodeInfo.getClassifyId(), classifyQrcodeInfo.getBookGroupId());
        Boolean isHaveKeywords = !ListUtils.isEmpty(keywords);
        if (ListUtils.isEmpty(replyMessages)) {
            //获取群名称
            GroupQrcodeBaseInfoVO groupInfo = groupQrcodeBiz.getBaseById(classifyQrcodeInfo.getGroupQrcodeId());
            //推送消息
            SendWeixinRequestTools.sendDefaultMessage(groupInfo == null ? "" : groupInfo.getGroupName(), robotId, weixinGroupId, isHaveKeywords);
        } else {
            //处理链接
            handleUrl(replyMessages, wechatInfo, classifyQrcodeInfo);
            //推送消息
            SendWeixinRequestTools.sendGuideMessage(replyMessages, robotId, weixinGroupId);
            //新增欢迎语应用触发记录
            addGuideAppTouchRecord(replyMessages,weixinGroupId,classifyQrcodeInfo.getBookGroupId(),classifyQrcodeInfo.getClassifyId());
        }
        //获取关键词信息（改成10个了）
        SendWeixinRequestTools.sendKeywordsInfo(keywords, robotId, weixinGroupId);
        if (bookGuide != null && bookGuide.getIsRecommend() != null && bookGuide.getIsRecommend() == 1) {
            //推送公众号消息
            SendWeixinRequestTools.sendAccountMessage(weixinGroupId, bookGuide.getRecommendLanguage(), robotId, wechatInfo);
        }
        //校验该群是否与微信群打卡有关
        List<Long> bookClockInfoIdList = bookClockCheck.checkGroupIsClock(classifyQrcodeInfo);
        if(!ListUtils.isEmpty(bookClockInfoIdList)){
            Map<String,Object> paramMap = new HashMap<>();
            int i = 0;
            List<BookClockKeywordDTO> bookClockKeywordDTOList = new ArrayList<>();
            for (Long bookClockInfoId:bookClockInfoIdList) {
                i++;
                if(i >= 5){
                    break;
                }
                paramMap.put("bookClockInfoId",bookClockInfoId);
                List<BookClockKeywordDTO> bookClockKeywordDTOS = bookClockKeywordDao.getKeywordsByInfoId(paramMap);
                bookClockKeywordDTOList.addAll(bookClockKeywordDTOS);
                if(i%2 == 0){
                    log.info("欢迎语中推送关键词信息,bookClockKeywordDTOList="+bookClockKeywordDTOList);
                    SendWeixinRequestTools.sendClockKeywordsInfo(bookClockKeywordDTOList, robotId, weixinGroupId);
                    bookClockKeywordDTOList.clear();
                }else if(i == bookClockInfoIdList.size()){
                    SendWeixinRequestTools.sendClockKeywordsInfo(bookClockKeywordDTOList, robotId, weixinGroupId);
                    bookClockKeywordDTOList.clear();
                }

            }
        }
    }

    @Override
    public Map<String, Object> getGuideMessage(String weixinGroupId, String wexinGroupName) {
        Map<String, Object> map = new HashMap<>();
        List<ReplyMessageVO> replyMessages = new ArrayList<>();
        //通过群id获取对应基本信息
        GroupClassifyQrcodeDTO classifyQrcodeInfo = bookGroupClassifyBiz.getClassifyQrcodeInfo(weixinGroupId);
        if (classifyQrcodeInfo == null && !StringUtil.isEmpty(wexinGroupName)) {
            classifyQrcodeInfo = bookGroupClassifyDao.getClassifyQrcodeInfoByName(wexinGroupName);
        }
        if (null == classifyQrcodeInfo) {
            return map;
        }
        map.put("qrCodeUrl", classifyQrcodeInfo.getQrCodeUrl());
        //获取该书是否设置推送公众号
        GuideDTO bookGuide = getBaseInfo(null, classifyQrcodeInfo.getBookGroupId());
        //获取该分类是否设置过欢迎语
        GuideDTO classifyGuide = getBaseInfo(classifyQrcodeInfo.getClassifyId(), classifyQrcodeInfo.getBookGroupId());
        if (classifyGuide != null) {
            replyMessages = bookGuideReplyDao.getReplyMessage(classifyGuide.getId());
        } else if (bookGuide != null) {
            replyMessages = bookGuideReplyDao.getReplyMessage(bookGuide.getId());
        }
        //获取公众号基本信息
        AccountSettingDto wechatInfo = qrcodeSceneConsr.getWechatInfo(classifyQrcodeInfo.getChannelId());
        //获取关键词信息（改成10个了）
        List<KeywordDTO> keywords = bookKeywordBiz.listFiveKeyword(classifyQrcodeInfo.getClassifyId(), classifyQrcodeInfo.getBookGroupId());
        map.put("keywords", keywords);
        Boolean isHaveKeywords = !ListUtils.isEmpty(keywords);
        if (ListUtils.isEmpty(replyMessages)) {
            replyMessages = new ArrayList<>();
            ReplyMessageVO replyMessageVO = new ReplyMessageVO();
            String content = "";
            //获取群名称
            GroupQrcodeBaseInfoVO groupInfo = groupQrcodeBiz.getBaseById(classifyQrcodeInfo.getGroupQrcodeId());
            String groupName = groupInfo.getGroupName();
            if (StringUtil.isEmpty(groupName)) {
                content += " 欢迎加入本群!";
            } else {
                content += " 欢迎加入" + groupName + "！";
            }
            if (isHaveKeywords) {
                content = content + "本群目的为学习交流和学习辅导，线上资源和工具为图书的增值服务，可根据实际情况配合图书一起使用。凭以下关键词领取任务或资源：";
            }
            replyMessageVO.setContent(content);
            replyMessages.add(replyMessageVO);
        } else {
            //处理链接
            handleUrl(replyMessages, wechatInfo, classifyQrcodeInfo);
        }
        map.put("reply", replyMessages);
        return map;
    }

    /**
     * 新增欢迎语应用触发记录
     */
    private void addGuideAppTouchRecord(List<ReplyMessageVO> replyMessages, String weixinGroupId, Long bookGroupId, Long classifyId) {
        for (ReplyMessageVO replyMessageVO:replyMessages){
            if (ReplyTypeEnum.APP.value.equals(replyMessageVO.getReplyType())){
                AppTouchRecord appTouchRecord = new AppTouchRecord();
                appTouchRecord.setServeId(replyMessageVO.getServeId());
                appTouchRecord.setServeType(replyMessageVO.getServeType());
                appTouchRecord.setTouchType(TouchTypeEnum.GUIDE.value);
                appTouchRecord.setBookGroupId(bookGroupId);
                appTouchRecord.setClassifyId(classifyId);
                GroupQrcode groupQrcode = groupQrcodeDao.getGroupQrcodeByGroupId(weixinGroupId);
                if (groupQrcode != null) {
                    appTouchRecord.setQrcodeId(groupQrcode.getId());
                }
                appTouchRecord.setWeixinGroupId(weixinGroupId);
                appTouchRecordDao.insert(appTouchRecord);
            }
        }
    }

    @ParamLog("处理地址")
    private void handleUrl(List<ReplyMessageVO> replyMessages, AccountSettingDto accountSettingDto, GroupClassifyQrcodeDTO groupClassifyQrcodeDTO) {
        if (ListUtils.isEmpty(replyMessages)) {
            return;
        }
        for (ReplyMessageVO replyMessageVO : replyMessages) {
            if (ReplyTypeEnum.APP.value.equals(replyMessageVO.getReplyType()) || ReplyTypeEnum.LINK.value.equals(replyMessageVO.getReplyType())) {
                String linkUrl = SendWeixinRequestTools.splitUrlNew(accountSettingDto, replyMessageVO.getLinkUrl(), groupClassifyQrcodeDTO.getBookGroupId(), groupClassifyQrcodeDTO.getClassifyId(), groupClassifyQrcodeDTO.getGroupQrcodeId());
                replyMessageVO.setLinkUrl(linkUrl);
            }
        }
    }

    @ParamLog("获取欢迎设置基本信息")
    private GuideDTO getBaseInfo(Long classifyId, Long bookGroupId) {
        if (classifyId == null) {
            classifyId = 0L;
        }
        return bookGuideDao.getBaseInfo(classifyId, bookGroupId);
    }
}
