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

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAExpensesItemDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALoanDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOASalaryDO;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAExpensesService;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOALoanService;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOASalaryService;
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 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.ArrayList;
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 BpmTaskFactoryLeaderScript extends BpmTaskAssignLeaderAbstractScript {

    @Resource
    private DeptApi deptApi;

    @Resource
    @Lazy // 解决循环依赖
    private BpmProcessInstanceService bpmProcessInstanceService;

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

    @Resource
    @Lazy // 解决循环依赖
    private BpmOAExpensesService expensesService;

    @Resource
    @Lazy // 解决循环依赖
    private BpmOALoanService loanService;

    @Resource
    @Lazy
    private BpmOASalaryService salaryService;

    @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();
        }

        DeptRespDTO dept = null;
        switch (processInstance.getProcessDefinitionKey()) {
            case "oa_expenses_2":
                // 根据流程实例ID 取到开支日报流程表单
                List<BpmOAExpensesItemDO> expensesItems = expensesService.getExpensesItem(Long.valueOf(processInstance.getBusinessKey()));
                // 获取开支所属工厂信息
                if (CollUtil.isNotEmpty(expensesItems)) {

                    DeptRespDTO factory = deptApi.getDeptByFactoryId(expensesItems.get(0).getDeptId()).getCheckedData();
                    // 获取工厂上级部门信息
                    dept = deptApi.getDept(factory.getParentId()).getCheckedData();
                }
                break;
            case "oa_loan_2":
                // 根据流程实例ID 取到借支流程表单
                BpmOALoanDO loanDO = loanService.getLoan(Long.valueOf(processInstance.getBusinessKey()));

                if (loanDO != null) {
                    // 获取借支工厂信息
                    DeptRespDTO factory = deptApi.getDeptByFactoryId(loanDO.getFactoryId()).getCheckedData();
                    // 获取工厂上级部门信息
                    dept = deptApi.getDept(factory.getParentId()).getCheckedData();
                }
                break;
            case "oa_salary_2":
                // 根据流程实例ID 取到薪资付款流程表单
                BpmOASalaryDO salaryDO = salaryService.getByProcessInstanceId(processInstance.getProcessInstanceId());
                if (salaryDO != null) {

                    // 获取申请部门信息
                    DeptRespDTO deptRespDTO = null;
                    if (salaryDO.getCompanyDeptId() != null) {
                        deptRespDTO = deptApi.getDept(salaryDO.getCompanyDeptId()).getCheckedData();
                    }else if (CollUtil.isNotEmpty(salaryDO.getFactoryDeptId())) {
                        deptRespDTO = deptApi.getDeptByFactoryId(new ArrayList<>(salaryDO.getFactoryDeptId()).get(0)).getCheckedData();
                    }
                    // 判断是否是属于工厂部门
                    if (deptRespDTO != null) {
                        dept = deptApi.getDept(deptRespDTO.getParentId()).getCheckedData();
                    }
                }

                break;
        }

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

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