package com.zioinfo.kintex.session;

import com.zioinfo.kintex.auth.KintexPrincipal;
import com.zioinfo.kintex.common.ApiResponse;
import com.zioinfo.kintex.session.SessionDtos.MyRsvpDto;
import com.zioinfo.kintex.session.SessionDtos.RsvpResultDto;
import com.zioinfo.kintex.session.SessionDtos.SessionDto;
import com.zioinfo.kintex.visitor.VisitorAuth;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * F-B4 세션 정원 RSVP + F-C5 대기열 API.
 * <ul>
 *   <li>공개 조회 {@code GET /api/public/events/{eventId}/sessions} — 로그인 시 내 상태 포함.</li>
 *   <li>신청/취소/내신청 {@code /api/visitor/sessions/**} — 인증 필요.</li>
 * </ul>
 */
@RestController
public class SessionController {

    private final SessionService service;

    public SessionController(SessionService service) {
        this.service = service;
    }

    /** 공개 세션 목록 — Bearer 동봉 시 myStatus 포함(permitAll 경로라 익명 허용). */
    @GetMapping("/api/public/events/{eventId}/sessions")
    public ApiResponse<List<SessionDto>> publicSessions(@PathVariable String eventId,
                                                        @AuthenticationPrincipal KintexPrincipal principal) {
        String userId = principal == null ? null : principal.userId();
        return ApiResponse.ok(service.list(eventId, userId));
    }

    /** 인증 세션 목록(내 상태 포함). */
    @GetMapping("/api/visitor/events/{eventId}/sessions")
    public ApiResponse<List<SessionDto>> mySessions(@PathVariable String eventId,
                                                    @AuthenticationPrincipal KintexPrincipal principal) {
        return ApiResponse.ok(service.list(eventId, VisitorAuth.requireUserId(principal)));
    }

    /** 내 RSVP 목록. */
    @GetMapping("/api/visitor/sessions/mine")
    public ApiResponse<List<MyRsvpDto>> mine(@AuthenticationPrincipal KintexPrincipal principal) {
        return ApiResponse.ok(service.mine(VisitorAuth.requireUserId(principal)));
    }

    /** 세션 신청(확정/대기). */
    @PostMapping("/api/visitor/sessions/{sessionId}/rsvp")
    public ApiResponse<RsvpResultDto> rsvp(@AuthenticationPrincipal KintexPrincipal principal,
                                           @PathVariable String sessionId) {
        return ApiResponse.ok(service.rsvp(VisitorAuth.requireUserId(principal), sessionId));
    }

    /** 세션 신청 취소(대기 승격 트리거). */
    @DeleteMapping("/api/visitor/sessions/{sessionId}/rsvp")
    public ApiResponse<RsvpResultDto> cancel(@AuthenticationPrincipal KintexPrincipal principal,
                                             @PathVariable String sessionId) {
        return ApiResponse.ok(service.cancel(VisitorAuth.requireUserId(principal), sessionId));
    }
}
