package com.zioinfo.kintex.work.approval;

import com.zioinfo.kintex.auth.EventAccessGuard;
import com.zioinfo.kintex.auth.KintexPrincipal;
import com.zioinfo.kintex.common.ApiResponse;
import com.zioinfo.kintex.common.PageResponse;
import com.zioinfo.kintex.common.audit.Audited;
import com.zioinfo.kintex.work.approval.dto.ApprovalDtos.ApprovalActionRequest;
import com.zioinfo.kintex.work.approval.dto.ApprovalDtos.ApprovalDetailDto;
import com.zioinfo.kintex.work.approval.dto.ApprovalDtos.ApprovalListDto;
import com.zioinfo.kintex.work.approval.dto.ApprovalDtos.ApprovalSaveRequest;
import jakarta.validation.Valid;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

/**
 * §5B 공통 전자결재 API (/api/work/approvals). F028.
 * 조회=인증, 승인/반려=현재 단계 결재선 당사자(서비스에서 403), 기안/상신/회수/재상신=기안자.
 */
@RestController
@RequestMapping("/api/work/approvals")
public class ApprovalController {

    private final ApprovalService service;
    private final EventAccessGuard authGuard;

    public ApprovalController(ApprovalService service, EventAccessGuard authGuard) {
        this.service = service;
        this.authGuard = authGuard;
    }

    /** 결재함 목록. box=DRAFT|DRAFTED|PENDING|DONE. */
    @GetMapping
    public ApiResponse<PageResponse<ApprovalListDto>> list(@AuthenticationPrincipal KintexPrincipal principal,
                                                           @RequestParam(defaultValue = "DRAFTED") String box,
                                                           @RequestParam(required = false) String keyword,
                                                           @RequestParam(defaultValue = "0") int page,
                                                           @RequestParam(defaultValue = "20") int size) {
        authGuard.require(principal);
        return ApiResponse.ok(service.list(principal, box, keyword, page, size));
    }

    /** 문서 상세(결재선·이력·액션 플래그). */
    @GetMapping("/{id}")
    public ApiResponse<ApprovalDetailDto> get(@AuthenticationPrincipal KintexPrincipal principal,
                                              @PathVariable String id) {
        authGuard.require(principal);
        return ApiResponse.ok(service.get(principal, id));
    }

    /** 기안(DRAFT 생성). */
    @Audited(action = "APPROVAL_CREATE", targetType = "approval")
    @PostMapping
    public ApiResponse<ApprovalDetailDto> create(@AuthenticationPrincipal KintexPrincipal principal,
                                                 @Valid @RequestBody ApprovalSaveRequest req) {
        authGuard.require(principal);
        return ApiResponse.ok(service.create(principal, req));
    }

    /** 상신(DRAFT→SUBMITTED). */
    @Audited(action = "APPROVAL_SUBMIT", targetType = "approval")
    @PostMapping("/{id}/submit")
    public ApiResponse<ApprovalDetailDto> submit(@AuthenticationPrincipal KintexPrincipal principal,
                                                 @PathVariable String id) {
        authGuard.require(principal);
        return ApiResponse.ok(service.submit(principal, id));
    }

    /** 승인(현재 단계 결재자). */
    @Audited(action = "APPROVAL_APPROVE", targetType = "approval")
    @PostMapping("/{id}/approve")
    public ApiResponse<ApprovalDetailDto> approve(@AuthenticationPrincipal KintexPrincipal principal,
                                                  @PathVariable String id,
                                                  @RequestBody(required = false) ApprovalActionRequest req) {
        authGuard.require(principal);
        return ApiResponse.ok(service.approve(principal, id, req));
    }

    /** 반려(사유 필수). */
    @Audited(action = "APPROVAL_REJECT", targetType = "approval")
    @PostMapping("/{id}/reject")
    public ApiResponse<ApprovalDetailDto> reject(@AuthenticationPrincipal KintexPrincipal principal,
                                                 @PathVariable String id,
                                                 @RequestBody(required = false) ApprovalActionRequest req) {
        authGuard.require(principal);
        return ApiResponse.ok(service.reject(principal, id, req));
    }

    /** 재상신(REJECTED→SUBMITTED, version+1). */
    @Audited(action = "APPROVAL_RESUBMIT", targetType = "approval")
    @PostMapping("/{id}/resubmit")
    public ApiResponse<ApprovalDetailDto> resubmit(@AuthenticationPrincipal KintexPrincipal principal,
                                                   @PathVariable String id,
                                                   @RequestBody(required = false) ApprovalSaveRequest req) {
        authGuard.require(principal);
        return ApiResponse.ok(service.resubmit(principal, id, req));
    }

    /** 회수(기안자 취소). */
    @Audited(action = "APPROVAL_CANCEL", targetType = "approval")
    @PostMapping("/{id}/cancel")
    public ApiResponse<ApprovalDetailDto> cancel(@AuthenticationPrincipal KintexPrincipal principal,
                                                 @PathVariable String id) {
        authGuard.require(principal);
        return ApiResponse.ok(service.cancel(principal, id));
    }
}
