package com.qqchen.deploy.backend.workflow.api;

import com.qqchen.deploy.backend.framework.api.Response;
import com.qqchen.deploy.backend.framework.controller.BaseController;
import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeInstanceDTO;
import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeInstance;
import com.qqchen.deploy.backend.workflow.dto.event.ShellLogEvent;
import com.qqchen.deploy.backend.workflow.dto.query.WorkflowNodeInstanceQuery;
import com.qqchen.deploy.backend.workflow.service.IWorkflowNodeInstanceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 工作流节点实例控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/workflow/node")
@Tag(name = "工作流节点实例管理", description = "工作流节点实例管理相关接口")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class WorkflowNodeInstanceApiController extends BaseController<WorkflowNodeInstance, WorkflowNodeInstanceDTO, Long, WorkflowNodeInstanceQuery> {
    
    @Resource
    private IWorkflowNodeInstanceService workflowNodeInstanceService;
    
    // 存储每个进程的SSE发射器
    private static final Map<String, SseEmitter> EMITTERS = new ConcurrentHashMap<>();
    
    @Operation(summary = "获取流程实例的所有节点")
    @GetMapping("/list/{processInstanceId}")
    public Response<List<WorkflowNodeInstanceDTO>> getNodeInstances(
        @Parameter(description = "流程实例ID") @PathVariable String processInstanceId
    ) {
        return Response.success(workflowNodeInstanceService.getNodesByProcessInstanceId(processInstanceId));
    }
    
    @Operation(summary = "获取节点执行日志")
    @GetMapping(value = "/log/{processInstanceId}", produces = "text/event-stream")
    public SseEmitter streamLogs(
        @Parameter(description = "流程实例ID") @PathVariable String processInstanceId
    ) {
        SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
        
        // 设置超时回调
        emitter.onTimeout(() -> {
            EMITTERS.remove(processInstanceId);
            log.debug("SSE connection timeout for process: {}", processInstanceId);
        });
        
        emitter.onCompletion(() -> {
            EMITTERS.remove(processInstanceId);
            log.debug("SSE connection completed for process: {}", processInstanceId);
        });
        
        emitter.onError(ex -> {
            EMITTERS.remove(processInstanceId);
            log.error("SSE connection error for process: {}", processInstanceId, ex);
        });
        
        EMITTERS.put(processInstanceId, emitter);
        
        // 发送初始连接成功消息
        try {
            emitter.send(SseEmitter.event()
                .name("STDOUT")
                .data("Connected successfully to process " + processInstanceId));
        } catch (IOException e) {
            log.error("Error sending initial message", e);
        }
        
        return emitter;
    }
    
    @EventListener
    public void handleShellLogEvent(ShellLogEvent event) {
        String processInstanceId = event.getProcessInstanceId();
        log.debug("Received log event for process: {}, type: {}, message: {}", 
            processInstanceId, event.getLogType(), event.getLogMessage());
            
        SseEmitter emitter = EMITTERS.get(processInstanceId);
        if (emitter != null) {
            try {
                // 发送日志事件到客户端
                emitter.send(SseEmitter.event()
                    .name(event.getLogType().toString())
                    .data(event.getLogMessage()));
                log.debug("Sent log event to client for process: {}", processInstanceId);
            } catch (IOException e) {
                log.error("Error sending event for process: {}", processInstanceId, e);
                EMITTERS.remove(processInstanceId);
                emitter.completeWithError(e);
            }
        } else {
//            log.warn("No emitter found for process: {}", processInstanceId);
        }
    }

    @Override
    protected void exportData(HttpServletResponse response, List<WorkflowNodeInstanceDTO> data) {

    }
}