package com.zioinfo.kintex.catalog;

import com.zioinfo.kintex.auth.EventAccessGuard;
import com.zioinfo.kintex.auth.KintexPrincipal;
import com.zioinfo.kintex.catalog.dto.CalendarDayDto;
import com.zioinfo.kintex.catalog.dto.ExhibitionDto;
import com.zioinfo.kintex.catalog.dto.HallUtilizationDto;
import com.zioinfo.kintex.common.ApiResponse;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDate;
import java.util.List;

/**
 * 전시 일정 카탈로그 API (SCR-15).
 * 인증 필수(로그인 사용자면 누구나) — 워크스페이스(내 행사)와 달리 전 홀 10년치 카탈로그를 제공한다.
 * <p>배열 직접 반환({@code ApiResponse<List<ExhibitionDto>>}) — 프론트 {@code exhibitionApi.list()} 계약 정합.
 */
@RestController
@RequestMapping("/api/events")
public class EventCatalogController {

    /** 카탈로그 상한(과도 응답 방지) — V10 시드 1,098건을 단일 응답으로 커버. */
    private static final int MAX_LIMIT = 2000;

    private final EventCatalogService service;
    private final EventAccessGuard guard;

    public EventCatalogController(EventCatalogService service, EventAccessGuard guard) {
        this.service = service;
        this.guard = guard;
    }

    /** GET /api/events?year=&status=ongoing|upcoming|ended&category= — 필터 없으면 전체(시작일 내림차순). */
    @GetMapping
    public ApiResponse<List<ExhibitionDto>> list(@AuthenticationPrincipal KintexPrincipal principal,
                                                 @RequestParam(required = false) String year,
                                                 @RequestParam(required = false) String status,
                                                 @RequestParam(required = false) String category,
                                                 @RequestParam(required = false, defaultValue = "0") int page,
                                                 @RequestParam(required = false, defaultValue = "2000") int size) {
        guard.require(principal);
        int limit = Math.min(Math.max(size, 1), MAX_LIMIT);
        int offset = Math.max(page, 0) * limit;
        return ApiResponse.ok(service.list(year, status, category, limit, offset));
    }

    /**
     * GET /api/events/hall-utilization?year=&month= — 지정 월 홀 그룹 가동률(실 event 기반 집계).
     * year/month 미지정 시 현재 연/월. 인증 필수(카탈로그와 동일).
     */
    @GetMapping("/hall-utilization")
    public ApiResponse<List<HallUtilizationDto>> hallUtilization(@AuthenticationPrincipal KintexPrincipal principal,
                                                                 @RequestParam(required = false, defaultValue = "0") int year,
                                                                 @RequestParam(required = false, defaultValue = "0") int month) {
        guard.require(principal);
        int y = year > 0 ? year : LocalDate.now().getYear();
        int m = month > 0 ? month : LocalDate.now().getMonthValue();
        return ApiResponse.ok(service.hallUtilization(y, m));
    }

    /**
     * GET /api/events/calendar?year=&month= — 지정 월 캘린더 점유(행사 진행 날짜·건수).
     * year/month 미지정 시 현재 연/월. 인증 필수.
     */
    @GetMapping("/calendar")
    public ApiResponse<List<CalendarDayDto>> calendar(@AuthenticationPrincipal KintexPrincipal principal,
                                                      @RequestParam(required = false, defaultValue = "0") int year,
                                                      @RequestParam(required = false, defaultValue = "0") int month) {
        guard.require(principal);
        int y = year > 0 ? year : LocalDate.now().getYear();
        int m = month > 0 ? month : LocalDate.now().getMonthValue();
        return ApiResponse.ok(service.calendar(y, m));
    }
}
