package com.zioinfo.kintex.logistics;

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.logistics.dto.LogisticsExtDtos.*;
import jakarta.validation.Valid;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

/**
 * M8 물류 확장 API — F041 장비 신청 · F042 렌탈 주문 · F043 선입고 트래킹 (SCR /logistics 탭 확장).
 * <ul>
 *   <li>조회(보드): 행사 접근 권한. 신청·주문·선입고 등록: 행사 멤버(참가업체 포함) + {@link Audited}.</li>
 *   <li>승인·주문 확정·상태 전이: 매니저 이상(주최자/홀매니저) + {@link Audited}.</li>
 * </ul>
 * 금액은 서버 계산 권위(카탈로그 단가 정본). 상태 전이 값은 서버 화이트리스트 검증(부적합 400, 미존재 404).
 */
@RestController
@RequestMapping("/api/events/{eventId}/logistics")
public class LogisticsExtController {

    private final LogisticsExtService service;
    private final EventAccessGuard guard;

    public LogisticsExtController(LogisticsExtService service, EventAccessGuard guard) {
        this.service = service;
        this.guard = guard;
    }

    /** GET /ext — 물류 확장 보드(카탈로그 + 신청/주문/선입고 목록 + canManage). */
    @GetMapping("/ext")
    public ApiResponse<LogisticsExtBoard> board(@AuthenticationPrincipal KintexPrincipal principal,
                                                @PathVariable String eventId) {
        guard.requireEventAccess(principal, eventId);
        return ApiResponse.ok(service.board(eventId, principal));
    }

    // ── ① 장비 신청 ──────────────────────────────────────────────────────────
    /** POST /equipment-requests — 장비 신청 생성(멤버). 금액 서버 계산. */
    @Audited(action = "LOGI_EQUIP_REQUEST", targetType = "logistics_equipment_request")
    @PostMapping("/equipment-requests")
    public ApiResponse<EquipmentRequestView> requestEquipment(@AuthenticationPrincipal KintexPrincipal principal,
                                                              @PathVariable String eventId,
                                                              @Valid @RequestBody EquipmentRequestBody body) {
        guard.requireEventAccess(principal, eventId);
        return ApiResponse.ok(service.createEquipmentRequest(eventId, body, principal));
    }

    /** POST /equipment-requests/{id}/status — 승인/반려/처리완료(매니저 이상). */
    @Audited(action = "LOGI_EQUIP_DECIDE", targetType = "logistics_equipment_request")
    @PostMapping("/equipment-requests/{id}/status")
    public ApiResponse<EquipmentRequestView> decideEquipment(@AuthenticationPrincipal KintexPrincipal principal,
                                                             @PathVariable String eventId,
                                                             @PathVariable String id,
                                                             @Valid @RequestBody StatusDecisionBody body) {
        guard.requireEventAccess(principal, eventId);
        return ApiResponse.ok(service.decideEquipmentRequest(eventId, id, body, principal));
    }

    // ── ② 렌탈 주문 ──────────────────────────────────────────────────────────
    /** POST /rental-orders — 렌탈 주문 생성(멤버). 기간·금액 서버 산출. */
    @Audited(action = "LOGI_RENTAL_ORDER", targetType = "logistics_rental_order")
    @PostMapping("/rental-orders")
    public ApiResponse<RentalOrderView> orderRental(@AuthenticationPrincipal KintexPrincipal principal,
                                                    @PathVariable String eventId,
                                                    @Valid @RequestBody RentalOrderBody body) {
        guard.requireEventAccess(principal, eventId);
        return ApiResponse.ok(service.createRentalOrder(eventId, body, principal));
    }

    /** POST /rental-orders/{id}/status — 확정/취소/납품(매니저 이상). */
    @Audited(action = "LOGI_RENTAL_DECIDE", targetType = "logistics_rental_order")
    @PostMapping("/rental-orders/{id}/status")
    public ApiResponse<RentalOrderView> decideRental(@AuthenticationPrincipal KintexPrincipal principal,
                                                     @PathVariable String eventId,
                                                     @PathVariable String id,
                                                     @Valid @RequestBody StatusDecisionBody body) {
        guard.requireEventAccess(principal, eventId);
        return ApiResponse.ok(service.decideRentalOrder(eventId, id, body, principal));
    }

    // ── ③ 선입고 트래킹 ──────────────────────────────────────────────────────
    /** POST /inbound — 운송장 등록(멤버). */
    @Audited(action = "LOGI_INBOUND_REGISTER", targetType = "logistics_inbound")
    @PostMapping("/inbound")
    public ApiResponse<InboundView> registerInbound(@AuthenticationPrincipal KintexPrincipal principal,
                                                    @PathVariable String eventId,
                                                    @Valid @RequestBody InboundBody body) {
        guard.requireEventAccess(principal, eventId);
        return ApiResponse.ok(service.registerInbound(eventId, body, principal));
    }

    /** POST /inbound/{id}/status — 입고예정/창고도착/부스전달 전이(매니저 이상). */
    @Audited(action = "LOGI_INBOUND_ADVANCE", targetType = "logistics_inbound")
    @PostMapping("/inbound/{id}/status")
    public ApiResponse<InboundView> advanceInbound(@AuthenticationPrincipal KintexPrincipal principal,
                                                   @PathVariable String eventId,
                                                   @PathVariable String id,
                                                   @Valid @RequestBody InboundStatusBody body) {
        guard.requireEventAccess(principal, eventId);
        return ApiResponse.ok(service.advanceInbound(eventId, id, body, principal));
    }
}
