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

import cn.hutool.core.date.DateUtil;
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
import com.qqchen.deploy.backend.workflow.dto.event.WorkflowInstanceStatusChangeEvent;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.delegate.event.FlowableProcessEngineEvent;
import org.flowable.engine.history.HistoricProcessInstance;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;

@Slf4j
@Component
public class ProcessEventHandler implements IFlowableEventHandler {

    @Resource
    private ApplicationEventPublisher publisher;

    @Resource
    @Lazy
    private ProcessEngine processEngine;

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

    @Override
    public void handle(FlowableEvent event) {
        String eventType = event.getType().name();
        FlowableProcessEngineEvent processEvent = (FlowableProcessEngineEvent) event;
        WorkflowInstanceStatusEnums status = convertToWorkflowStatus(eventType);

        if (status != null) {

            HistoricProcessInstance historicProcessInstance = processEngine.getHistoryService()
                .createHistoricProcessInstanceQuery()
                .processInstanceId(processEvent.getProcessInstanceId())
                .singleResult();

            publisher.publishEvent(WorkflowInstanceStatusChangeEvent.builder()
                .processInstanceId(processEvent.getProcessInstanceId())
                .status(status)
                .endTime(historicProcessInstance != null && historicProcessInstance.getEndTime() != null ?
                    DateUtil.toLocalDateTime(historicProcessInstance.getEndTime()) : null)
                .build()
            );
        }
    }

    private WorkflowInstanceStatusEnums convertToWorkflowStatus(String eventType) {
        return switch (eventType) {
            case "PROCESS_CREATED" -> WorkflowInstanceStatusEnums.CREATED;
            case "PROCESS_STARTED" -> WorkflowInstanceStatusEnums.RUNNING;
            case "PROCESS_COMPLETED" -> WorkflowInstanceStatusEnums.COMPLETED;
            case "PROCESS_CANCELLED" -> WorkflowInstanceStatusEnums.FAILED;
            case "PROCESS_SUSPENDED" -> WorkflowInstanceStatusEnums.SUSPENDED;
//            case "PROCESS_RESUMED" -> WorkflowInstanceStatusEnums.RUNNING;
            case "PROCESS_COMPLETED_WITH_TERMINATE_END_EVENT" -> WorkflowInstanceStatusEnums.TERMINATED;
            default -> null;
        };
    }

}