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

import cn.hutool.json.JSONUtil;
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;
        }
        JobEntityImpl job = (JobEntityImpl) entityEvent.getEntity();
        log.info("Processing job event: {}", JSONUtil.toJsonStr(job));
        WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType);
        switch (status) {
            case FAILED -> {
                publisher.publishEvent(new TerminationProcessInstanceListenerEvent(job.getId(), job.getProcessInstanceId(), ((FlowableEntityExceptionEventImpl) event).getCause().getMessage()));
            }
            default -> {

            }
        }
//        if (status != null) {
//            publisher.publishEvent(WorkflowNodeInstanceStatusChangeEvent.builder()
//                .processInstanceId(job.getProcessInstanceId())
//                .executionId(job.getExecutionId())
//                .nodeId(job.getElementId())
//                .nodeName(job.getElementName())
//                .nodeType(job.getJobHandlerType())
//                .status(status)
//                .startTime(job.getCreateTime() != null ? DateUtil.toLocalDateTime(job.getCreateTime()) : null)
//                .endTime(status.isFinalState() ? LocalDateTime.now() : null)
//                .build()
//            );
//        }
    }

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