package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;

import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
import static java.util.Collections.emptySet;

/**
 * 分配给审批人的上级领导 审批的 Script 实现类
 *

 */
@Component
public class BpmTaskCurrentAssignLeaderScript extends BpmTaskAssignLeaderAbstractScript {


    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private DeptApi deptApi;
    @Resource
    @Lazy // 解决循环依赖
    private BpmProcessInstanceService bpmProcessInstanceService;

    @Resource
    @Lazy // 解决循环依赖
    private BpmTaskService bpmTaskService ;

    @Override
    public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
        // 获得发起人
        ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(execution.getProcessInstanceId());
        List<BpmTaskRespVO> bpmTaskRespVOs = bpmTaskService.getTaskListByProcessInstanceId(processInstance.getProcessInstanceId());
        if (CollUtil.isEmpty(bpmTaskRespVOs)) {
            return emptySet();
        }
        Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());

        //获取最后一个Task任务相关数据
        BpmTaskRespVO bpmTaskRespVO = bpmTaskRespVOs.get(0) ;
        Long assigneeUserId = bpmTaskRespVO.getAssigneeUser().getId() ;

        // 获得对应 发起人 的部门
        DeptRespDTO dept = getUserDept(startUserId);
        if (dept == null) { // 找不到发起人的部门，所以无法使用该规则
            return emptySet();
        }

        int count = 0;
        Long parentId = dept.getParentId();
        for (int i = 0; i < dept.getLevel(); i++) {

            if (i == 0) { //第一次查找  判断审批人是否为发起人部门负责人
                if (assigneeUserId.toString().equals(processInstance.getStartUserId())
                    && !dept.getLeaderUserId().toString().equals(processInstance.getStartUserId())){  //如果发起人不是所在部门负责人时

                    count = 1;
                    break;
                }
            }

            //获得发起人的上级部门
            DeptRespDTO parentDept = deptApi.getDept(parentId).getCheckedData();
            if (parentDept == null) { // 找不到父级部门，所以只好结束寻找。原因是：例如说，级别比较高的人，所在部门层级比较少
                return emptySet();
            }
            if (!parentDept.getLeaderUserId().toString().equals(assigneeUserId.toString())){  //如果发起人上级部门负责人不为当前审批人时

                dept = parentDept;
                count = 1;
                break;
            }

            parentId = parentDept.getParentId();
        }

        if (count == 0){// 找不到父级部门。原因是：人的所属部门配在了最高节点了
            return emptySet();
        }

        return dept.getLeaderUserId() != null ? asSet(dept.getLeaderUserId()) : emptySet();

//        //获取最后一个Task任务相关数据
//        BpmTaskRespVO bpmTaskRespVO = bpmTaskRespVOs.get(0) ;
//        Long assigneeUserId = bpmTaskRespVO.getAssigneeUser().getId() ;
//        // 获取当前审批用户的部门信息
//        DeptRespDTO dept = getUserDept(assigneeUserId);
//        if (dept == null) { // 找不到发起人的部门，所以无法使用该规则
//            return emptySet();
//        }
//        DeptRespDTO parentDept = deptApi.getDept(dept.getParentId()).getCheckedData();
//        if (parentDept == null) { // 找不到父级部门。原因是：人的所属部门配在了最高节点了
//            return emptySet();
//        }
//        return parentDept.getLeaderUserId() != null ? asSet(parentDept.getLeaderUserId()) : emptySet();
    }

    @Override
    public BpmTaskRuleScriptEnum getEnum() {
        return BpmTaskRuleScriptEnum.LEADER_X4;
    }

    private DeptRespDTO getUserDept(Long userId) {
        AdminUserRespDTO user = adminUserApi.getUser(userId).getCheckedData();
        if (user.getDeptId() == null) { // 找不到部门，所以无法使用该规则
            return null;
        }
        return deptApi.getDept(user.getDeptId()).getCheckedData();
    }
}
