package com.flowable.devops.controller;

import com.flowable.devops.service.TaskService;
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.Mono;

import java.util.List;
import java.util.Map;

/**
 * 任务REST API控制器
 * 
 * 提供任务管理和审批的HTTP API接口
 */
@Slf4j
@RestController
@RequestMapping("/api/tasks")
@CrossOrigin(origins = "*")
public class TaskController {
    
    @Autowired
    private TaskService taskService;
    
    /**
     * 获取用户待办任务
     */
    @GetMapping("/assigned")
    public Mono<ResponseEntity<List<TaskService.TaskInfo>>> getAssignedTasks(
            @RequestParam String userId) {
        log.info("获取用户待办任务: {}", userId);
        
        return Mono.fromCallable(() -> taskService.getTasks(userId))
                .map(tasks -> {
                    log.info("用户 {} 返回 {} 个待办任务", userId, tasks.size());
                    return ResponseEntity.ok(tasks);
                })
                .onErrorResume(e -> {
                    log.error("获取待办任务失败: {}", userId, e);
                    return Mono.just(ResponseEntity.internalServerError().build());
                });
    }
    
    /**
     * 获取用户候选任务
     */
    @GetMapping("/candidate")
    public Mono<ResponseEntity<List<TaskService.TaskInfo>>> getCandidateTasks(
            @RequestParam String userId,
            @RequestParam(required = false) List<String> groups) {
        log.info("获取用户候选任务: {} (组: {})", userId, groups);
        
        return Mono.fromCallable(() -> taskService.getCandidateTasks(userId, groups))
                .map(tasks -> {
                    log.info("用户 {} 返回 {} 个候选任务", userId, tasks.size());
                    return ResponseEntity.ok(tasks);
                })
                .onErrorResume(e -> {
                    log.error("获取候选任务失败: {}", userId, e);
                    return Mono.just(ResponseEntity.internalServerError().build());
                });
    }
    
    /**
     * 获取任务详情
     */
    @GetMapping("/{taskId}")
    public Mono<ResponseEntity<TaskService.TaskDetail>> getTaskDetail(@PathVariable String taskId) {
        log.info("获取任务详情: {}", taskId);
        
        return Mono.fromCallable(() -> taskService.getTaskDetail(taskId))
                .map(ResponseEntity::ok)
                .onErrorResume(e -> {
                    log.error("获取任务详情失败: {}", taskId, e);
                    return Mono.just(ResponseEntity.notFound().build());
                });
    }
    
    /**
     * 完成任务
     */
    @PostMapping("/{taskId}/complete")
    public Mono<ResponseEntity<Map<String, String>>> completeTask(
            @PathVariable String taskId,
            @RequestBody Map<String, Object> request) {
        String userId = (String) request.get("userId");
        String comment = (String) request.get("comment");
        @SuppressWarnings("unchecked")
        Map<String, Object> variables = (Map<String, Object>) request.get("variables");
        
        log.info("完成任务: {} (用户: {}, 评论: {})", taskId, userId, comment);
        
        return Mono.fromRunnable(() -> taskService.completeTask(taskId, userId, variables, comment))
                .then(Mono.fromCallable(() -> {
                    log.info("任务完成成功: {} (用户: {})", taskId, userId);
                    return ResponseEntity.ok(Map.of(
                            "status", "success",
                            "message", "任务完成成功",
                            "taskId", taskId,
                            "timestamp", String.valueOf(System.currentTimeMillis())
                    ));
                }))
                .onErrorResume(e -> {
                    log.error("完成任务失败: {} (用户: {})", taskId, userId, e);
                    return Mono.just(ResponseEntity.badRequest().build());
                });
    }
    
    /**
     * 认领任务
     */
    @PostMapping("/{taskId}/claim")
    public Mono<ResponseEntity<Map<String, String>>> claimTask(
            @PathVariable String taskId,
            @RequestBody Map<String, String> request) {
        String userId = request.get("userId");
        log.info("认领任务: {} (用户: {})", taskId, userId);
        
        return Mono.fromRunnable(() -> taskService.claimTask(taskId, userId))
                .then(Mono.fromCallable(() -> {
                    log.info("任务认领成功: {} (用户: {})", taskId, userId);
                    return ResponseEntity.ok(Map.of(
                            "status", "success",
                            "message", "任务认领成功",
                            "taskId", taskId,
                            "timestamp", String.valueOf(System.currentTimeMillis())
                    ));
                }))
                .onErrorResume(e -> {
                    log.error("认领任务失败: {} (用户: {})", taskId, userId, e);
                    return Mono.just(ResponseEntity.badRequest().build());
                });
    }
    
    /**
     * 释放任务
     */
    @PostMapping("/{taskId}/unclaim")
    public Mono<ResponseEntity<Map<String, String>>> unclaimTask(
            @PathVariable String taskId,
            @RequestBody Map<String, String> request) {
        String userId = request.get("userId");
        log.info("释放任务: {} (用户: {})", taskId, userId);
        
        return Mono.fromRunnable(() -> taskService.unclaimTask(taskId, userId))
                .then(Mono.fromCallable(() -> {
                    log.info("任务释放成功: {} (用户: {})", taskId, userId);
                    return ResponseEntity.ok(Map.of(
                            "status", "success",
                            "message", "任务释放成功",
                            "taskId", taskId,
                            "timestamp", String.valueOf(System.currentTimeMillis())
                    ));
                }))
                .onErrorResume(e -> {
                    log.error("释放任务失败: {} (用户: {})", taskId, userId, e);
                    return Mono.just(ResponseEntity.badRequest().build());
                });
    }
    
    /**
     * 委派任务
     */
    @PostMapping("/{taskId}/delegate")
    public Mono<ResponseEntity<Map<String, String>>> delegateTask(
            @PathVariable String taskId,
            @RequestBody Map<String, String> request) {
        String fromUserId = request.get("fromUserId");
        String toUserId = request.get("toUserId");
        String comment = request.get("comment");
        
        log.info("委派任务: {} (从 {} 到 {}, 评论: {})", taskId, fromUserId, toUserId, comment);
        
        return Mono.fromRunnable(() -> taskService.delegateTask(taskId, fromUserId, toUserId, comment))
                .then(Mono.fromCallable(() -> {
                    log.info("任务委派成功: {} -> {}", taskId, toUserId);
                    return ResponseEntity.ok(Map.of(
                            "status", "success",
                            "message", "任务委派成功",
                            "taskId", taskId,
                            "timestamp", String.valueOf(System.currentTimeMillis())
                    ));
                }))
                .onErrorResume(e -> {
                    log.error("委派任务失败: {} (从 {} 到 {})", taskId, fromUserId, toUserId, e);
                    return Mono.just(ResponseEntity.badRequest().build());
                });
    }
    
    /**
     * 转办任务
     */
    @PostMapping("/{taskId}/transfer")
    public Mono<ResponseEntity<Map<String, String>>> transferTask(
            @PathVariable String taskId,
            @RequestBody Map<String, String> request) {
        String fromUserId = request.get("fromUserId");
        String toUserId = request.get("toUserId");
        String comment = request.get("comment");
        
        log.info("转办任务: {} (从 {} 到 {}, 评论: {})", taskId, fromUserId, toUserId, comment);
        
        return Mono.fromRunnable(() -> taskService.transferTask(taskId, fromUserId, toUserId, comment))
                .then(Mono.fromCallable(() -> {
                    log.info("任务转办成功: {} -> {}", taskId, toUserId);
                    return ResponseEntity.ok(Map.of(
                            "status", "success",
                            "message", "任务转办成功",
                            "taskId", taskId,
                            "timestamp", String.valueOf(System.currentTimeMillis())
                    ));
                }))
                .onErrorResume(e -> {
                    log.error("转办任务失败: {} (从 {} 到 {})", taskId, fromUserId, toUserId, e);
                    return Mono.just(ResponseEntity.badRequest().build());
                });
    }
    
    /**
     * 获取任务评论
     */
    @GetMapping("/{taskId}/comments")
    public Mono<ResponseEntity<List<TaskService.TaskComment>>> getTaskComments(@PathVariable String taskId) {
        log.info("获取任务评论: {}", taskId);
        
        return Mono.fromCallable(() -> taskService.getTaskComments(taskId))
                .map(comments -> {
                    log.info("任务 {} 返回 {} 条评论", taskId, comments.size());
                    return ResponseEntity.ok(comments);
                })
                .onErrorResume(e -> {
                    log.error("获取任务评论失败: {}", taskId, e);
                    return Mono.just(ResponseEntity.notFound().build());
                });
    }
    
    /**
     * 添加任务评论
     */
    @PostMapping("/{taskId}/comments")
    public Mono<ResponseEntity<TaskService.TaskComment>> addTaskComment(
            @PathVariable String taskId,
            @RequestBody Map<String, String> request) {
        String userId = request.get("userId");
        String message = request.get("message");
        
        log.info("添加任务评论: {} (用户: {}, 内容: {})", taskId, userId, message);
        
        return Mono.fromCallable(() -> taskService.addTaskComment(taskId, userId, message))
                .map(comment -> {
                    log.info("任务评论添加成功: {} (ID: {})", taskId, comment.getId());
                    return ResponseEntity.ok(comment);
                })
                .onErrorResume(e -> {
                    log.error("添加任务评论失败: {} (用户: {})", taskId, userId, e);
                    return Mono.just(ResponseEntity.badRequest().build());
                });
    }
    
    /**
     * 获取任务统计信息
     */
    @GetMapping("/statistics")
    public Mono<ResponseEntity<TaskService.TaskStatistics>> getTaskStatistics(
            @RequestParam String userId,
            @RequestParam(required = false) List<String> groups) {
        log.info("获取任务统计信息: {} (组: {})", userId, groups);
        
        return Mono.fromCallable(() -> taskService.getTaskStatistics(userId, groups))
                .map(stats -> {
                    log.info("用户 {} 统计信息: 待办 {}, 候选 {}, 逾期 {}", 
                            userId, stats.getAssignedCount(), stats.getCandidateCount(), stats.getOverdueCount());
                    return ResponseEntity.ok(stats);
                })
                .onErrorResume(e -> {
                    log.error("获取任务统计信息失败: {}", userId, e);
                    return Mono.just(ResponseEntity.internalServerError().build());
                });
    }
    
    /**
     * 健康检查接口
     */
    @GetMapping("/health")
    public Mono<ResponseEntity<Map<String, String>>> health() {
        return Mono.just(ResponseEntity.ok(Map.of(
                "status", "UP",
                "service", "task-service",
                "timestamp", String.valueOf(System.currentTimeMillis())
        )));
    }
}