package com.srs.flowable.listener.outsideAccommodation;


import com.srs.common.utils.SecurityUtils;
import com.srs.common.utils.spring.SpringUtils;
import com.srs.dormitory.domain.DmsOutsideAccommodationApply;
import com.srs.flowable.domain.EnlistmentReserve;
import com.srs.flowable.domain.EnlistmentReserveApproval;
import com.srs.flowable.domain.OutsideAccommodationApply;
import com.srs.flowable.domain.OutsideAccommodationApproval;
import com.srs.flowable.mapper.EnlistmentReserveApprovalMapper;
import com.srs.flowable.mapper.EnlistmentReserveMapper;
import com.srs.flowable.mapper.OutsideAccommodationApplyMapper;
import com.srs.flowable.mapper.OutsideAccommodationApprovalMapper;
import com.srs.system.service.ISysUserService;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;


/**
 * 审批流程负责人自动流转监听器
 * 用于节点审批通过时，添加审批记录
 */
@Component("OutsideAccommodationEndListener") // Spring Bean名称，与BPMN表达式对应
public class OutsideAccommodationEndListener implements ExecutionListener {

    // 用于查询流程定义中的节点信息
    @Autowired
    private RepositoryService repositoryService;

    @Override
    public void notify(DelegateExecution execution) {
        // 1. 获取当前节点ID和流程定义ID
        String currentActivityId = execution.getCurrentActivityId(); // 当前节点ID（兼容所有版本）
        String processDefinitionId = execution.getProcessDefinitionId(); // 流程定义ID

        // 2. 根据节点ID查询节点名称（核心修正：通过流程定义获取名称）
        String currentNodeName = getNodeNameByActivityId(processDefinitionId, currentActivityId);
        if (currentNodeName == null) {
            throw new RuntimeException("未找到节点ID=" + currentActivityId + "的名称");
        }

        // 获取申请表id
        Long accommodationId = Long.valueOf(execution.getVariable("accommodationId").toString());

        // 获取审核意见
        String approvalOpinion = (String) execution.getVariable("approvalOpinion");

        // 获取审核状态（兼容Integer/Long类型）
        Object approvalResultObj = execution.getVariable("approvalResult");
        Long approvalResult = null;
        if (approvalResultObj != null) {
            // 先转为数字，再获取long值
            Number num = (Number) approvalResultObj;
            approvalResult = num.longValue();
        }


        OutsideAccommodationApplyMapper outsideAccommodationApplyMapper = SpringUtils.getBean(OutsideAccommodationApplyMapper.class);
        // 根据Id查询外宿申请记录
        OutsideAccommodationApply outsideAccommodationApply = outsideAccommodationApplyMapper.selectDmsOutsideAccommodationApplyById(accommodationId);
        // 添加审批记录
        saveApprovalRecord(outsideAccommodationApply.getId(), outsideAccommodationApply.getProcessInstanceId(),outsideAccommodationApply.getApplyNo(),currentNodeName, outsideAccommodationApply.getStudentName(), outsideAccommodationApply.getStudentNo(), approvalOpinion, approvalResult);
        Long status = 1L;
        if (currentNodeName.equals("辅导员审批")) {
            status = 2L;
        }
        if (currentNodeName.equals("二级学院书记审批")) {
            status = 3L;
        }
        if (currentNodeName.equals("学工处审批")) {
            status = 4L;
        }
        // 如果到了最后一个审批人，则修改申请表审核状态
        if (currentNodeName.equals("学校领导审批")){
            // 改变申请表中的审核状态（审核通过）
            status = 5L;
        }
        outsideAccommodationApply.setStatus(status);
        outsideAccommodationApplyMapper.updateDmsOutsideAccommodationApply(outsideAccommodationApply);
    }

    /**
     * 根据节点ID和流程定义ID，查询节点名称（兼容所有版本的核心方法）
     */
    private String getNodeNameByActivityId(String processDefinitionId, String activityId) {
        // 获取流程模型
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        if (bpmnModel == null) {
            throw new RuntimeException("未找到流程定义ID=" + processDefinitionId + "的模型");
        }

        // 从模型中获取节点信息（FlowNode包含用户任务、网关等节点）
        FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(activityId);
        return flowNode != null ? flowNode.getName() : null;
    }

    /**
     * 通用审批记录保存方法
     */
    private void saveApprovalRecord(Long ApplyId,String processInstanceId, String applyNo, String nodeName, String studentName, String studentNo, String approvalOpinion, Long approvalResult) {
        OutsideAccommodationApproval outsideAccommodationApproval = new OutsideAccommodationApproval();
        // 赋值
        outsideAccommodationApproval.setApplyId(ApplyId);
        outsideAccommodationApproval.setProcessInstanceId(processInstanceId);
        outsideAccommodationApproval.setApplyNo(applyNo);
        outsideAccommodationApproval.setApprovalNode(nodeName);
        outsideAccommodationApproval.setApproverId(SecurityUtils.getLoginUser().getUser().getUserId());
        // SecurityUtils.getUserName()是工号
        outsideAccommodationApproval.setApproverName(SecurityUtils.getLoginUser().getUser().getNickName());
//        System.out.println(SecurityUtils.getLoginUser().getUser());
        // 若变量未传递，直接用默认值“同意”（前端点击同意按钮的默认意见）
        outsideAccommodationApproval.setApprovalOpinion(approvalOpinion);

        // 审核状态
        outsideAccommodationApproval.setApprovalResult(approvalResult == null ? 0L : approvalResult);

        // 审批时间：当前系统时间
        outsideAccommodationApproval.setApprovalTime(new Date());
        outsideAccommodationApproval.setStudentName(studentName);
        outsideAccommodationApproval.setStudentNo(studentNo);
        OutsideAccommodationApprovalMapper outsideAccommodationApprovalMapper = (OutsideAccommodationApprovalMapper) SpringUtils.getBean(OutsideAccommodationApprovalMapper.class);
        // 查询审批记录是否存在
        OutsideAccommodationApproval approval = outsideAccommodationApprovalMapper.selectOutsideAccommodationApprovalByStuName(studentName, studentNo, SecurityUtils.getLoginUser().getUser().getUserId());
        if (approval == null) {
            outsideAccommodationApprovalMapper.insertDmsOutsideAccommodationApproval(outsideAccommodationApproval);
        } else {
            approval.setId(approval.getId());
            outsideAccommodationApprovalMapper.insertDmsOutsideAccommodationApproval(outsideAccommodationApproval);
        }
    }
}