package com.zioinfo.kintex.system.holiday;

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) + 캘린더 공개(인증) 조회.
 * <ul>
 *   <li>관리: {@code /api/admin/holidays} — 목록/추가/삭제/휴무토글, ADMIN 게이트({@link SystemAccessGuard}).</li>
 *   <li>공개(인증): {@code GET /api/holidays?from=&to=} — 기간 내 실제 휴무만(붉은색 표시용).</li>
 * </ul>
 * 데이터·시드(2024~2050)는 V41 소유 — 본 API는 그 위 조회·임시공휴일 관리만. 테넌트 스코프.
 */
@RestController
public class HolidayController {

    private final HolidayService service;
    private final SystemAccessGuard guard;

    public HolidayController(HolidayService service, SystemAccessGuard guard) {
        this.service = service;
        this.guard = guard;
    }

    /** 관리자 — 목록(year 또는 from/to, 휴무 off 포함). */
    @GetMapping("/api/admin/holidays")
    public ApiResponse<List<HolidayDto>> adminList(@AuthenticationPrincipal KintexPrincipal principal,
                                                   @RequestParam(value = "year", required = false) Integer year,
                                                   @RequestParam(value = "from", required = false) String from,
                                                   @RequestParam(value = "to", required = false) String to) {
        guard.requireAdmin(principal);
        return ApiResponse.ok(service.adminList(principal.tenantId(), year, from, to));
    }

    /** 관리자 — 데이터 존재 연도 목록(년 선택 드롭다운). */
    @GetMapping("/api/admin/holidays/years")
    public ApiResponse<List<Integer>> years(@AuthenticationPrincipal KintexPrincipal principal) {
        guard.requireAdmin(principal);
        return ApiResponse.ok(service.years(principal.tenantId()));
    }

    /** 관리자 — 임시공휴일 추가(PK 충돌 시 409). */
    @Audited(action = "HOLIDAY_CREATE", targetType = "holiday")
    @PostMapping("/api/admin/holidays")
    public ApiResponse<HolidayDto> create(@AuthenticationPrincipal KintexPrincipal principal,
                                          @Valid @RequestBody HolidayCreateRequest req) {
        guard.requireAdmin(principal);
        return ApiResponse.ok(service.create(principal.tenantId(), req));
    }

    /** 관리자 — 삭제. */
    @Audited(action = "HOLIDAY_DELETE", targetType = "holiday")
    @DeleteMapping("/api/admin/holidays/{ymd}")
    public ApiResponse<Void> delete(@AuthenticationPrincipal KintexPrincipal principal,
                                    @PathVariable String ymd) {
        guard.requireAdmin(principal);
        service.delete(principal.tenantId(), ymd);
        return ApiResponse.ok(null);
    }

    /** 관리자 — 휴무 여부 토글(임시휴무 on/off). */
    @Audited(action = "HOLIDAY_TOGGLE", targetType = "holiday")
    @PatchMapping("/api/admin/holidays/{ymd}")
    public ApiResponse<Void> toggle(@AuthenticationPrincipal KintexPrincipal principal,
                                    @PathVariable String ymd,
                                    @Valid @RequestBody HolidayToggleRequest req) {
        guard.requireAdmin(principal);
        service.toggle(principal.tenantId(), ymd, req.isHoliday());
        return ApiResponse.ok(null);
    }

    /** 공개(인증) — 캘린더 붉은색 표시용. 기간 내 실제 휴무만. */
    @GetMapping("/api/holidays")
    public ApiResponse<List<HolidayDto>> calendar(@AuthenticationPrincipal KintexPrincipal principal,
                                                  @RequestParam(value = "from", required = false) String from,
                                                  @RequestParam(value = "to", required = false) String to) {
        guard.require(principal);
        return ApiResponse.ok(service.publicRange(principal.tenantId(), from, to));
    }
}
