package com.pcloud.book.push.check;

import com.pcloud.book.base.dto.ReplyParamDTO;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.keywords.enums.ReplyTypeEnum;
import com.pcloud.book.push.dto.SelfPushAddParamDTO;
import com.pcloud.book.push.entity.MorningEveningNews;
import com.pcloud.book.push.entity.Push;
import com.pcloud.book.push.entity.PushGroup;
import com.pcloud.book.push.entity.PushItem;
import com.pcloud.book.push.entity.SelfPushItem;
import com.pcloud.book.push.enums.ItemTypeEnum;
import com.pcloud.book.push.enums.PushTypeEnum;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.core.constant.SystemCode;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.string.StringUtil;

import org.springframework.stereotype.Component;

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

/**
 * @Description
 * @Author ruansiyuan
 * @Date 2019/4/18 15:48
 **/
@Component("pushCheck")
public class PushCheck {

    /**
     * 创建群发参数校验
     *
     * @param push
     */
    @ParamLog("创建群发参数校验")
    public void createPushParamCheck(Push push) {
        if (push == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "参数为空！");
        }
        if (push.getPushType() == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "群发类型不能为空！");
        }
        checkPushTime(push);
        if (push.getStartTime() != null && (push.getStartTime().getTime() - DateUtils.getDayStart(new Date()).getTime() < 0)) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "开始时间必须在现在时间之后！");
        }
        if (push.getEndTime() != null && (push.getEndTime().getTime() - System.currentTimeMillis() <= 0)) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "结束时间必须在现在时间之后！");
        }
        if (push.getStartTime() != null && push.getEndTime() != null && push.getStartTime().getTime() - push.getEndTime().getTime() > 0) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "开始时间必须在结束时间之前！");
        }
        checkHasDayToSend(push);
        if (ListUtils.isEmpty(push.getPushGroups())) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送群不能为空！");
        }
        if (ListUtils.isEmpty(push.getPushItems())) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项不能为空！");
        }
        if (push.getPushItems().size() > 4) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "群发消息项不能超过4条！");
        }
        for (PushGroup pushGroup : push.getPushGroups()) {
            if (pushGroup == null) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送群不能为空！");
            }
            if (pushGroup.getBookId() == null) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送群书id不能为空！");
            }
            if (pushGroup.getClassifyId() == null) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送群分类id不能为空！");
            }
            if (pushGroup.getBookGroupQrcodeId()==null) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送群二维码id不能为空！");
            }
        }
        for (PushItem pushItem : push.getPushItems()) {
            if (pushItem == null) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项不能为空！");
            }
            if (pushItem.getItemType() == null) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型不能为空！");
            }
            if (ItemTypeEnum.TEXT.value.equals(pushItem.getItemType()) && StringUtil.isEmpty(pushItem.getTextContent())) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为文本时，文本不能为空！");
            }
            if (ItemTypeEnum.LINK.value.equals(pushItem.getItemType()) && StringUtil.isEmpty(pushItem.getLinkUrl())) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为链接时，链接不能为空！");
            }
            if (ItemTypeEnum.APP.value.equals(pushItem.getItemType()) && (pushItem.getAppId() == null && pushItem.getProductId() == null)) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为应用或作品时，应用id或作品id不能为空！");
            }
            if (ItemTypeEnum.APP.value.equals(pushItem.getItemType()) && pushItem.getAppId() != null && StringUtil.isEmpty(pushItem.getAppUrl())) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为应用时，应用链接不能为空！");
            }
            if (ItemTypeEnum.APP.value.equals(pushItem.getItemType()) && pushItem.getProductId() != null && StringUtil.isEmpty(pushItem.getProductUrl())) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为作品时，作品链接不能为空！");
            }
            if (ItemTypeEnum.IMAGE.value.equals(pushItem.getItemType()) && StringUtil.isEmpty(pushItem.getImageUrl())) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为图片时，图片不能为空！");
            }
        }

    }

    /**
     * 校验时间有效性
     */
    private void checkHasDayToSend(Push push) {
        if (push.getStartTime() != null && push.getEndTime() != null) {
            if (PushTypeEnum.DAY.value.equals(push.getPushType())) {
                Date endTime = push.getEndTime();
                Date now = new Date();
                String pushTime = push.getPushTime();
                if (DateUtils.getDayStart(endTime).getTime() == DateUtils.getDayStart(now).getTime()) {
                    if (DateUtils.getDateFromString(pushTime, "HH:mm:ss").getTime()
                            < DateUtils.getDateFromString(DateUtils.getStrFormTime("HH:mm:ss", new Date()), "HH:mm:ss").getTime()) {
                        throw new BookBizException(BookBizException.PARAM_IS_ERROR, "时间填写错误，没有有效的群发时间，请重新选取！");
                    }
                }
            }
            if (PushTypeEnum.WEEK.value.equals(push.getPushType()) && push.getWeekDay() != null && push.getEndTime() != null) {
                Date endDay = push.getEndTime();
                Integer weekDay = push.getWeekDay();
                String pushTime = push.getPushTime();
                if (weekDay == 7) {
                    weekDay = 1;
                } else {
                    weekDay = weekDay + 1;
                }
                List<String> list = new ArrayList<>();
                for (Date i = new Date(); !i.after(endDay); i = DateUtils.addDay(i, 1)) {
                    if (weekDay == DateUtils.getWeekIndex(i)) {
                        list.add(DateUtils.formatDate(i, "yyyy-MM-dd"));
                    }
                }
                if (ListUtils.isEmpty(list)) {
                    throw new BookBizException(BookBizException.PARAM_IS_ERROR, "时间填写错误，没有有效的群发时间，请重新选取！");
                }
                if (list.size() == 1) {
                    String s = list.get(0);
                    Date date1 = DateUtils.getDateFromString(s, "yyyy-MM-dd");
                    date1 = DateUtils.addHour(date1, new Integer(pushTime.substring(0, 2)));
                    date1 = DateUtils.addMinute(date1, new Integer(pushTime.substring(3, 5)));
                    date1 = DateUtils.addMinute(date1, new Integer(pushTime.substring(6, 8)));
                    Long sl = date1.getTime();
                    Long sll = new Date().getTime();
                    if (sl < sll) {
                        throw new BookBizException(BookBizException.PARAM_IS_ERROR, "时间填写错误，没有有效的群发时间，请重新选取！");
                    }
                }
            }
        }
    }

    /**
     * 校验时间
     *
     * @param push
     */
    public void checkPushTime(Push push) {
        if (push == null) {
            return;
        }
        if (PushTypeEnum.DAY.value.equals(push.getPushType()) || PushTypeEnum.ONE.value.equals(push.getPushType()) || PushTypeEnum.WEEK.value.equals(push.getPushType())) {
            if (StringUtil.isEmpty(push.getPushTime())) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "设置为定时发送时发送时间不能为空！");
            }
            if (PushTypeEnum.ONE.value.equals(push.getPushType())) {
                Date pushOneDate = DateUtils.StringToDateTime(push.getPushTime());
                if (pushOneDate == null) {
                    throw new BookBizException(BookBizException.PARAM_IS_ERROR, "时间格式错误，应为2019-01-01 12:00:00！");
                }
                if (pushOneDate.getTime() - System.currentTimeMillis() <= 0) {
                    throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送时间不能早于当前时间！");
                }
            }
            if (PushTypeEnum.DAY.value.equals(push.getPushType()) || PushTypeEnum.WEEK.value.equals(push.getPushType())) {
                if (!push.getPushTime().matches("([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$")) {
                    throw new BookBizException(BookBizException.PARAM_IS_ERROR, "时间格式不对，应为HH:mm:ss！");
                }
            }
            if (PushTypeEnum.WEEK.value.equals(push.getPushType())) {
                if (push.getWeekDay() == null) {
                    throw new BookBizException(BookBizException.PARAM_IS_ERROR, "周几不能为空！");
                }
            }
        }
    }

    /**
     * 更新群发参数校验
     * @param push
     */
    public void updatePushParamCheck(Push push) {
        createPushParamCheck(push);
        if (push.getId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "群发id不能为空！");
        }
    }

    /**
     * 批量新增群发关联参数校验
     * @param pushGroups
     */
    public void createPushGroupBatchParamCheck(List<PushGroup> pushGroups) {
        if (ListUtils.isEmpty(pushGroups)){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "群发关联为空！");
        }
        for (PushGroup pushGroup:pushGroups){
            if (pushGroup==null){
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "群发关联为空！");
            }
            if (pushGroup.getPushId()==null){
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "群发id不能为空！");
            }
            if (pushGroup.getBookId() == null) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送群书id不能为空！");
            }
            if (pushGroup.getClassifyId() == null) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送群分类id不能为空！");
            }
            if (pushGroup.getBookGroupQrcodeId()==null) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送群二维码id不能为空！");
            }
        }
    }

    /**
     * 新增群发消息项校验
     * @param pushItem
     */
    public void createPushItemParamCheck(PushItem pushItem) {
        if (pushItem == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项不能为空！");
        }
        if (pushItem.getPushId() == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "群发id不能为空！");
        }
        if (pushItem.getItemType() == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型不能为空！");
        }
        if (ItemTypeEnum.TEXT.value.equals(pushItem.getItemType()) && StringUtil.isEmpty(pushItem.getTextContent())) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为文本时，文本不能为空！");
        }
        if (ItemTypeEnum.LINK.value.equals(pushItem.getItemType()) && StringUtil.isEmpty(pushItem.getLinkUrl())) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为链接时，链接不能为空！");
        }
        if (ItemTypeEnum.APP.value.equals(pushItem.getItemType()) && (pushItem.getAppId() == null && pushItem.getProductId() == null)) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为应用时，应用id或作品id不能为空！");
        }
        if (ItemTypeEnum.IMAGE.value.equals(pushItem.getItemType()) && StringUtil.isEmpty(pushItem.getImageUrl())) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为图片时，图片不能为空！");
        }
    }

    /**
     * 新增早晚报参数校验
     * @param morningEveningNews
     */
    public void createMorningEveningNewsParamCheck(MorningEveningNews morningEveningNews) {
        if(morningEveningNews.getHasMorningOpen()==null||morningEveningNews.getHasEveningOpen()==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"是否开启早报和晚报不能为空！");
        }
        if (morningEveningNews.getHasStartContent()==null||morningEveningNews.getHasEndContent()==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"是否开启开场和结束语不能为空！");
        }
        if (morningEveningNews.getSendCount()==null||morningEveningNews.getSendCount()<=0){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"推送条数必须不能为空且大于0！");
        }
        if (morningEveningNews.getHasMorningOpen()&&StringUtil.isEmpty(morningEveningNews.getMorningTime())){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"开启早报后，早报时间不能为空！");
        }
        if (morningEveningNews.getHasEveningOpen()&&StringUtil.isEmpty(morningEveningNews.getEveningTime())){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"开启晚报后，晚报时间不能为空！");
        }
        if (morningEveningNews.getHasStartContent()&&StringUtil.isEmpty(morningEveningNews.getStartContent())){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"开启开场语后，开场语不能为空！");
        }
        if (morningEveningNews.getHasEndContent()&&StringUtil.isEmpty(morningEveningNews.getEndContent())){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"开启结束语后，结束语不能为空！");
        }

    }

    @ParamLog("个人号群发参数校验")
    public void selfPushParamCheck(SelfPushAddParamDTO addParamDTO) {
        if (null == addParamDTO) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "参数为空");
        }
        if (SystemCode.adviser.code.equalsIgnoreCase(addParamDTO.getSystemCode())){//编辑端群发
            if (null == addParamDTO.getBookGroupId()){
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少bookGroupId");
            }
            if (ListUtils.isEmpty(addParamDTO.getUserIdList())) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择群发对象");
            }
        }
        if (SystemCode.pcloud.code.equalsIgnoreCase(addParamDTO.getSystemCode())){//平台端群发
            if (StringUtil.isEmpty(addParamDTO.getAltId())){
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少个人号id");
            }
            if (ListUtils.isEmpty(addParamDTO.getUserIdList()) && null == addParamDTO.getSendAll()) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "请选择群发对象");
            }
        }
        if (null == addParamDTO.getSendNow()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少立即发送字段");
        }
        if (!addParamDTO.getSendNow()) {
            if (StringUtil.isEmpty(addParamDTO.getSendTime())) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "自定义发送时间不能为空");
            }
            String s="00,01,02,03,04";
            if (s.contains(addParamDTO.getSendTime().substring(0,2))) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "自定义发送时间不正确");
            }
            if (StringUtil.isEmpty(addParamDTO.getStartTime())) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "自定义发送开始时间不能为空");
            }
            if (StringUtil.isEmpty(addParamDTO.getEndTime())) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "自定义发送结束时间不能为空");
            }
            if (null==addParamDTO.getPushType()) {
                throw new BookBizException(BookBizException.PARAM_IS_NULL, "发送类型不能为空");
            }
            if (addParamDTO.getPushType()==2) {
                if (StringUtil.isEmpty(addParamDTO.getWeekDays())) {
                    throw new BookBizException(BookBizException.PARAM_IS_NULL, "自定义发送周机不能为空");
                }
            }


        }
        if (ListUtils.isEmpty(addParamDTO.getReplyParamDTOS())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "发送消息为空");
        }
        if (addParamDTO.getReplyParamDTOS().size() > 4) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "发送消息数量不能超过4条");
        }
        if (!ListUtils.isEmpty(addParamDTO.getUserIdList()) && addParamDTO.getUserIdList().size() > 100) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "好友数量不能超过100");
        }
        for (ReplyParamDTO replyParamDTO : addParamDTO.getReplyParamDTOS()) {
            if (replyParamDTO == null) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项不能为空！");
            }
            if (replyParamDTO.getReplyType() == null) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型不能为空！");
            }
            if (ReplyTypeEnum.TEXT.value.equals(replyParamDTO.getReplyType()) && StringUtil.isEmpty(replyParamDTO.getContent())) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为文本时，文本不能为空！");
            }
            if (ReplyTypeEnum.LINK.value.equals(replyParamDTO.getReplyType()) && StringUtil.isEmpty(replyParamDTO.getLinkUrl())) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为链接时，链接不能为空！");
            }
            if (ReplyTypeEnum.APP.value.equals(replyParamDTO.getReplyType())){
                if (StringUtil.isEmpty(replyParamDTO.getServeType()) || null ==replyParamDTO.getServeId()
                        || StringUtil.isEmpty(replyParamDTO.getLinkUrl())){
                    throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为应用或作品时，id或链接不能为空！");
                }
            }
            if (ReplyTypeEnum.IMAGE.value.equals(replyParamDTO.getReplyType()) && StringUtil.isEmpty(replyParamDTO.getPicUrl())) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为图片时，图片不能为空！");
            }
            if (ReplyTypeEnum.RESOURCE.value.equals(replyParamDTO.getReplyType()) && null == replyParamDTO.getResourceId()) {
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "发送消息项内容类型为文件时，文件id不能为空！");
            }

            //参数转换
            List<SelfPushItem> items = paramChange(addParamDTO.getReplyParamDTOS());
            addParamDTO.setPushItemList(items);
        }
    }

    /**
     * 参数转换
     * @param paramDTOS
     * @return
     */
    List<SelfPushItem> paramChange(List<ReplyParamDTO> paramDTOS){
        List<SelfPushItem> itemList = new ArrayList<>();
        for (ReplyParamDTO paramDTO : paramDTOS){
            SelfPushItem item = new SelfPushItem();
            if (ReplyTypeEnum.TEXT.value.equals(paramDTO.getReplyType())){
                item.setTextContent(paramDTO.getContent());
                item.setItemType(ItemTypeEnum.TEXT.value);
            }
            if (ReplyTypeEnum.LINK.value.equals(paramDTO.getReplyType())){
                item.setLinkUrl(paramDTO.getLinkUrl());
                item.setLinkTitle(paramDTO.getContent());
                item.setLinkDescription(paramDTO.getDescription());
                item.setLinkImageUrl(paramDTO.getPicUrl());
                item.setItemType(ItemTypeEnum.LINK.value);
            }
            if (ReplyTypeEnum.IMAGE.value.equals(paramDTO.getReplyType())){
                item.setImageUrl(paramDTO.getPicUrl());
                item.setItemType(ItemTypeEnum.IMAGE.value);
            }
            if (ReplyTypeEnum.RESOURCE.value.equals(paramDTO.getReplyType())){
                item.setResourceId(paramDTO.getResourceId());
                item.setItemType(ItemTypeEnum.RESOURCE.value);
            }
            if (ReplyTypeEnum.APP.value.equals(paramDTO.getReplyType())){
                if ("APP".equalsIgnoreCase(paramDTO.getServeType())) {
                    item.setAppId(paramDTO.getServeId());
                    item.setAppUrl(paramDTO.getLinkUrl());
                }
                if ("PRODUCT".equalsIgnoreCase(paramDTO.getServeType())){
                    item.setProductId(paramDTO.getServeId());
                    item.setProductUrl(paramDTO.getLinkUrl());
                }
                item.setLinkTitle(paramDTO.getContent());
                item.setLinkImageUrl(paramDTO.getPicUrl());
                item.setLinkDescription(paramDTO.getDescription());
                item.setLinkUrl(paramDTO.getLinkUrl());
                item.setItemType(ItemTypeEnum.APP.value);
            }
            itemList.add(item);
        }
        return itemList;
    }
}
