package com.qqchen.deploy.backend.workflow.event.handler;

import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums;
import com.qqchen.deploy.backend.workflow.dto.event.TerminationProcessInstanceListenerEvent;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.common.engine.impl.event.FlowableEntityExceptionEventImpl;
import org.flowable.job.service.impl.persistence.entity.JobEntityImpl;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;

@Slf4j
@Component
public class JobEventHandler implements IFlowableEventHandler {

    @Resource
    @Lazy
    private ApplicationEventPublisher publisher;

    @Override
    public boolean canHandle(String eventType) {
        return eventType.startsWith("JOB_EXECUTION_");
    }

    @Override
    public void handle(FlowableEvent event) {
        String eventType = event.getType().name();
        if (!(event instanceof FlowableEngineEntityEvent entityEvent)) {
            return;
        }
        
        // ✅ 类型转换安全：检查实体类型
        Object entity = entityEvent.getEntity();
        if (!(entity instanceof JobEntityImpl job)) {
            log.debug("Job event entity is not JobEntityImpl, skipping: {}", entity.getClass().getName());
            return;
        }
        
        log.debug("Processing job event: jobId={}, processInstanceId={}", job.getId(), job.getProcessInstanceId());
        WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType);
        
        // ✅ 类型转换安全：只在失败事件时转换为异常事件获取错误信息
        if (status == WorkflowNodeInstanceStatusEnums.FAILED) {
            String errorMessage = null;
            if (event instanceof FlowableEntityExceptionEventImpl exceptionEvent) {
                Throwable cause = exceptionEvent.getCause();
                errorMessage = cause != null ? cause.getMessage() : "Job execution failed";
            } else {
                errorMessage = "Job execution failed";
            }
            publisher.publishEvent(new TerminationProcessInstanceListenerEvent(
                job.getId(), 
                job.getProcessInstanceId(), 
                errorMessage
            ));
        }
    }

    private WorkflowNodeInstanceStatusEnums convertToNodeStatus(String eventType) {
        return switch (eventType) {
            case "JOB_EXECUTION_SUCCESS" -> WorkflowNodeInstanceStatusEnums.RUNNING;
            case "JOB_EXECUTION_FAILURE" -> WorkflowNodeInstanceStatusEnums.FAILED;
            default -> null;
        };
    }
}