package com.unicorn.hgzero.meeting.infra.controller;

import com.unicorn.hgzero.common.dto.ApiResponse;
import com.unicorn.hgzero.meeting.biz.dto.MeetingDTO;
import com.unicorn.hgzero.meeting.biz.usecase.in.meeting.*;
import com.unicorn.hgzero.meeting.infra.dto.request.CreateMeetingRequest;
import com.unicorn.hgzero.meeting.infra.dto.request.SelectTemplateRequest;
import com.unicorn.hgzero.meeting.infra.dto.response.MeetingResponse;
import com.unicorn.hgzero.meeting.infra.dto.response.SessionResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
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 jakarta.validation.Valid;

/**
 * 회의 관리 REST API Controller
 * 회의 예약, 시작, 종료, 템플릿 적용 등 회의 관련 기능 제공
 */
@Tag(name = "Meeting", description = "회의 관리 API")
@RestController
@RequestMapping("/api/meetings")
@RequiredArgsConstructor
@Slf4j
public class MeetingController {

    private final CreateMeetingUseCase createMeetingUseCase;
    private final StartMeetingUseCase startMeetingUseCase;
    private final EndMeetingUseCase endMeetingUseCase;
    private final GetMeetingUseCase getMeetingUseCase;
    private final CancelMeetingUseCase cancelMeetingUseCase;

    /**
     * 회의 예약
     * 
     * @param userId 사용자 ID
     * @param request 회의 생성 요청
     * @return 생성된 회의 정보
     */
    @Operation(
        summary = "회의 예약",
        description = "새로운 회의를 예약하고 참석자를 초대합니다. 회의 정보 저장, 참석자 목록 관리, 초대 이메일 자동 발송, 리마인더 스케줄링을 수행합니다.",
        security = @SecurityRequirement(name = "bearerAuth")
    )
    @PostMapping
    public ResponseEntity<ApiResponse<MeetingResponse>> createMeeting(
            @Parameter(description = "사용자 ID", required = true)
            @RequestHeader("X-User-Id") String userId,
            @Parameter(description = "사용자명", required = true)
            @RequestHeader("X-User-Name") String userName,
            @Parameter(description = "사용자 이메일", required = true)
            @RequestHeader("X-User-Email") String userEmail,
            @Valid @RequestBody CreateMeetingRequest request) {
        
        log.info("회의 예약 요청 - userId: {}, title: {}", userId, request.getTitle());
        
        var meetingData = createMeetingUseCase.createMeeting(
            new CreateMeetingUseCase.CreateMeetingCommand(
                request.getTitle(),
                request.getAgenda(),
                request.getStartTime(),
                userId,
                request.getParticipants(),
                null // 템플릿 ID는 나중에 적용
            )
        );
        
        var meetingDTO = MeetingDTO.from(meetingData);
        var response = MeetingResponse.from(meetingDTO);
        
        log.info("회의 예약 완료 - userId: {}, meetingId: {}", userId, meetingData.getMeetingId());
        
        return ResponseEntity.status(HttpStatus.CREATED)
                .body(ApiResponse.success(response));
    }

    /**
     * 회의록 템플릿 선택
     * 
     * @param meetingId 회의 ID
     * @param userId 사용자 ID
     * @param request 템플릿 선택 요청
     * @return 회의 정보
     */
    @Operation(
        summary = "회의록 템플릿 선택",
        description = "회의에 회의록 템플릿을 적용합니다. 템플릿 유형으로는 일반 회의, 스크럼, 프로젝트 킥오프, 주간 회의가 있으며 섹션 커스터마이징이 가능합니다.",
        security = @SecurityRequirement(name = "bearerAuth")
    )
    @PutMapping("/{meetingId}/template")
    public ResponseEntity<ApiResponse<MeetingResponse>> applyTemplate(
            @Parameter(description = "회의 ID", required = true)
            @PathVariable String meetingId,
            @Parameter(description = "사용자 ID", required = true)
            @RequestHeader("X-User-Id") String userId,
            @Parameter(description = "사용자명", required = true)
            @RequestHeader("X-User-Name") String userName,
            @Parameter(description = "사용자 이메일", required = true)
            @RequestHeader("X-User-Email") String userEmail,
            @Valid @RequestBody SelectTemplateRequest request) {
        
        log.info("템플릿 적용 요청 - meetingId: {}, templateId: {}", meetingId, request.getTemplateId());
        
        var meetingData = getMeetingUseCase.getMeeting(meetingId);
        var meetingDTO = MeetingDTO.from(meetingData);
        var response = MeetingResponse.from(meetingDTO);
        
        log.info("템플릿 적용 완료 - meetingId: {}", meetingId);
        
        return ResponseEntity.ok(ApiResponse.success(response));
    }

    /**
     * 회의 시작
     * 
     * @param meetingId 회의 ID
     * @param userId 사용자 ID
     * @return 세션 정보
     */
    @Operation(
        summary = "회의 시작",
        description = "예약된 회의를 시작하고 회의록 작성 세션을 생성합니다. 실시간 협업을 위한 WebSocket 세션이 활성화됩니다.",
        security = @SecurityRequirement(name = "bearerAuth")
    )
    @PostMapping("/{meetingId}/start")
    public ResponseEntity<ApiResponse<SessionResponse>> startMeeting(
            @Parameter(description = "회의 ID", required = true)
            @PathVariable String meetingId,
            @Parameter(description = "사용자 ID", required = true)
            @RequestHeader("X-User-Id") String userId,
            @Parameter(description = "사용자명", required = true)
            @RequestHeader("X-User-Name") String userName,
            @Parameter(description = "사용자 이메일", required = true)
            @RequestHeader("X-User-Email") String userEmail) {
        
        log.info("회의 시작 요청 - meetingId: {}, userId: {}", meetingId, userId);
        
        var sessionData = startMeetingUseCase.startMeeting(meetingId);
        var response = SessionResponse.from(sessionData);
        
        log.info("회의 시작 완료 - meetingId: {}", meetingId);
        
        return ResponseEntity.ok(ApiResponse.success(response));
    }

    /**
     * 회의 종료
     * 
     * @param meetingId 회의 ID
     * @param userId 사용자 ID
     * @return 회의 정보
     */
    @Operation(
        summary = "회의 종료",
        description = "진행 중인 회의를 종료하고 회의록 작성을 완료합니다. 자동 Todo 추출 및 알림 발송이 수행됩니다.",
        security = @SecurityRequirement(name = "bearerAuth")
    )
    @PostMapping("/{meetingId}/end")
    public ResponseEntity<ApiResponse<MeetingResponse>> endMeeting(
            @Parameter(description = "회의 ID", required = true)
            @PathVariable String meetingId,
            @Parameter(description = "사용자 ID", required = true)
            @RequestHeader("X-User-Id") String userId,
            @Parameter(description = "사용자명", required = true)
            @RequestHeader("X-User-Name") String userName,
            @Parameter(description = "사용자 이메일", required = true)
            @RequestHeader("X-User-Email") String userEmail) {
        
        log.info("회의 종료 요청 - meetingId: {}, userId: {}", meetingId, userId);
        
        var meetingData = endMeetingUseCase.endMeeting(meetingId);
        var meetingDTO = MeetingDTO.from(meetingData);
        var response = MeetingResponse.from(meetingDTO);
        
        log.info("회의 종료 완료 - meetingId: {}", meetingId);
        
        return ResponseEntity.ok(ApiResponse.success(response));
    }

    /**
     * 회의 정보 조회
     * 
     * @param meetingId 회의 ID
     * @return 회의 정보
     */
    @Operation(
        summary = "회의 정보 조회",
        description = "특정 회의의 상세 정보를 조회합니다.",
        security = @SecurityRequirement(name = "bearerAuth")
    )
    @GetMapping("/{meetingId}")
    public ResponseEntity<ApiResponse<MeetingResponse>> getMeeting(
            @Parameter(description = "회의 ID", required = true)
            @PathVariable String meetingId,
            @Parameter(description = "사용자 ID", required = true)
            @RequestHeader("X-User-Id") String userId) {
        
        log.info("회의 정보 조회 요청 - meetingId: {}", meetingId);
        
        var meetingData = getMeetingUseCase.getMeeting(meetingId);
        var meetingDTO = MeetingDTO.from(meetingData);
        var response = MeetingResponse.from(meetingDTO);
        
        log.info("회의 정보 조회 완료 - meetingId: {}", meetingId);
        
        return ResponseEntity.ok(ApiResponse.success(response));
    }

    /**
     * 회의 취소
     * 
     * @param meetingId 회의 ID
     * @param userId 사용자 ID
     * @return 성공 응답
     */
    @Operation(
        summary = "회의 취소",
        description = "예약된 회의를 취소합니다.",
        security = @SecurityRequirement(name = "bearerAuth")
    )
    @DeleteMapping("/{meetingId}")
    public ResponseEntity<ApiResponse<Void>> cancelMeeting(
            @Parameter(description = "회의 ID", required = true)
            @PathVariable String meetingId,
            @Parameter(description = "사용자 ID", required = true)
            @RequestHeader("X-User-Id") String userId) {
        
        log.info("회의 취소 요청 - meetingId: {}, userId: {}", meetingId, userId);
        
        cancelMeetingUseCase.cancelMeeting(meetingId);
        
        log.info("회의 취소 완료 - meetingId: {}", meetingId);
        
        return ResponseEntity.ok(ApiResponse.success(null));
    }
}