package com.unicorn.hgzero.stt.controller;

import com.unicorn.hgzero.common.response.ApiResponse;
import com.unicorn.hgzero.stt.dto.TranscriptionDto;
import com.unicorn.hgzero.stt.dto.TranscriptSegmentDto;
import com.unicorn.hgzero.stt.service.TranscriptionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;

/**
 * 음성 변환 컨트롤러
 * 실시간 및 배치 음성-텍스트 변환 기능을 제공
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/stt/transcription")
@RequiredArgsConstructor
@Validated
@Tag(name = "음성 변환", description = "음성-텍스트 변환 API")
public class TranscriptionController {
    
    private final TranscriptionService transcriptionService;
    
    @Operation(
        summary = "실시간 음성 변환",
        description = "실시간 음성 스트림을 텍스트로 변환합니다."
    )
    @ApiResponses(value = {
        @io.swagger.v3.oas.annotations.responses.ApiResponse(
            responseCode = "200", 
            description = "변환 성공",
            content = @Content(schema = @Schema(implementation = TranscriptSegmentDto.Response.class))
        ),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(
            responseCode = "400", 
            description = "잘못된 요청"
        ),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(
            responseCode = "404", 
            description = "녹음 세션을 찾을 수 없음"
        )
    })
    @PostMapping("/stream")
    public ResponseEntity<ApiResponse<TranscriptSegmentDto.Response>> processAudioStream(
            @Valid @RequestBody TranscriptionDto.StreamRequest request) {
        log.info("실시간 음성 변환 요청 - recordingId: {}, timestamp: {}", 
                request.getRecordingId(), request.getTimestamp());
        
        TranscriptSegmentDto.Response response = transcriptionService.processAudioStream(request);
        
        return ResponseEntity.ok(ApiResponse.success(response));
    }
    
    @Operation(
        summary = "배치 음성 변환",
        description = "오디오 파일을 업로드하여 배치 변환 작업을 시작합니다."
    )
    @ApiResponses(value = {
        @io.swagger.v3.oas.annotations.responses.ApiResponse(
            responseCode = "200", 
            description = "배치 작업 시작 성공",
            content = @Content(schema = @Schema(implementation = TranscriptionDto.BatchResponse.class))
        ),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(
            responseCode = "400", 
            description = "잘못된 파일 형식 또는 요청"
        ),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(
            responseCode = "404", 
            description = "녹음 세션을 찾을 수 없음"
        )
    })
    @PostMapping(value = "/batch", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<ApiResponse<TranscriptionDto.BatchResponse>> transcribeAudioBatch(
            @Parameter(description = "배치 변환 요청 정보")
            @Valid @RequestPart("request") TranscriptionDto.BatchRequest request,
            @Parameter(description = "변환할 오디오 파일")
            @RequestPart("audioFile") MultipartFile audioFile) {
        log.info("배치 음성 변환 요청 - recordingId: {}, fileSize: {}", 
                request.getRecordingId(), audioFile.getSize());
        
        TranscriptionDto.BatchResponse response = transcriptionService.transcribeAudioBatch(request, audioFile);
        
        return ResponseEntity.ok(ApiResponse.success(response));
    }
    
    @Operation(
        summary = "배치 변환 완료 콜백",
        description = "Azure 배치 변환 완료 시 호출되는 콜백 엔드포인트입니다."
    )
    @ApiResponses(value = {
        @io.swagger.v3.oas.annotations.responses.ApiResponse(
            responseCode = "200", 
            description = "콜백 처리 성공",
            content = @Content(schema = @Schema(implementation = TranscriptionDto.CompleteResponse.class))
        ),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(
            responseCode = "400", 
            description = "잘못된 콜백 데이터"
        )
    })
    @PostMapping("/batch/callback")
    public ResponseEntity<ApiResponse<TranscriptionDto.CompleteResponse>> processBatchCallback(
            @Valid @RequestBody TranscriptionDto.BatchCallbackRequest request) {
        log.info("배치 변환 콜백 처리 - jobId: {}, status: {}", 
                request.getJobId(), request.getStatus());
        
        TranscriptionDto.CompleteResponse response = transcriptionService.processBatchCallback(request);
        
        return ResponseEntity.ok(ApiResponse.success(response));
    }
    
    @Operation(
        summary = "변환 결과 조회",
        description = "녹음의 전체 변환 결과를 조회합니다."
    )
    @ApiResponses(value = {
        @io.swagger.v3.oas.annotations.responses.ApiResponse(
            responseCode = "200", 
            description = "조회 성공",
            content = @Content(schema = @Schema(implementation = TranscriptionDto.Response.class))
        ),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(
            responseCode = "404", 
            description = "변환 결과를 찾을 수 없음"
        )
    })
    @GetMapping("/{recordingId}")
    public ResponseEntity<ApiResponse<TranscriptionDto.Response>> getTranscription(
            @Parameter(description = "녹음 ID", required = true)
            @PathVariable String recordingId,
            @Parameter(description = "세그먼트 정보 포함 여부")
            @RequestParam(required = false, defaultValue = "false") Boolean includeSegments,
            @Parameter(description = "특정 화자 필터")
            @RequestParam(required = false) String speakerId) {
        log.debug("변환 결과 조회 요청 - recordingId: {}, includeSegments: {}, speakerId: {}", 
                recordingId, includeSegments, speakerId);
        
        TranscriptionDto.Response response = transcriptionService.getTranscription(recordingId, includeSegments, speakerId);
        
        return ResponseEntity.ok(ApiResponse.success(response));
    }
}