package com.zioinfo.kintex.system.commoncode;

import com.zioinfo.kintex.auth.EventAccessGuard;
import com.zioinfo.kintex.auth.KintexPrincipal;
import com.zioinfo.kintex.common.ApiResponse;
import com.zioinfo.kintex.common.audit.Audited;
import com.zioinfo.kintex.system.SystemAccessGuard;
import jakarta.validation.Valid;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 공통코드 API. 조회(드롭다운)는 인증 사용자 공개, 관리(CRUD)는 ADMIN.
 *  - GET /api/common/code-groups, /api/common/codes/{grpCode}  (인증)
 *  - /api/admin/codes/**  (ADMIN)
 */
@RestController
public class CommonCodeController {

    private final CommonCodeService service;
    private final EventAccessGuard authGuard;
    private final SystemAccessGuard adminGuard;

    public CommonCodeController(CommonCodeService service, EventAccessGuard authGuard,
                                SystemAccessGuard adminGuard) {
        this.service = service;
        this.authGuard = authGuard;
        this.adminGuard = adminGuard;
    }

    @GetMapping("/api/common/code-groups")
    public ApiResponse<List<CodeGroupDto>> groups(@AuthenticationPrincipal KintexPrincipal principal) {
        authGuard.require(principal);
        return ApiResponse.ok(service.groups());
    }

    @GetMapping("/api/common/codes/{grpCode}")
    public ApiResponse<List<CodeDto>> codes(@AuthenticationPrincipal KintexPrincipal principal,
                                            @PathVariable String grpCode) {
        authGuard.require(principal);
        return ApiResponse.ok(service.codes(grpCode));
    }

    @Audited(action = "CODE_GROUP_SAVE", targetType = "common_code_group")
    @PostMapping("/api/admin/codes/groups")
    public ApiResponse<Void> saveGroup(@AuthenticationPrincipal KintexPrincipal principal,
                                       @Valid @RequestBody CodeGroupDto group) {
        adminGuard.requireAdmin(principal);
        service.saveGroup(group);
        return ApiResponse.ok(null);
    }

    @Audited(action = "CODE_GROUP_DELETE", targetType = "common_code_group")
    @DeleteMapping("/api/admin/codes/groups/{grpCode}")
    public ApiResponse<Void> deleteGroup(@AuthenticationPrincipal KintexPrincipal principal,
                                         @PathVariable String grpCode) {
        adminGuard.requireAdmin(principal);
        service.deleteGroup(grpCode);
        return ApiResponse.ok(null);
    }

    @Audited(action = "CODE_SAVE", targetType = "common_code")
    @PostMapping("/api/admin/codes")
    public ApiResponse<Void> saveCode(@AuthenticationPrincipal KintexPrincipal principal,
                                      @Valid @RequestBody CodeDto code) {
        adminGuard.requireAdmin(principal);
        service.saveCode(code);
        return ApiResponse.ok(null);
    }

    @Audited(action = "CODE_DELETE", targetType = "common_code")
    @DeleteMapping("/api/admin/codes/{grpCode}/{code}")
    public ApiResponse<Void> deleteCode(@AuthenticationPrincipal KintexPrincipal principal,
                                        @PathVariable String grpCode, @PathVariable String code) {
        adminGuard.requireAdmin(principal);
        service.deleteCode(grpCode, code);
        return ApiResponse.ok(null);
    }
}
