package com.zioinfo.kintex.auction;

import com.zioinfo.kintex.auction.dto.AuctionDtos.*;
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 org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * M15 공사/장치 옥션 API (SCR-26·27·29).
 * 인증 필수. 개설=발주자(주최자/참가업체/홀매니저), 응찰=등록 장치업체, 낙찰/전체비교=발주자.
 * <p>봉인 입찰·등록업체 게이트는 {@link AuctionService}가 서버에서 강제한다(컨트롤러는 인증만 확인).
 */
@RestController
@RequestMapping("/api/auctions")
public class AuctionController {

    private final AuctionService service;
    private final BoqService boqService;
    private final EventAccessGuard guard;

    public AuctionController(AuctionService service, BoqService boqService, EventAccessGuard guard) {
        this.service = service;
        this.boqService = boqService;
        this.guard = guard;
    }

    /** GET /api/auctions?eventId=&page=&size= — 옥션 목록(카드). */
    @GetMapping
    public ApiResponse<List<AuctionSummary>> list(@AuthenticationPrincipal KintexPrincipal principal,
                                                  @RequestParam(required = false) String eventId,
                                                  @RequestParam(defaultValue = "0") int page,
                                                  @RequestParam(defaultValue = "100") int size) {
        guard.require(principal);
        return ApiResponse.ok(service.list(eventId, page, size));
    }

    /** POST /api/auctions — 옥션 개설(발주자 권한, 서비스에서 검증). */
    @Audited(action = "AUCTION_CREATE", targetType = "auction")
    @PostMapping
    public ApiResponse<AuctionSummary> create(@AuthenticationPrincipal KintexPrincipal principal,
                                              @RequestBody CreateAuctionRequest req) {
        guard.require(principal);
        return ApiResponse.ok(service.create(principal, req));
    }

    /** GET /api/auctions/{id} — 상세·봉인 순위. 타사 금액·업체명은 서버가 마스킹. */
    @GetMapping("/{id}")
    public ApiResponse<AuctionDetail> detail(@AuthenticationPrincipal KintexPrincipal principal,
                                             @PathVariable String id) {
        guard.require(principal);
        return ApiResponse.ok(service.getDetail(id, principal));
    }

    /**
     * GET /api/auctions/{id}/boq — 물량서(BOQ) 자동산출(자료 패키지 첨부).
     * 부스 설계 데이터(M2/M4)에서 규칙 기반 집계. 옥션 상세 열람 권한과 동일(인증 + 옥션 존재).
     */
    @GetMapping("/{id}/boq")
    public ApiResponse<com.zioinfo.kintex.auction.dto.AuctionDtos.BoqResult> boq(
            @AuthenticationPrincipal KintexPrincipal principal,
            @PathVariable String id) {
        guard.require(principal);
        return ApiResponse.ok(boqService.boq(id));
    }

    /** POST /api/auctions/{id}/bids — 응찰(견적서 제출). 등록업체만·마감 후 409. */
    @Audited(action = "AUCTION_BID", targetType = "bid")
    @PostMapping("/{id}/bids")
    public ApiResponse<BidResult> bid(@AuthenticationPrincipal KintexPrincipal principal,
                                      @PathVariable String id,
                                      @RequestBody BidRequest req) {
        guard.require(principal);
        return ApiResponse.ok(service.placeBid(id, principal, req));
    }

    /** POST /api/auctions/{id}/close — 라운드 마감 처리(발주자만). 마감 후 봉인 해제·응찰 차단. */
    @Audited(action = "AUCTION_CLOSE", targetType = "auction")
    @PostMapping("/{id}/close")
    public ApiResponse<AuctionSummary> close(@AuthenticationPrincipal KintexPrincipal principal,
                                             @PathVariable String id) {
        guard.require(principal);
        return ApiResponse.ok(service.closeRound(id, principal));
    }

    /** POST /api/auctions/{id}/award — 낙찰(발주자·마감 후만). 사유 필수·감사 추적. */
    @Audited(action = "AUCTION_AWARD", targetType = "award")
    @PostMapping("/{id}/award")
    public ApiResponse<AwardResult> award(@AuthenticationPrincipal KintexPrincipal principal,
                                          @PathVariable String id,
                                          @RequestBody AwardRequest req) {
        guard.require(principal);
        return ApiResponse.ok(service.award(id, principal, req));
    }

    /** GET /api/auctions/{id}/award-view — 마감 후 발주자 전용 전체 견적 비교(봉인 해제). */
    @GetMapping("/{id}/award-view")
    public ApiResponse<AwardView> awardView(@AuthenticationPrincipal KintexPrincipal principal,
                                            @PathVariable String id) {
        guard.require(principal);
        return ApiResponse.ok(service.awardView(id, principal));
    }
}
