package cn.axzo.msg.center.message.domain.param;

import cn.axzo.msg.center.common.exception.ServiceException;
import cn.axzo.msg.center.common.utils.BizAssertions;
import cn.axzo.msg.center.service.domain.card.AppVersionConfig;
import cn.axzo.msg.center.service.domain.card.StateImageConfig;
import cn.axzo.msg.center.service.dto.MessageTemplateButtonV3DTO;
import cn.axzo.msg.center.service.dto.MessageTemplateCardJumpV3DTO;
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
import cn.axzo.msg.center.service.enums.MessageChannel;
import cn.axzo.msg.center.service.enums.PresetButtonType;
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
import cn.axzo.msg.center.service.enums.RouterButtonSourceEnum;
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
import cn.axzo.msg.center.service.enums.StatusEnum;
import cn.axzo.msg.center.service.enums.SystemButtonEnum;
import cn.axzo.msg.center.service.pending.card.domain.CardElementConfig;
import cn.axzo.msg.center.service.template.request.MessageTemplateGroupV3CreateRequest;
import cn.axzo.msg.center.service.template.request.MessageTemplateV3CreateRequest;
import cn.axzo.msg.center.service.template.request.MessageTemplateV3DeleteRequest;
import cn.axzo.msg.center.service.template.request.MessageTemplateV3UpdateRequest;
import cn.axzo.msg.center.service.template.response.MessageTemplateV3DetailResponse;
import cn.axzo.msg.center.utils.MessageTemplateCategoryUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.collections.CollectionUtils;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @description
 *
 * @author cold_blade
 * @date 2023/10/5
 * @version 1.0
 */
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MessageTemplateV3SaveOrUpdateParam implements Serializable {

    private static final long serialVersionUID = 6657624182580261353L;

    /**
     * 模板编码
     */
    private String templateCode;
    /**
     * 操作者的自然人id
     */
    private Long operatorId;
    /**
     * 操作者的自然人姓名
     */
    private String operatorName;
    /**
     * 模板名称
     */
    private String templateName;
    /**
     * 消息类型
     *   GENERAL_MESSAGE: 通知
     *   BIZ_PENDING_MESSAGE: 业务待办
     *   APPROVAL_PENDING_MESSAGE: 审批待办
     */
    private MessageCategoryEnum msgCategory;
    /**
     * 消息分类树的叶结点的结点编码列表
     */
    private List<String> leafGroupNodes;
    /**
     * 推送终端配置
     *   B_ENTERPRISE_APP: B-安心筑企业版
     *   C_WORKER_APP: C-安心筑工人版
     */
    private List<PushTerminalEnum> pushTerminals;
    /**
     * 该模板最低支持的APP版本号
     */
    private String minAppVersion;
    /**
     * 消息标题
     */
    private String title;
    /**
     * 消息内容
     */
    private String content;
    /**
     * 消息图标
     */
    private String icon;
    /**
     * 消息卡片信息标签列表，可为空
     */
    private List<MessageTemplateGroupV3CreateRequest> groups;
    /**
     * 卡片跳转
     */
    private MessageTemplateCardJumpV3DTO cardJump;
    /**
     * 按钮列表
     */
    private List<MessageTemplateButtonV3DTO> buttons;
    /**
     * 待办样式, BIZ_COMMON: 业务待办能用, FLOW_COMMON: 审批待办能用, 其它动态配置的
     */
    private String detailStyleCode;

    private JSONObject pushData;

    /**
     * 模板状态
     */
    private StatusEnum status;

    /**
     * 推送终端/最低版本
     */
    private List<AppVersionConfig> appVersionConfigs;

    /**
     * 消息通道:IM/待办
     */
    private List<MessageChannel> channels;

    /**
     * 卡片样式编码
     */
    private String cardStyleCode;

    /**
     * 卡片样式扩展字段
     */
    private List<CardElementConfig> cardExtFields;

    /**
     * 配置状态戳
     */
    private List<StateImageConfig> stateImageConfigs;

    /**
     * 操作者的自然人id
     */
    private Long createPersonId;
    /**
     * 操作人人姓名
     */
    private String createPersonName;

    /**
     * 更新人id
     */
    private Long updatePersonId;
    /**
     * 更新人姓名
     */
    private String updatePersonName;

    /**
     * 校验
     */
    public void checkCreate() {
        //1 流程待办，暂不能使用IM通道
        switch (this.getMsgCategory()) {
            case GENERAL_MESSAGE:
                break;
            case IM_MESSAGE_CARD:
            case BIZ_PENDING_MESSAGE:
            case APPROVAL_PENDING_MESSAGE:
                boolean contains = CollectionUtils.isNotEmpty(this.getChannels()) && this.getChannels().contains(MessageChannel.IM);
                BizAssertions.assertFalse(contains, "流程待办，暂不能使用IM通道");
        }
        //2 同一个预设按钮类型，只能有一个
        if (CollectionUtils.isNotEmpty(this.getButtons())) {
            Map<String, Set<PresetButtonType>> collect = this.getButtons().stream()
                    .filter(item -> item.getCategory().equals(RouterCategoryEnum.PRESET_BUTTON)
                            && item.getSource().equals(RouterButtonSourceEnum.CUSTOM)
                    ).collect(Collectors.groupingBy(e -> e.getSource().name() + e.getCategory().name() + e.getPresetBtnType(), Collectors.mapping(MessageTemplateButtonV3DTO::getPresetBtnType, Collectors.toSet())));
            if (Objects.nonNull(collect) && collect.size() != 0 && CollectionUtils.isNotEmpty(collect.values())) {
                for (Set<PresetButtonType> presetButtonTypes : collect.values()) {
                    Boolean presetButtonCheckFlag = CollectionUtils.isNotEmpty(presetButtonTypes) && presetButtonTypes.size() > 1;
                    BizAssertions.assertFalse(presetButtonCheckFlag, "同一个预设按钮类型，只能有一个");
                }
            }
            //3 按钮类型非空校验
            if (this.getButtons() != null)
                this.getButtons().forEach(MessageTemplateButtonV3DTO::validate);
        }
    }

    /**
     * 重新设置系统类型的btnCode
     * source:SYSTEM;category:JUMP/ACTION
     * code的开始字符:BPMN_
     */
    public void rechangeBtnCode() {
        this.getButtons().stream()
                .filter(item -> item.getSource().equals(RouterButtonSourceEnum.SYSTEM)
                        && (item.getCategory().equals(RouterCategoryEnum.JUMP) || item.getCategory().equals(RouterCategoryEnum.ACTION)))
                .forEach(item -> {
                    if (!item.getBtnCode().startsWith(SystemButtonEnum.CODE_START)) {
                        item.setBtnCode(SystemButtonEnum.getByName(item.getName()).getCode());
                    }
                });
    }


    public static MessageTemplateV3SaveOrUpdateParam from(MessageTemplateV3CreateRequest request) {
        MessageCategoryEnum category = MessageTemplateCategoryUtil
                .checkAndReturnSubCategory(request.getCategory(), request.getSubCategory())
                .orElseThrow(() -> new ServiceException("无效的参数"));

        if (CollectionUtils.isNotEmpty(request.getGroups())) {
            request.getGroups().forEach(item -> {
                item.setCreatePersonId(request.getOperatorId());
                item.setCreatePersonName(request.getOperatorName());
            });
        }
        if (CollectionUtils.isNotEmpty(request.getButtons())) {
            request.getButtons().forEach(item -> {
                item.setCreatePersonId(request.getOperatorId());
                item.setCreatePersonName(request.getOperatorName());
            });
        }
        return MessageTemplateV3SaveOrUpdateParam.builder()
                .templateName(request.getTemplateName())
                .detailStyleCode(request.getDetailStyleCode())
                .operatorId(request.getOperatorId())
                .operatorName(request.getOperatorName())
                .createPersonId(request.getOperatorId())
                .createPersonName(request.getOperatorName())
                .msgCategory(category)
                .leafGroupNodes(request.getLeafGroupNodes())
                .title(request.getMsgTitle())
                .content(request.getMsgContent())
                .groups(request.getGroups())
                .icon(request.getMsgIcon())
                .minAppVersion(request.getMinAppVersion())
                .operatorId(request.getOperatorId())
                .buttons(request.getButtons())
                .pushTerminals(request.getPushTerminals())
                .cardJump(request.getCardJump())
                .pushData(request.getPushData())
                .status(StatusEnum.ENABLE)
                .appVersionConfigs(request.getAppVersionConfigs())//推送终端/最低版本
                .channels(request.getChannels())//消息通道:IM/待办
                .cardStyleCode(request.getCardStyleCode())//卡片样式编码
                .cardExtFields(request.getCardExtFields())//卡片样式扩展字段
                .stateImageConfigs(request.getStateImageConfigs())//配置状态戳
                .build();
    }

    public static MessageTemplateV3SaveOrUpdateParam from(MessageTemplateV3UpdateRequest request, MessageTemplateV3DetailResponse detail) {

        if (CollectionUtils.isNotEmpty(request.getGroups())) {
            request.getGroups().forEach(item -> {
                item.setCreatePersonId(detail.getCreatePersonId());
                item.setCreatePersonName(detail.getCreatePersonName());
                item.setUpdatePersonId(request.getOperatorId());
                item.setUpdatePersonName(request.getOperatorName());
            });
        }
        if (CollectionUtils.isNotEmpty(request.getButtons())) {
            request.getButtons().forEach(item -> {
                item.setCreatePersonId(detail.getCreatePersonId());
                item.setCreatePersonName(detail.getCreatePersonName());
                item.setUpdatePersonId(request.getOperatorId());
                item.setUpdatePersonName(request.getOperatorName());
            });
        }

        return MessageTemplateV3SaveOrUpdateParam.builder()
                .templateName(request.getTemplateName())
                .detailStyleCode(request.getDetailStyleCode())
                .operatorName(request.getOperatorName())
                .updatePersonId(request.getOperatorId())
                .updatePersonName(request.getOperatorName())
                .createPersonId(detail.getCreatePersonId())
                .createPersonName(detail.getCreatePersonName())
                .templateCode(request.getTemplateCode())
                .leafGroupNodes(request.getLeafGroupNodes())
                .title(request.getMsgTitle())
                .content(request.getMsgContent())
                .groups(request.getGroups())
                .cardJump(request.getCardJump())
                .minAppVersion(request.getMinAppVersion())
                .icon(request.getMsgIcon())
                .operatorId(request.getOperatorId())
                .operatorName(request.getOperatorName())
                .buttons(request.getButtons())
                .pushTerminals(request.getPushTerminals())
                .groups(request.getGroups())
                .pushData(request.getPushData())
                //推送终端/最低版本
                .appVersionConfigs(request.getAppVersionConfigs())
                //消息通道,IM/代办
                .channels(request.getChannels())
                //卡片样式编码
                .cardStyleCode(request.getCardStyleCode())
                //卡片样式扩展字段
                .cardExtFields(request.getCardExtFields())
                //配置状态戳
                .stateImageConfigs(request.getStateImageConfigs())
                .build();
    }

    public static MessageTemplateV3SaveOrUpdateParam from(MessageTemplateV3DeleteRequest request) {
        return MessageTemplateV3SaveOrUpdateParam.builder()
                .templateCode(request.getTemplateCode())
                .operatorId(request.getOperatorId())
                .build();
    }



    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}
