package cn.axzo.workflow.common.model.request.bpmn.process;

import cn.axzo.workflow.common.constant.BpmnConstants;
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.math.NumberUtils;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 创建流程实例的入参模型
 */
@ApiModel("创建流程实例的入参模型")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class BpmnProcessInstanceCreateDTO extends BpmnProcessInstanceCreateWithFormDTO {

    /**
     * 废弃
     * 流程定义的 id
     */
    @Deprecated
    private String processDefinitionId;
    /**
     * 流程定义的标识
     * <p>
     * [对应 OMS 系统中审批业务的业务 ID]
     */
    @NotEmpty(message = "流程定义的标识不能为空")
    private String processDefinitionKey;

    /**
     * 发起流程实例归属租户 ID
     * <p>
     * 为空时,默认是编辑公共流程模型, 如果是代运营创建,则必填
     * <h1 color=red>建议都传值，在安心筑中对应工作台 ID</h1>
     */
    @ApiModelProperty(value = "发起的审批是属于哪个租户")
    @NotBlank(message = "工作台 ID 不能为空")
    private String tenantId;

    /**
     * 流程在发起时指定审批人
     */
    @ApiModelProperty(value = "发起时指定节点的审批人")
    private Map</*节点标识*/String, List<BpmnTaskDelegateAssigner>> specifyAssignerMap;

    /**
     * 流程实例关联的变量
     */
    @Builder.Default
    private Map<String, Object> variables = new HashMap<>();

    /**
     * 业务管理中定义变量的入参
     */
    @Builder.Default
    private Map<String, Object> bizCustomVariables = new HashMap<>();

    /**
     * 待办相关的变量,如路由参数, 模板参数等等
     */
    @Builder.Default
    private Map<String, Object> pendingVariables = new HashMap<>();

    /**
     * 组织关系
     * <p>
     * 用于流程引擎计算对应节点的审批人, 例如第一个审批节点配置的是劳务分包的岗位,第二个审批节点配置的专业分包的角色,
     * 那么, 组织关系就需要传入劳务分包的信息以及专业分包的信息,如果还有更多的审批节点配置,以此类推.
     * 同时，该属性还会用于计算抄送人，以及消息通知的目标接收人
     */
    @ApiModelProperty(value = "组织关系")
    @NotNull(message = "组织关系不能为空")
    private CooperationOrgDTO cooperationOrg;

    /**
     * 业务的唯一标识
     * <p>
     * 例如说，请假申请的编号。通过它，可以查询到对应的实例
     */
    @NotEmpty(message = "业务的唯一标识不能为空")
    private String businessKey;

    @ApiModelProperty(value = "发起人信息")
    @Valid
    @NotNull(message = "发起人不能为空")
    private BpmnTaskDelegateAssigner initiator;

    /**
     * 自定义的流程实例名称, 可为空, 默认使用模型名称
     */
    @ApiModelProperty(value = "自定义的流程实例名称")
    private String customProcessInstanceName;

    /**
     * 是否异步执行，该异步是引擎的一种运行模式
     */
    @ApiModelProperty(value = "是否异步", notes = "异步时,只接收请求便返回数据")
    @Builder.Default
    private Boolean async = true;

    /**
     * 签署业务，发起时，可基于模型启用的模板，再勾选使用本次发起时选择的文档标签
     */
    @ApiModelProperty(value = "签署业务发起时，选择的文档")
    private List<Long> docIds;

    /**
     * 仅针对签署业务，设置审批完成后的最终签署人列表，该属性仅为透传，业务消费时，请从 MQ 广播事件中的 variables 中通过 key= {@link BpmnConstants#SIGNATORIES } 获取
     */
    @ApiModelProperty(value = "签署业务，最终签署人")
    private List<BpmnTaskDelegateAssigner> signatories;

    public String getTenantId() {
        if (NumberUtils.isDigits(tenantId)) {
            return tenantId;
        }
        return null;
    }
}