package com.ga.api.controller.regulatory;

import com.ga.api.service.regulatory.RegulatoryLimitChecker;
import com.ga.api.service.regulatory.RegulatoryLimitService;
import com.ga.api.service.regulatory.ViolationResult;
import com.ga.common.annotation.DataChangeLog;
import com.ga.common.annotation.RequirePermission;
import com.ga.common.model.ApiResponse;
import com.ga.common.model.PageResponse;
import com.ga.core.vo.regulatory.RegulatoryLimitResp;
import com.ga.core.vo.regulatory.RegulatoryLimitSaveReq;
import com.ga.core.vo.regulatory.RegulatoryLimitSearchParam;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;

@Tag(name = "규제 한도 관리")
@RestController
@RequestMapping("/api/regulatory-limits")
@RequiredArgsConstructor
public class RegulatoryLimitController {

    private final RegulatoryLimitService limitService;
    private final RegulatoryLimitChecker limitChecker;

    @GetMapping
    @RequirePermission(menu = "REGULATORY_LIMIT", perm = "READ")
    public ApiResponse<PageResponse<RegulatoryLimitResp>> list(RegulatoryLimitSearchParam param) {
        return ApiResponse.ok(limitService.list(param));
    }

    @GetMapping("/{limitId}")
    @RequirePermission(menu = "REGULATORY_LIMIT", perm = "READ")
    public ApiResponse<RegulatoryLimitResp> detail(@PathVariable Long limitId) {
        return ApiResponse.ok(limitService.detail(limitId));
    }

    @PostMapping
    @RequirePermission(menu = "REGULATORY_LIMIT", perm = "CREATE")
    @DataChangeLog(menu = "REGULATORY_LIMIT", table = "regulatory_limit")
    public ApiResponse<Void> create(@Valid @RequestBody RegulatoryLimitSaveReq req) {
        limitService.create(req);
        return ApiResponse.ok();
    }

    @PutMapping("/{limitId}")
    @RequirePermission(menu = "REGULATORY_LIMIT", perm = "UPDATE")
    @DataChangeLog(menu = "REGULATORY_LIMIT", table = "regulatory_limit")
    public ApiResponse<Void> update(@PathVariable Long limitId,
                                    @Valid @RequestBody RegulatoryLimitSaveReq req) {
        limitService.update(limitId, req);
        return ApiResponse.ok();
    }

    @PutMapping("/{limitId}/deactivate")
    @RequirePermission(menu = "REGULATORY_LIMIT", perm = "UPDATE")
    @DataChangeLog(menu = "REGULATORY_LIMIT", table = "regulatory_limit")
    public ApiResponse<Void> deactivate(@PathVariable Long limitId) {
        limitService.deactivate(limitId);
        return ApiResponse.ok();
    }

    @PutMapping("/{limitId}/activate")
    @RequirePermission(menu = "REGULATORY_LIMIT", perm = "UPDATE")
    @DataChangeLog(menu = "REGULATORY_LIMIT", table = "regulatory_limit")
    public ApiResponse<Void> activate(@PathVariable Long limitId) {
        limitService.activate(limitId);
        return ApiResponse.ok();
    }

    @PostMapping("/check-contract")
    @RequirePermission(menu = "REGULATORY_LIMIT", perm = "READ")
    public ApiResponse<ViolationResult> checkContract(@Valid @RequestBody ContractLimitCheckReq req) {
        LocalDate baseDate = req.getBaseDate() != null ? req.getBaseDate() : LocalDate.now();
        ViolationResult result;
        if ("FIRST_YEAR_RATIO".equals(req.getLimitType())) {
            result = limitChecker.checkFirstYear(req.getContractId(), req.getAdditionalAmount(), baseDate);
        } else {
            result = limitChecker.checkContractTotal(req.getContractId(), req.getAdditionalAmount(), baseDate);
        }
        return ApiResponse.ok(result);
    }
}
