package com.writeoff.module.audit.controller;

import com.writeoff.common.api.ApiResponse;
import com.writeoff.common.api.PageResult;
import com.writeoff.module.audit.dto.AuditActionRequest;
import com.writeoff.module.audit.dto.AuditMaterialItemRejectRequest;
import com.writeoff.module.audit.dto.AuditMaterialModuleApproveRequest;
import com.writeoff.module.audit.dto.BatchAuditActionRequest;
import com.writeoff.module.audit.dto.BatchRemindRequest;
import com.writeoff.module.audit.dto.TransferAuditTaskRequest;
import com.writeoff.module.audit.model.AuditTask;
import com.writeoff.security.DataScopeType;
import com.writeoff.module.audit.service.AuditService;
import com.writeoff.security.RequirePermission;
import javax.validation.Valid;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("/api/audits")
public class AuditController {
    private final AuditService auditService;

    public AuditController(AuditService auditService) {
        this.auditService = auditService;
    }

    @GetMapping("/tasks")
    public ApiResponse<PageResult<AuditTask>> tasks(
            @RequestParam(value = "mine", required = false, defaultValue = "false") boolean mine,
            @RequestParam(value = "scope", required = false) String scope,
            @RequestParam(value = "meetingId", required = false) Long meetingId,
            @RequestParam(value = "pageNo", required = false) Integer pageNo,
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
            @RequestParam(value = "sortBy", required = false) String sortBy,
            @RequestParam(value = "order", required = false) String order
    ) {
        if (meetingId == null && pageNo == null && pageSize == null && sortBy == null && order == null) {
            return ApiResponse.success(auditService.listTasks(mine, scope));
        }
        return ApiResponse.success(auditService.listTasks(mine, scope, meetingId, pageNo, pageSize, sortBy, order));
    }

    @PostMapping("/tasks/{id}/approve")
    @RequirePermission(value = "audit.approve", dataScope = DataScopeType.MEETING, auditAction = "AUDIT_APPROVE")
    public ApiResponse<Map<String, Object>> approve(@PathVariable("id") Long taskId,
                                                    @RequestBody @Valid AuditActionRequest request) {
        return ApiResponse.success(auditService.approve(taskId, request));
    }

    @PostMapping("/tasks/{id}/reject")
    @RequirePermission(value = "audit.reject", dataScope = DataScopeType.MEETING, auditAction = "AUDIT_REJECT")
    public ApiResponse<Map<String, Object>> reject(@PathVariable("id") Long taskId,
                                                   @RequestBody @Valid AuditActionRequest request) {
        return ApiResponse.success(auditService.reject(taskId, request));
    }

    @PostMapping("/tasks/{id}/return")
    @RequirePermission(value = "audit.return", dataScope = DataScopeType.MEETING, auditAction = "AUDIT_RETURN")
    public ApiResponse<Map<String, Object>> back(@PathVariable("id") Long taskId,
                                                 @RequestBody @Valid AuditActionRequest request) {
        return ApiResponse.success(auditService.back(taskId, request));
    }

    @GetMapping("/export-opinions")
    @RequirePermission(value = "audit.export.opinions", dataScope = DataScopeType.TENANT, auditAction = "AUDIT_EXPORT_OPINIONS")
    public ApiResponse<Map<String, Object>> exportOpinions() {
        return ApiResponse.success(auditService.exportOpinions());
    }

    @GetMapping("/tasks/{id}/material")
    @RequirePermission(value = "audit.material.read", dataScope = DataScopeType.MEETING_MODULE, auditAction = "AUDIT_MATERIAL_READ")
    public ApiResponse<Map<String, Object>> readTaskMaterial(@PathVariable("id") Long id,
                                                              @RequestParam("moduleCode") String moduleCode) {
        return ApiResponse.success(auditService.readTaskMaterial(id, moduleCode));
    }

    @PostMapping("/tasks/{id}/material/approve-module")
    @RequirePermission(value = "audit.approve", dataScope = DataScopeType.MEETING_MODULE, auditAction = "AUDIT_MATERIAL_APPROVE_MODULE")
    public ApiResponse<Map<String, Object>> approveMaterialModule(@PathVariable("id") Long id,
                                                                  @RequestBody @Valid AuditMaterialModuleApproveRequest request) {
        return ApiResponse.success(auditService.approveMaterialModule(id, request));
    }

    @PostMapping("/tasks/{id}/material/reject-item")
    @RequirePermission(value = "audit.reject", dataScope = DataScopeType.MEETING_MODULE, auditAction = "AUDIT_MATERIAL_REJECT_ITEM")
    public ApiResponse<Map<String, Object>> rejectMaterialItem(@PathVariable("id") Long id,
                                                               @RequestBody @Valid AuditMaterialItemRejectRequest request) {
        return ApiResponse.success(auditService.rejectMaterialItem(id, request));
    }

    @PostMapping("/tasks/{id}/transfer")
    @RequirePermission(value = "audit.transfer", dataScope = DataScopeType.MEETING, auditAction = "AUDIT_TRANSFER")
    public ApiResponse<Map<String, Object>> transfer(@PathVariable("id") Long id,
                                                     @RequestBody @Valid TransferAuditTaskRequest request) {
        return ApiResponse.success(auditService.transfer(id, request));
    }

    @PostMapping("/tasks/batch-remind")
    @RequirePermission(value = "audit.remind", dataScope = DataScopeType.TENANT, auditAction = "AUDIT_BATCH_REMIND")
    public ApiResponse<Map<String, Object>> batchRemind(@RequestBody @Valid BatchRemindRequest request) {
        return ApiResponse.success(auditService.batchRemind(request));
    }

    @GetMapping("/tasks/sla-stat")
    @RequirePermission(value = "audit.sla.read", dataScope = DataScopeType.TENANT, auditAction = "AUDIT_SLA_STAT")
    public ApiResponse<Map<String, Object>> slaStat() {
        return ApiResponse.success(auditService.slaStat());
    }

    @PostMapping("/tasks/batch-approve")
    @RequirePermission(value = "audit.approve", dataScope = DataScopeType.TENANT, auditAction = "AUDIT_BATCH_APPROVE")
    public ApiResponse<Map<String, Object>> batchApprove(@RequestBody @Valid BatchAuditActionRequest request) {
        return ApiResponse.success(auditService.batchApprove(request));
    }

    @PostMapping("/tasks/batch-reject")
    @RequirePermission(value = "audit.reject", dataScope = DataScopeType.TENANT, auditAction = "AUDIT_BATCH_REJECT")
    public ApiResponse<Map<String, Object>> batchReject(@RequestBody @Valid BatchAuditActionRequest request) {
        return ApiResponse.success(auditService.batchReject(request));
    }
}
