package com.flowable.devops.controller;

import com.flowable.devops.entity.WorkflowDefinition;
import com.flowable.devops.entity.WorkflowExecution;
import com.flowable.devops.service.WorkflowService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import jakarta.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * 工作流REST API控制器
 * 
 * 提供工作流定义和执行的HTTP API接口
 */
@Slf4j
@RestController
@RequestMapping("/api/workflows")
@CrossOrigin(origins = "*")
public class WorkflowController {
    
    @Autowired
    private WorkflowService workflowService;
    
    /**
     * 获取工作流列表
     */
    @GetMapping
    public Mono<ResponseEntity<List<WorkflowDefinition>>> getWorkflows(
            @RequestParam(required = false) String status) {
        log.info("获取工作流列表，状态过滤: {}", status);
        
        return Mono.fromCallable(() -> workflowService.list(status))
                .map(workflows -> {
                    log.info("返回 {} 个工作流定义", workflows.size());
                    return ResponseEntity.ok(workflows);
                })
                .onErrorResume(e -> {
                    log.error("获取工作流列表失败", e);
                    return Mono.just(ResponseEntity.internalServerError().build());
                });
    }
    
    /**
     * 根据ID获取工作流定义
     */
    @GetMapping("/{id}")
    public Mono<ResponseEntity<WorkflowDefinition>> getWorkflow(@PathVariable String id) {
        log.info("获取工作流定义: {}", id);
        
        return Mono.fromCallable(() -> workflowService.getById(id))
                .map(ResponseEntity::ok)
                .onErrorResume(e -> {
                    log.error("获取工作流定义失败: {}", id, e);
                    return Mono.just(ResponseEntity.notFound().build());
                });
    }
    
    /**
     * 创建工作流定义
     */
    @PostMapping
    public Mono<ResponseEntity<WorkflowDefinition>> createWorkflow(
            @Valid @RequestBody WorkflowDefinition workflow) {
        log.info("创建工作流定义: {}", workflow.getName());
        
        return Mono.fromCallable(() -> workflowService.create(workflow))
                .subscribeOn(reactor.core.scheduler.Schedulers.boundedElastic())
                .map(created -> {
                    log.info("工作流定义创建成功: {} (ID: {})", created.getName(), created.getId());
                    return ResponseEntity.ok(created);
                })
                .onErrorResume(e -> {
                    log.error("创建工作流定义失败: {}", workflow.getName(), e);
                    return Mono.just(ResponseEntity.badRequest().build());
                });
    }
    
    /**
     * 更新工作流定义
     */
    @PutMapping("/{id}")
    public Mono<ResponseEntity<WorkflowDefinition>> updateWorkflow(
            @PathVariable String id,
            @Valid @RequestBody WorkflowDefinition workflow) {
        log.info("更新工作流定义: {}", id);
        
        return Mono.fromCallable(() -> workflowService.update(id, workflow))
                .map(updated -> {
                    log.info("工作流定义更新成功: {}", id);
                    return ResponseEntity.ok(updated);
                })
                .onErrorResume(e -> {
                    log.error("更新工作流定义失败: {}", id, e);
                    return Mono.just(ResponseEntity.badRequest().build());
                });
    }
    
    /**
     * 删除工作流定义
     */
    @DeleteMapping("/{id}")
    public Mono<ResponseEntity<Void>> deleteWorkflow(@PathVariable String id) {
        log.info("删除工作流定义: {}", id);
        
        return Mono.fromRunnable(() -> workflowService.delete(id))
                .then(Mono.fromCallable(() -> {
                    log.info("工作流定义删除成功: {}", id);
                    return ResponseEntity.ok().<Void>build();
                }))
                .onErrorResume(e -> {
                    log.error("删除工作流定义失败: {}", id, e);
                    return Mono.just(ResponseEntity.badRequest().build());
                });
    }
    
    /**
     * 激活工作流定义
     */
    @PostMapping("/{id}/activate")
    public Mono<ResponseEntity<WorkflowDefinition>> activateWorkflow(@PathVariable String id) {
        log.info("激活工作流定义: {}", id);
        
        return Mono.fromCallable(() -> workflowService.activate(id))
                .map(activated -> {
                    log.info("工作流定义激活成功: {}", id);
                    return ResponseEntity.ok(activated);
                })
                .onErrorResume(e -> {
                    log.error("激活工作流定义失败: {}", id, e);
                    return Mono.just(ResponseEntity.badRequest().build());
                });
    }
    
    /**
     * 执行工作流
     */
    @PostMapping("/{id}/execute")
    public Mono<ResponseEntity<WorkflowService.WorkflowExecutionResult>> executeWorkflow(
            @PathVariable String id,
            @RequestBody(required = false) Map<String, Object> input) {
        log.info("执行工作流: {} (输入: {})", id, input);
        
        return Mono.fromCallable(() -> {
            Map<String, Object> safeInput = input != null ? input : Map.of();
            return workflowService.execute(id, safeInput);
        })
                .map(result -> {
                    log.info("工作流执行完成: {} -> {}", id, result.getExecutionId());
                    return ResponseEntity.ok(result);
                })
                .onErrorResume(e -> {
                    log.error("执行工作流失败: {}", id, e);
                    return Mono.just(ResponseEntity.badRequest().build());
                });
    }
    
    /**
     * 获取工作流执行历史
     */
    @GetMapping("/{id}/executions")
    public Mono<ResponseEntity<List<WorkflowExecution>>> getExecutions(@PathVariable String id) {
        log.info("获取工作流执行历史: {}", id);
        
        return Mono.fromCallable(() -> workflowService.getExecutions(id))
                .map(executions -> {
                    log.info("返回 {} 个执行记录", executions.size());
                    return ResponseEntity.ok(executions);
                })
                .onErrorResume(e -> {
                    log.error("获取工作流执行历史失败: {}", id, e);
                    return Mono.just(ResponseEntity.internalServerError().build());
                });
    }
    
    /**
     * 获取执行详情
     */
    @GetMapping("/executions/{executionId}")
    public Mono<ResponseEntity<WorkflowService.WorkflowExecutionDetail>> getExecutionDetail(
            @PathVariable String executionId) {
        log.info("获取执行详情: {}", executionId);
        
        return Mono.fromCallable(() -> workflowService.getExecutionDetail(executionId))
                .map(ResponseEntity::ok)
                .onErrorResume(e -> {
                    log.error("获取执行详情失败: {}", executionId, e);
                    return Mono.just(ResponseEntity.notFound().build());
                });
    }
    
    /**
     * 健康检查接口
     */
    @GetMapping("/health")
    public Mono<ResponseEntity<Map<String, String>>> health() {
        return Mono.just(ResponseEntity.ok(Map.of(
                "status", "UP",
                "service", "workflow-service",
                "timestamp", String.valueOf(System.currentTimeMillis())
        )));
    }
}