package cn.axzo.msg.center.api.request.v3;

import cn.axzo.basics.common.util.AssertUtil;
import cn.axzo.msg.center.service.dto.PersonV3DTO;
import cn.axzo.msg.center.service.enums.OrganizationTypeEnum;
import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

/**
 * @author yanglin
 */
@Setter
@Getter
@Slf4j
public class MessageSendReqV3 implements Serializable {

    /**
     * 发送待办时, channelParams 的 key, 传值 {@link PendingSendInfo}
     */
    public static final String CHANNEL_PENDING = "channel_pending";

    /**
     * 发起者
     * <p>如果是平台，则发起人为空
     */
    private PersonV3DTO sender;

    /**
     * 接收者列表
     */
    @NotNull(message = "接收者列表不能为空")
    private List<PersonV3DTO> receivers;

    /**
     * 业务事件code
     * oms->消息模板 配置
     */
    @NotBlank(message = "业务事件code不能为空")
    private String bizEventMappingCode;

    /**
     * 关联业务唯一标识
     * 例如: 请假申请的编号
     */
    private String bizCode;

    /**
     * 业务扩展参数-JSON字符串格式
     */
    private JSONObject bizExtParams;

    /**
     * 路由参数-JSON字符串格式
     */
    private JSONObject routerParams;

    /**
     * 发送者项目部ID
     */
    private Long senderWorkspaceId;

    /**
     * 发送者企业ID
     */
    private Long senderOuId;

    /**
     * 接收者项目部ID
     */
    private Long receiversWorkspaceId;

    /**
     * 接收者企业ID
     * <p>如果是工人，则所在企业可以为空；其它均必传
     */
    private Long receiversOuId;

    /**
     * 接收者(消息)所属组织类型
     */
    private OrganizationTypeEnum receiversOrgType;

    /**
     * 副标题
     */
    private String subtitle;

    /**
     * 渠道参数
     */
    private JSONObject channelParams;

    public void addChannelParam(String key, Object object) {
        if (channelParams == null) {
            channelParams = new JSONObject();
        }
        channelParams.put(key, object);
    }

    public <T> T getChannelParam(String key, Class<T> asType) {
        if (channelParams == null) {
            return null;
        }
        if (!channelParams.containsKey(key)) {
            return null;
        }
        return channelParams.getObject(key, asType);
    }

    public Collection<PersonV3DTO> distinctReceivers() {
        if (receivers == null) {
            return Collections.emptySet();
        }
        HashMap<Long, PersonV3DTO> personId2Person = new HashMap<>();
        for (PersonV3DTO receiver : receivers) {
            if (!personId2Person.containsKey(receiver.getId())) {
                personId2Person.put(receiver.getId(), receiver);
            }
        }
        return personId2Person.values();
    }

    public List<PersonV3DTO> receivers() {
        if (receivers == null) {
            return Collections.emptyList();
        }
        return receivers;
    }

    public Long determineReceiversOuId() {
        return receiversOuId == null ? 0L : receiversOuId;
    }

    public Long determineReceiversWorkspaceId() {
        return receiversWorkspaceId == null ? 0L : receiversWorkspaceId;
    }

    public String determineBizCode() {
        return bizCode == null ? "" : bizCode;
    }

    public void validate() {
        AssertUtil.notNull(bizEventMappingCode, "bizEventCode不能为空");
        AssertUtil.notEmpty(receivers, "receivers不能为空");

        for (PersonV3DTO receiver : receivers) {
            AssertUtil.notNull(receiver.getId(), "接收者ID不能为空");
            if (receiver.getId() <= 0)
                log.warn("接收者ID <= 0, request={}", this);
            // 去掉这个校验
            //AssertUtil.isFalse(receiver.getId() <= 0, "接收者ID必须>=0");
        }
    }

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