package cn.axzo.workflow.server.controller.delegate;

import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.axzo.workflow.common.code.FlowableEngineRespCode.ENGINE_USER_TASK_CALC_ERROR;
import static cn.axzo.workflow.common.constant.BpmnConstants.INITIATOR_SPECIFY;

/**
 * 基于发起人指定的任务审批人选择器
 *
 * @author wangli
 * @since 2025-08-18 14:43
 */
@Slf4j
@Component
@AllArgsConstructor
public class BasedInitiatorSpecifiedV2TaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector {
    private final RuntimeService runtimeService;

    @Override
    public String getType() {
        return ApproverSpecifyEnum.initiatorSpecified_v2.getType();
    }

    @Override
    public List<BpmnTaskDelegateAssigner> select(FlowElement flowElement, DelegateExecution execution, Boolean throwException) {
        List<BpmnTaskDelegateAssigner> assigners = new ArrayList<>();
        try {
            populateAssigneeByInitiatorSpecify(assigners, flowElement, execution);
        } catch (Throwable t) {
            if (Boolean.TRUE.equals(throwException)) {
                log.warn("执行查询发起时指定审批人时发现异常, 审批节点：{}, 异常信息：{}", flowElement.getId(), t.getMessage());
                if (!(t instanceof WorkflowEngineException)) {
                    throw new WorkflowEngineException(ENGINE_USER_TASK_CALC_ERROR, flowElement.getId(),
                            this.getType(), t.getMessage());
                }
                throw t;
            } else {
                return Collections.emptyList();
            }
        }
        return assigners.stream().filter(i -> StringUtils.hasText(i.getPersonId())).collect(Collectors.toList());
    }

    /**
     * 创建审批时，传入各个节点应该设置的审批人的数据信息，此处直接设置人
     *
     * @param assigners
     * @param flowElement
     * @param execution
     */
    private void populateAssigneeByInitiatorSpecify(List<BpmnTaskDelegateAssigner> assigners, FlowElement flowElement, DelegateExecution execution) {
        String processInstanceId = execution.getProcessInstanceId();
        @SuppressWarnings("unchecked")
        Map<String, List<BpmnTaskDelegateAssigner>> initiatorSpecifyMap = runtimeService.getVariable(processInstanceId, INITIATOR_SPECIFY, Map.class);
        if (CollectionUtils.isEmpty(initiatorSpecifyMap)) {
            return;
        }

        assigners.addAll(initiatorSpecifyMap.getOrDefault(flowElement.getId(), Collections.emptyList()));
    }
}
