package com.kt.event.eventservice.presentation.controller;

import com.kt.event.common.dto.ApiResponse;
import com.kt.event.common.dto.PageResponse;
import com.kt.event.common.security.UserPrincipal;
import com.kt.event.eventservice.application.dto.request.SelectObjectiveRequest;
import com.kt.event.eventservice.application.dto.response.EventCreatedResponse;
import com.kt.event.eventservice.application.dto.response.EventDetailResponse;
import com.kt.event.eventservice.application.service.EventService;
import com.kt.event.eventservice.domain.enums.EventStatus;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;

/**
 * 이벤트 컨트롤러
 *
 * 이벤트 전체 생명주기 관리 API를 제공합니다.
 *
 * @author Event Service Team
 * @version 1.0.0
 * @since 2025-10-23
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/events")
@RequiredArgsConstructor
@Tag(name = "Event", description = "이벤트 관리 API")
public class EventController {

    private final EventService eventService;

    /**
     * 이벤트 목적 선택 (Step 1: 이벤트 생성)
     *
     * @param request 목적 선택 요청
     * @param userPrincipal 인증된 사용자 정보
     * @return 생성된 이벤트 응답
     */
    @PostMapping("/objectives")
    @Operation(summary = "이벤트 목적 선택", description = "이벤트 생성의 첫 단계로 목적을 선택합니다.")
    public ResponseEntity<ApiResponse<EventCreatedResponse>> selectObjective(
            @Valid @RequestBody SelectObjectiveRequest request,
            @AuthenticationPrincipal UserPrincipal userPrincipal) {

        log.info("이벤트 목적 선택 API 호출 - userId: {}, objective: {}",
                 userPrincipal.getUserId(), request.getObjective());

        EventCreatedResponse response = eventService.createEvent(
            userPrincipal.getUserId(),
            userPrincipal.getStoreId(),
            request
        );

        return ResponseEntity.status(HttpStatus.CREATED)
            .body(ApiResponse.success(response));
    }

    /**
     * 이벤트 목록 조회
     *
     * @param status 상태 필터
     * @param search 검색어
     * @param objective 목적 필터
     * @param page 페이지 번호
     * @param size 페이지 크기
     * @param sort 정렬 기준
     * @param order 정렬 순서
     * @param userPrincipal 인증된 사용자 정보
     * @return 이벤트 목록 응답
     */
    @GetMapping
    @Operation(summary = "이벤트 목록 조회", description = "사용자의 이벤트 목록을 조회합니다.")
    public ResponseEntity<ApiResponse<PageResponse<EventDetailResponse>>> getEvents(
            @RequestParam(required = false) EventStatus status,
            @RequestParam(required = false) String search,
            @RequestParam(required = false) String objective,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size,
            @RequestParam(defaultValue = "createdAt") String sort,
            @RequestParam(defaultValue = "desc") String order,
            @AuthenticationPrincipal UserPrincipal userPrincipal) {

        log.info("이벤트 목록 조회 API 호출 - userId: {}", userPrincipal.getUserId());

        // Pageable 생성
        Sort.Direction direction = "asc".equalsIgnoreCase(order) ? Sort.Direction.ASC : Sort.Direction.DESC;
        Pageable pageable = PageRequest.of(page, size, Sort.by(direction, sort));

        Page<EventDetailResponse> events = eventService.getEvents(
            userPrincipal.getUserId(),
            status,
            search,
            objective,
            pageable
        );

        PageResponse<EventDetailResponse> pageResponse = PageResponse.<EventDetailResponse>builder()
            .content(events.getContent())
            .page(events.getNumber())
            .size(events.getSize())
            .totalElements(events.getTotalElements())
            .totalPages(events.getTotalPages())
            .first(events.isFirst())
            .last(events.isLast())
            .build();

        return ResponseEntity.ok(ApiResponse.success(pageResponse));
    }

    /**
     * 이벤트 상세 조회
     *
     * @param eventId 이벤트 ID
     * @param userPrincipal 인증된 사용자 정보
     * @return 이벤트 상세 응답
     */
    @GetMapping("/{eventId}")
    @Operation(summary = "이벤트 상세 조회", description = "특정 이벤트의 상세 정보를 조회합니다.")
    public ResponseEntity<ApiResponse<EventDetailResponse>> getEvent(
            @PathVariable UUID eventId,
            @AuthenticationPrincipal UserPrincipal userPrincipal) {

        log.info("이벤트 상세 조회 API 호출 - userId: {}, eventId: {}",
                 userPrincipal.getUserId(), eventId);

        EventDetailResponse response = eventService.getEvent(userPrincipal.getUserId(), eventId);

        return ResponseEntity.ok(ApiResponse.success(response));
    }

    /**
     * 이벤트 삭제
     *
     * @param eventId 이벤트 ID
     * @param userPrincipal 인증된 사용자 정보
     * @return 성공 응답
     */
    @DeleteMapping("/{eventId}")
    @Operation(summary = "이벤트 삭제", description = "이벤트를 삭제합니다. DRAFT 상태만 삭제 가능합니다.")
    public ResponseEntity<ApiResponse<Void>> deleteEvent(
            @PathVariable UUID eventId,
            @AuthenticationPrincipal UserPrincipal userPrincipal) {

        log.info("이벤트 삭제 API 호출 - userId: {}, eventId: {}",
                 userPrincipal.getUserId(), eventId);

        eventService.deleteEvent(userPrincipal.getUserId(), eventId);

        return ResponseEntity.ok(ApiResponse.success(null));
    }

    /**
     * 이벤트 배포
     *
     * @param eventId 이벤트 ID
     * @param userPrincipal 인증된 사용자 정보
     * @return 성공 응답
     */
    @PostMapping("/{eventId}/publish")
    @Operation(summary = "이벤트 배포", description = "이벤트를 배포합니다. DRAFT → PUBLISHED 상태 변경.")
    public ResponseEntity<ApiResponse<Void>> publishEvent(
            @PathVariable UUID eventId,
            @AuthenticationPrincipal UserPrincipal userPrincipal) {

        log.info("이벤트 배포 API 호출 - userId: {}, eventId: {}",
                 userPrincipal.getUserId(), eventId);

        eventService.publishEvent(userPrincipal.getUserId(), eventId);

        return ResponseEntity.ok(ApiResponse.success(null));
    }

    /**
     * 이벤트 종료
     *
     * @param eventId 이벤트 ID
     * @param userPrincipal 인증된 사용자 정보
     * @return 성공 응답
     */
    @PostMapping("/{eventId}/end")
    @Operation(summary = "이벤트 종료", description = "이벤트를 종료합니다. PUBLISHED → ENDED 상태 변경.")
    public ResponseEntity<ApiResponse<Void>> endEvent(
            @PathVariable UUID eventId,
            @AuthenticationPrincipal UserPrincipal userPrincipal) {

        log.info("이벤트 종료 API 호출 - userId: {}, eventId: {}",
                 userPrincipal.getUserId(), eventId);

        eventService.endEvent(userPrincipal.getUserId(), eventId);

        return ResponseEntity.ok(ApiResponse.success(null));
    }
}
