package com.qqchen.deploy.backend.deploy.listener;

import com.qqchen.deploy.backend.deploy.service.IDeployRecordService;
import com.qqchen.deploy.backend.workflow.dto.event.WorkflowInstanceStatusChangeEvent;
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
import com.qqchen.deploy.backend.workflow.repository.IWorkflowInstanceRepository;
import com.qqchen.deploy.backend.workflow.repository.IWorkflowDefinitionRepository;
import com.qqchen.deploy.backend.workflow.repository.IWorkflowCategoryRepository;
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
import com.qqchen.deploy.backend.workflow.entity.WorkflowCategory;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * 部署记录工作流状态同步监听器
 * 监听工作流实例状态变化事件，同步更新部署记录状态
 *
 * @author qqchen
 * @since 2025-11-02
 */
@Slf4j
@Component
public class DeployRecordWorkflowStatusSyncListener {

    private static final String DEPLOYMENT_CATEGORY_CODE = "DEPLOYMENT";

    @Resource
    private IDeployRecordService deployRecordService;

    @Resource
    private IWorkflowInstanceRepository workflowInstanceRepository;

    @Resource
    private IWorkflowDefinitionRepository workflowDefinitionRepository;

    @Resource
    private IWorkflowCategoryRepository workflowCategoryRepository;

    /**
     * 监听工作流实例状态变化事件
     * 同步更新部署记录状态
     */
    @EventListener
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void handleWorkflowStatusChange(WorkflowInstanceStatusChangeEvent event) {
        try {
            // 1. 查询工作流实例
            WorkflowInstance instance = workflowInstanceRepository
                    .findByProcessInstanceId(event.getProcessInstanceId())
                    .orElse(null);

            if (instance == null) {
                log.warn("工作流实例不存在: processInstanceId={}", event.getProcessInstanceId());
                return;
            }

            // 2. 判断是否为部署类型的工作流（提前校验，避免不必要的操作）
            if (!isDeploymentWorkflow(instance)) {
                return;
            }

            // 3. 更新工作流实例的结束时间（如果事件中有且实例中还没有）
            if (event.getEndTime() != null && instance.getEndTime() == null) {
                instance.setEndTime(event.getEndTime());
                workflowInstanceRepository.save(instance);
            }

            // 4. 同步状态（处理状态优先级）
            // 注意：这里需要确保 instance 的 endTime 已更新，因为 syncStatusFromWorkflowInstance 会使用它
            deployRecordService.syncStatusFromWorkflowInstance(instance, event.getStatus());

        } catch (Exception e) {
            log.error("同步部署记录状态失败（工作流状态变化）: processInstanceId={}", 
                    event.getProcessInstanceId(), e);
            // 不影响主流程，只记录错误
        }
    }

    /**
     * 判断是否为部署类型的工作流
     */
    private boolean isDeploymentWorkflow(WorkflowInstance instance) {
        if (instance.getWorkflowDefinitionId() == null) {
            return false;
        }

        WorkflowDefinition definition = workflowDefinitionRepository
                .findById(instance.getWorkflowDefinitionId())
                .orElse(null);

        if (definition == null || definition.getCategoryId() == null) {
            return false;
        }

        WorkflowCategory category = workflowCategoryRepository
                .findById(definition.getCategoryId())
                .orElse(null);

        return category != null && DEPLOYMENT_CATEGORY_CODE.equals(category.getCode());
    }
}

