package com.dne.ems.controller;

import java.time.LocalDate;
import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.dne.ems.dto.TaskApprovalRequest;
import com.dne.ems.dto.TaskAssignmentRequest;
import com.dne.ems.dto.TaskCreationRequest;
import com.dne.ems.dto.TaskDetailDTO;
import com.dne.ems.dto.TaskFromFeedbackRequest;
import com.dne.ems.dto.TaskRejectionRequest;
import com.dne.ems.dto.TaskSummaryDTO;
import com.dne.ems.model.Feedback;
import com.dne.ems.model.enums.PollutionType;
import com.dne.ems.model.enums.SeverityLevel;
import com.dne.ems.model.enums.TaskStatus;
import com.dne.ems.service.TaskManagementService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

/**
 * 任务管理控制器，处理任务全生命周期管理
 *
 * <p>主要功能：
 * <ul>
 *   <li>任务创建与分配</li>
 *   <li>任务状态管理</li>
 *   <li>任务审核与审批</li>
 *   <li>从反馈创建任务</li>
 * </ul>
 *
 * @author DNE开发团队
 * @version 1.0
 * @since 2024
 */
@RestController
@RequestMapping("/api/management/tasks")
@RequiredArgsConstructor
@PreAuthorize("hasRole('SUPERVISOR')")
public class TaskManagementController {

    private final TaskManagementService taskManagementService;

    /**
     * 获取任务分页列表(支持多条件过滤)
     *
     * @param status 任务状态过滤条件
     * @param assigneeId 分配人ID过滤条件
     * @param severity 严重程度过滤条件
     * @param pollutionType 污染类型过滤条件
     * @param startDate 开始日期过滤条件(yyyy-MM-dd)
     * @param endDate 结束日期过滤条件(yyyy-MM-dd)
     * @param pageable 分页参数
     * @return 任务分页列表
     * @throws AccessDeniedException 如果用户无权限
     */
    @Operation(summary = "Get a paginated list of tasks", description = "Retrieves tasks with advanced filtering options.")
    @GetMapping
    @PreAuthorize("hasAnyAuthority('ADMIN', 'SUPERVISOR', 'DECISION_MAKER')")
    public ResponseEntity<List<TaskSummaryDTO>> getTasks(
        @Parameter(description = "Filter by task status") @RequestParam(required = false) TaskStatus status,
        @Parameter(description = "Filter by assignee ID") @RequestParam(required = false) Long assigneeId,
        @Parameter(description = "Filter by severity level") @RequestParam(required = false) SeverityLevel severity,
        @Parameter(description = "Filter by pollution type") @RequestParam(required = false) PollutionType pollutionType,
        @Parameter(description = "Start date for filtering tasks (format: yyyy-MM-dd)") @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
        @Parameter(description = "End date for filtering tasks (format: yyyy-MM-dd)") @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate,
        Pageable pageable
    ) {
        Page<TaskSummaryDTO> tasks = taskManagementService.getTasks(status, assigneeId, severity, pollutionType, startDate, endDate, pageable);
        return ResponseEntity.ok(tasks.getContent());
    }

    /**
     * 分配任务给工作人员
     *
     * @param taskId 任务ID
     * @param request 包含分配信息的请求体
     * @return 更新后的任务摘要
     * @throws ResourceNotFoundException 如果任务不存在
     * @throws InvalidOperationException 如果任务已分配
     */
    @PostMapping("/{taskId}/assign")
    public ResponseEntity<TaskSummaryDTO> assignTask(
            @PathVariable Long taskId,
            @RequestBody @Valid TaskAssignmentRequest request) {
        TaskSummaryDTO updatedTask = taskManagementService.assignTask(taskId, request);
        return ResponseEntity.ok(updatedTask);
    }

    /**
     * 获取任务详情
     *
     * @param taskId 任务ID
     * @return 任务详情DTO
     * @throws ResourceNotFoundException 如果任务不存在
     */
    @GetMapping("/{taskId}")
    public ResponseEntity<TaskDetailDTO> getTaskDetails(@PathVariable Long taskId) {
        TaskDetailDTO taskDetails = taskManagementService.getTaskDetails(taskId);
        return ResponseEntity.ok(taskDetails);
    }

    /**
     * 审核任务
     *
     * @param taskId 任务ID
     * @param request 包含审核信息的请求体
     * @return 更新后的任务详情
     * @throws ResourceNotFoundException 如果任务不存在
     * @throws InvalidOperationException 如果任务状态不允许审核
     */
    @PostMapping("/{taskId}/review")
    public ResponseEntity<TaskDetailDTO> reviewTask(
            @PathVariable Long taskId,
            @RequestBody @Valid TaskApprovalRequest request) {
        TaskDetailDTO updatedTask = taskManagementService.reviewTask(taskId, request);
        return ResponseEntity.ok(updatedTask);
    }

    /**
     * 取消任务
     *
     * @param taskId 任务ID
     * @return 更新后的任务详情
     * @throws ResourceNotFoundException 如果任务不存在
     * @throws InvalidOperationException 如果任务状态不允许取消
     */
    @PostMapping("/{taskId}/cancel")
    public ResponseEntity<TaskDetailDTO> cancelTask(@PathVariable Long taskId) {
        TaskDetailDTO updatedTask = taskManagementService.cancelTask(taskId);
        return ResponseEntity.ok(updatedTask);
    }

    /**
     * 创建新任务
     *
     * @param request 包含任务信息的请求体
     * @return 创建的任务详情
     * @throws InvalidRequestException 如果请求参数无效
     */
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public ResponseEntity<TaskDetailDTO> createTask(@RequestBody @Valid TaskCreationRequest request) {
        TaskDetailDTO createdTask = taskManagementService.createTask(request);
        return ResponseEntity.status(HttpStatus.CREATED).body(createdTask);
    }

    /**
     * 获取待处理反馈列表
     *
     * @return 待处理反馈列表
     * @throws AccessDeniedException 如果用户无权限
     */
    @GetMapping("/feedback")
    @PreAuthorize("hasAnyRole('SUPERVISOR', 'ADMIN')")
    public ResponseEntity<List<Feedback>> getPendingFeedback() {
        List<Feedback> feedbackList = taskManagementService.getPendingFeedback();
        return ResponseEntity.ok(feedbackList);
    }

    /**
     * 从反馈创建任务
     *
     * @param feedbackId 反馈ID
     * @param request 包含任务信息的请求体
     * @return 创建的任务详情
     * @throws ResourceNotFoundException 如果反馈不存在
     * @throws InvalidOperationException 如果反馈已处理
     */
    @PostMapping("/feedback/{feedbackId}/create-task")
    @PreAuthorize("hasRole('SUPERVISOR')")
    public ResponseEntity<TaskDetailDTO> createTaskFromFeedback(
            @PathVariable Long feedbackId,
            @RequestBody @Valid TaskFromFeedbackRequest request) {
        TaskDetailDTO createdTask = taskManagementService.createTaskFromFeedback(feedbackId, request);
        return ResponseEntity.status(HttpStatus.CREATED).body(createdTask);
    }

    /**
     * 批准任务，将状态更新为"已完成"
     *
     * @param taskId 任务ID
     * @return 更新后的任务详情
     * @throws ResourceNotFoundException 如果任务不存在
     * @throws InvalidOperationException 如果任务状态不是"已提交"
     */
    @PostMapping("/{taskId}/approve")
    @PreAuthorize("hasRole('ADMIN')")
    @Operation(summary = "Approve a task", description = "Approves a submitted task, changing its status to COMPLETED.")
    public ResponseEntity<TaskDetailDTO> approveTask(@PathVariable Long taskId) {
        TaskDetailDTO updatedTask = taskManagementService.approveTask(taskId);
        return ResponseEntity.ok(updatedTask);
    }

    /**
     * 拒绝任务，将状态更新为"进行中"
     *
     * @param taskId 任务ID
     * @param request 包含拒绝理由的请求体
     * @return 更新后的任务详情
     * @throws ResourceNotFoundException 如果任务不存在
     * @throws InvalidOperationException 如果任务状态不是"已提交"
     */
    @PostMapping("/{taskId}/reject")
    @PreAuthorize("hasRole('ADMIN')")
    @Operation(summary = "Reject a task", description = "Rejects a submitted task, changing its status back to IN_PROGRESS.")
    public ResponseEntity<TaskDetailDTO> rejectTask(
            @PathVariable Long taskId,
            @RequestBody @Valid TaskRejectionRequest request) {
        TaskDetailDTO updatedTask = taskManagementService.rejectTask(taskId, request.getReason());
        return ResponseEntity.ok(updatedTask);
    }
} 