package com.jeeplus.modules.flowable.listener;

import cn.hutool.extra.spring.SpringUtil;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.flowable.model.ActRuTaskInfo;
import com.jeeplus.flowable.model.Flow;
import com.jeeplus.flowable.service.FlowTaskService;
import com.jeeplus.flowable.service.MyNoticeService;
import com.jeeplus.flowable.utils.StringUtils;
import com.jeeplus.sys.feign.ICwProjectReportApi;
import com.jeeplus.sys.feign.IOfficeApi;
import com.jeeplus.sys.feign.IUserApi;
import com.jeeplus.sys.service.dto.OfficeDTO;
import com.jeeplus.sys.service.dto.UserDTO;
import lombok.SneakyThrows;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.List;

@Component("myExecutionListener")
public class MyExecutionListener implements ExecutionListener {

    @SneakyThrows
    public void notify(DelegateExecution delegateExecution) {

        String eventName = delegateExecution.getEventName ( );
        System.out.println("--------- delegateExecution -----------" + delegateExecution);

        if ( "start".equals ( eventName ) ) {
            System.out.println ( "start=========" );
        } else if ( "end".equals ( eventName ) ) {
            //根据这里的 delegateExecution的id去act_ru_task表中查该流程的数据 对应表中的EXECUTION_ID_
            ActRuTaskInfo task = SpringUtil.getBean(MyNoticeService.class).getTaskInfoByID(delegateExecution.getId());

            if (null != task) {
                List<Flow> flows = SpringUtil.getBean(FlowTaskService.class).historicTaskList(task.getProcInstId());
                //根据PROC_DEF_ID_去act_re_deployment中查询流程的名称
                String substring = task.getProcDefId().substring(0, task.getProcDefId().indexOf(":"));
                String actName = SpringUtil.getBean(FlowTaskService.class).getActNameByDefId(substring);

                String titleName = "";
                // 根据流程定义ID查询流程实例
                ProcessInstance processInstance = SpringUtil.getBean(RuntimeService.class).createProcessInstanceQuery()
                        .processInstanceId(task.getProcInstId())
                        .singleResult();

                if (processInstance != null) {
                    // 获取流程实例标题变量名（假设标题存储在名为"title"的变量中）
                    String titleVariableName = "title";

                    // 查询流程实例的标题变量
                    Object title = SpringUtil.getBean(RuntimeService.class).getVariable(processInstance.getId(), titleVariableName);
                    // 获取流程实例标题变量名（假设标题存储在名为"title"的变量中）
                    String formTitleName = "formTitle";

                    // 查询流程实例的标题变量
                    Object formTitleNames = SpringUtil.getBean(RuntimeService.class).getVariable(processInstance.getId(), formTitleName);
                    System.out.println(formTitleNames);

                    if (title != null) {
                        if(StringUtils.isBlank(title.toString())){
                            titleName = actName;
                        }else{
                            titleName = title.toString();
                        }
                    } else {
                        // 如果标题变量不存在或者没有值，可以返回默认标题
                        titleName = "";
                    }
                }
                Flow flow = new Flow();
                for (int i=0;i<flows.size();i++){
                    if (flows.get(i).getComment().getMessage().equals("发起流程")){
                        flow = flows.get(i);
                    }
                }

                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                if(actName.equals("会计-报告签章-电子公章") || actName.equals("会计-复核及签章")){
                    UserDTO userDTO = SpringUtil.getBean(IUserApi.class).getById(flow.getAssigneeId());
                    OfficeDTO officeDTO = userDTO.getOfficeDTO();
                    if(null != officeDTO){
                        //根据officeId获取office信息
                        OfficeDTO officeById = SpringUtil.getBean(IOfficeApi.class).getOfficeById(officeDTO.getId());
                        OfficeDTO parentOffice = SpringUtil.getBean(IOfficeApi.class).getOfficeById(officeById.getParentId());
                        //如果是苏州分部发送的签章申请，则会给徐珊发送通知
                        if(null != parentOffice && "苏州分公司".equals(parentOffice.getName())){
                            //需要判定 报告中的签字注师1或者签字注师2 必须含有潘中 才需要通知
                            //1602912511302615042  潘中的id
                            String reportId = SpringUtil.getBean(ICwProjectReportApi.class).getReportReviewUserIdByProcInsId(delegateExecution.getProcessInstanceId(), "1602912511302615042");

                            if(StringUtils.isNotBlank(reportId)){
                                //获取角色为“苏州报告签字盖章代办”的角色对应人员信息
                                List<UserDTO> userDTOList = SpringUtil.getBean(IUserApi.class).getUserInfoByEnName("szbgqzgzdb");
                                for (UserDTO dto : userDTOList) {
                                    SpringUtil.getBean(MyNoticeService.class).add(task.getProcInstId(),titleName,task.getProcDefId(),actName,
                                            flow.getAssigneeName(),format.format(flow.getHistIns().getEndTime()),
                                            dto.getName(),dto.getId(),userDTO.getId());
                                }
                            }

                        }
                    }
                }

                UserDTO userDTO = SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken());

                SpringUtil.getBean(MyNoticeService.class).add(task.getProcInstId(),titleName,task.getProcDefId(),actName,
                        flow.getAssigneeName(),format.format(flow.getHistIns().getEndTime()),
                        flow.getAssigneeName(),flow.getAssigneeId(),userDTO.getId());
            }

            System.out.println ( "end=========" );
        } else if ( "take".equals ( eventName ) ) {//连线监听
            System.out.println ( "take=========" );
        }
    }
}
