package com.kt.event.content.infra.web.controller;

import com.kt.event.content.biz.domain.ImageStyle;
import com.kt.event.content.biz.domain.Platform;
import com.kt.event.content.biz.dto.ContentCommand;
import com.kt.event.content.biz.dto.ContentInfo;
import com.kt.event.content.biz.dto.ImageInfo;
import com.kt.event.content.biz.dto.JobInfo;
import com.kt.event.content.biz.usecase.in.DeleteImageUseCase;
import com.kt.event.content.biz.usecase.in.GenerateImagesUseCase;
import com.kt.event.content.biz.usecase.in.GetEventContentUseCase;
import com.kt.event.content.biz.usecase.in.GetImageDetailUseCase;
import com.kt.event.content.biz.usecase.in.GetImageListUseCase;
import com.kt.event.content.biz.usecase.in.GetJobStatusUseCase;
import com.kt.event.content.biz.usecase.in.RegenerateImageUseCase;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * Content Service REST API Controller
 *
 * API 명세: content-service-api.yaml
 * - 이미지 생성 요청 및 Job 상태 조회
 * - 생성된 콘텐츠 조회 및 관리
 * - 이미지 재생성 및 삭제
 */
@Slf4j
@RestController
@RequestMapping
@RequiredArgsConstructor
public class ContentController {

    private final GenerateImagesUseCase generateImagesUseCase;
    private final GetJobStatusUseCase getJobStatusUseCase;
    private final GetEventContentUseCase getEventContentUseCase;
    private final GetImageListUseCase getImageListUseCase;
    private final GetImageDetailUseCase getImageDetailUseCase;
    private final RegenerateImageUseCase regenerateImageUseCase;
    private final DeleteImageUseCase deleteImageUseCase;

    /**
     * POST /api/v1/content/images/generate
     * SNS 이미지 생성 요청 (비동기)
     *
     * @param command 이미지 생성 요청 정보
     * @return 202 ACCEPTED - Job ID 반환
     */
    @PostMapping("/images/generate")
    public ResponseEntity<JobInfo> generateImages(@RequestBody ContentCommand.GenerateImages command) {
        log.info("이미지 생성 요청: eventId={}, styles={}, platforms={}",
                command.getEventId(), command.getStyles(), command.getPlatforms());

        JobInfo jobInfo = generateImagesUseCase.execute(command);

        return ResponseEntity.status(HttpStatus.ACCEPTED).body(jobInfo);
    }

    /**
     * GET /api/v1/content/images/jobs/{jobId}
     * 이미지 생성 작업 상태 조회 (폴링)
     *
     * @param jobId Job ID
     * @return 200 OK - Job 상태 정보
     */
    @GetMapping("/images/jobs/{jobId}")
    public ResponseEntity<JobInfo> getJobStatus(@PathVariable String jobId) {
        log.info("Job 상태 조회: jobId={}", jobId);

        JobInfo jobInfo = getJobStatusUseCase.execute(jobId);

        return ResponseEntity.ok(jobInfo);
    }

    /**
     * GET /api/v1/content/events/{eventId}
     * 이벤트의 생성된 콘텐츠 조회
     *
     * @param eventId 이벤트 ID
     * @return 200 OK - 콘텐츠 정보 (이미지 목록 포함)
     */
    @GetMapping("/events/{eventId}")
    public ResponseEntity<ContentInfo> getContentByEventId(@PathVariable String eventId) {
        log.info("이벤트 콘텐츠 조회: eventId={}", eventId);

        ContentInfo contentInfo = getEventContentUseCase.execute(eventId);

        return ResponseEntity.ok(contentInfo);
    }

    /**
     * GET /api/v1/content/events/{eventId}/images
     * 이벤트의 이미지 목록 조회 (필터링)
     *
     * @param eventId 이벤트 ID
     * @param style 이미지 스타일 필터 (선택)
     * @param platform 플랫폼 필터 (선택)
     * @return 200 OK - 이미지 목록
     */
    @GetMapping("/events/{eventId}/images")
    public ResponseEntity<List<ImageInfo>> getImages(
            @PathVariable String eventId,
            @RequestParam(required = false) String style,
            @RequestParam(required = false) String platform) {
        log.info("이미지 목록 조회: eventId={}, style={}, platform={}", eventId, style, platform);

        // String -> Enum 변환
        ImageStyle imageStyle = style != null ? ImageStyle.valueOf(style.toUpperCase()) : null;
        Platform imagePlatform = platform != null ? Platform.valueOf(platform.toUpperCase()) : null;

        List<ImageInfo> images = getImageListUseCase.execute(eventId, imageStyle, imagePlatform);

        return ResponseEntity.ok(images);
    }

    /**
     * GET /api/v1/content/images/{imageId}
     * 특정 이미지 상세 조회
     *
     * @param imageId 이미지 ID
     * @return 200 OK - 이미지 상세 정보
     */
    @GetMapping("/images/{imageId:[0-9]+}")
    public ResponseEntity<ImageInfo> getImageById(@PathVariable Long imageId) {
        log.info("이미지 상세 조회: imageId={}", imageId);

        ImageInfo imageInfo = getImageDetailUseCase.execute(imageId);

        return ResponseEntity.ok(imageInfo);
    }

    /**
     * DELETE /api/v1/content/images/{imageId}
     * 생성된 이미지 삭제
     *
     * @param imageId 이미지 ID
     * @return 204 NO CONTENT
     */
    @DeleteMapping("/images/{imageId:[0-9]+}")
    public ResponseEntity<Void> deleteImage(@PathVariable Long imageId) {
        log.info("이미지 삭제 요청: imageId={}", imageId);

        deleteImageUseCase.execute(imageId);

        return ResponseEntity.noContent().build();
    }

    /**
     * POST /api/v1/content/images/{imageId}/regenerate
     * 이미지 재생성 요청
     *
     * @param imageId 이미지 ID
     * @param requestBody 재생성 요청 정보 (선택)
     * @return 202 ACCEPTED - Job ID 반환
     */
    @PostMapping("/images/{imageId:[0-9]+}/regenerate")
    public ResponseEntity<JobInfo> regenerateImage(
            @PathVariable Long imageId,
            @RequestBody(required = false) ContentCommand.RegenerateImage requestBody) {
        log.info("이미지 재생성 요청: imageId={}", imageId);

        // imageId를 포함한 command 생성
        ContentCommand.RegenerateImage command = ContentCommand.RegenerateImage.builder()
                .imageId(imageId)
                .newPrompt(requestBody != null ? requestBody.getNewPrompt() : null)
                .build();

        JobInfo jobInfo = regenerateImageUseCase.execute(command);

        return ResponseEntity.status(HttpStatus.ACCEPTED).body(jobInfo);
    }
}
