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

import com.unicorn.hgzero.common.dto.ApiResponse;
import com.unicorn.hgzero.meeting.biz.domain.AgendaSection;
import com.unicorn.hgzero.meeting.biz.domain.Meeting;
import com.unicorn.hgzero.meeting.biz.domain.Minutes;
import com.unicorn.hgzero.meeting.biz.domain.MinutesSection;
import com.unicorn.hgzero.meeting.biz.service.AgendaSectionService;
import com.unicorn.hgzero.meeting.biz.service.MeetingService;
import com.unicorn.hgzero.meeting.biz.service.MinutesService;
import com.unicorn.hgzero.meeting.infra.dto.response.ParticipantMinutesResponse;
import com.unicorn.hgzero.meeting.infra.dto.response.AgendaSectionResponse;
import com.unicorn.hgzero.meeting.infra.dto.response.MeetingStatisticsResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 회의 AI 기능 API Controller
 * 회의 종료 후 AI 통합 회의록 생성을 위한 API
 */
@RestController
@RequestMapping("/api/meetings")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "Meeting AI", description = "회의 AI 통합 기능 API")
public class MeetingAiController {

    private final MinutesService minutesService;
    private final AgendaSectionService agendaSectionService;
    private final MeetingService meetingService;

    @GetMapping("/{meetingId}/ai/participant-minutes")
    @Operation(
        summary = "참석자별 회의록 조회",
        description = "특정 회의의 모든 참석자가 작성한 회의록을 조회합니다. AI Service가 통합 회의록 생성 시 사용합니다."
    )
    public ResponseEntity<ApiResponse<ParticipantMinutesResponse>> getParticipantMinutes(
            @Parameter(description = "회의 ID") @PathVariable String meetingId,
            @RequestHeader("X-User-Id") String userId) {

        log.info("참석자별 회의록 조회 요청 - meetingId: {}, userId: {}", meetingId, userId);

        try {
            List<Minutes> participantMinutes = minutesService.getParticipantMinutesByMeeting(meetingId);

            List<ParticipantMinutesResponse.ParticipantMinutesItem> items = participantMinutes.stream()
                    .map(this::convertToParticipantMinutesItem)
                    .collect(Collectors.toList());

            ParticipantMinutesResponse response = ParticipantMinutesResponse.builder()
                    .meetingId(meetingId)
                    .participantMinutes(items)
                    .build();

            log.info("참석자별 회의록 조회 성공 - meetingId: {}, count: {}", meetingId, items.size());

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

        } catch (Exception e) {
            log.error("참석자별 회의록 조회 실패 - meetingId: {}", meetingId, e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.errorWithType("참석자별 회의록 조회에 실패했습니다"));
        }
    }

    @GetMapping("/{meetingId}/ai/agenda-sections")
    @Operation(
        summary = "안건별 섹션 조회",
        description = "특정 회의의 안건별 AI 요약 섹션을 조회합니다. 회의 종료 화면에서 사용합니다."
    )
    public ResponseEntity<ApiResponse<AgendaSectionResponse>> getAgendaSections(
            @Parameter(description = "회의 ID") @PathVariable String meetingId,
            @RequestHeader("X-User-Id") String userId) {

        log.info("안건별 섹션 조회 요청 - meetingId: {}, userId: {}", meetingId, userId);

        try {
            List<AgendaSection> sections = agendaSectionService.getAgendaSectionsByMeeting(meetingId);

            List<AgendaSectionResponse.AgendaSectionItem> items = sections.stream()
                    .map(this::convertToAgendaSectionItem)
                    .collect(Collectors.toList());

            AgendaSectionResponse response = AgendaSectionResponse.builder()
                    .meetingId(meetingId)
                    .sections(items)
                    .build();

            log.info("안건별 섹션 조회 성공 - meetingId: {}, count: {}", meetingId, items.size());

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

        } catch (Exception e) {
            log.error("안건별 섹션 조회 실패 - meetingId: {}", meetingId, e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.errorWithType("안건별 섹션 조회에 실패했습니다"));
        }
    }

    @GetMapping("/{meetingId}/ai/statistics")
    @Operation(
        summary = "회의 통계 조회",
        description = "특정 회의의 통계 정보를 조회합니다. 회의 종료 화면에서 사용합니다."
    )
    public ResponseEntity<ApiResponse<MeetingStatisticsResponse>> getMeetingStatistics(
            @Parameter(description = "회의 ID") @PathVariable String meetingId,
            @RequestHeader("X-User-Id") String userId) {

        log.info("회의 통계 조회 요청 - meetingId: {}, userId: {}", meetingId, userId);

        try {
            MeetingStatisticsResponse response = buildMeetingStatistics(meetingId);

            log.info("회의 통계 조회 성공 - meetingId: {}", meetingId);

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

        } catch (Exception e) {
            log.error("회의 통계 조회 실패 - meetingId: {}", meetingId, e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.errorWithType("회의 통계 조회에 실패했습니다"));
        }
    }

    private ParticipantMinutesResponse.ParticipantMinutesItem convertToParticipantMinutesItem(Minutes minutes) {
        List<ParticipantMinutesResponse.ParticipantMinutesItem.MinutesSection> sections = null;
        if (minutes.getSections() != null) {
            sections = minutes.getSections().stream()
                    .map(this::convertToMinutesSection)
                    .collect(Collectors.toList());
        }

        return ParticipantMinutesResponse.ParticipantMinutesItem.builder()
                .minutesId(minutes.getMinutesId())
                .userId(minutes.getUserId())
                .title(minutes.getTitle())
                .status(minutes.getStatus())
                .version(minutes.getVersion())
                .createdBy(minutes.getCreatedBy())
                .createdAt(minutes.getCreatedAt())
                .lastModifiedAt(minutes.getLastModifiedAt())
                .sections(sections)
                .build();
    }

    private ParticipantMinutesResponse.ParticipantMinutesItem.MinutesSection convertToMinutesSection(MinutesSection section) {
        return ParticipantMinutesResponse.ParticipantMinutesItem.MinutesSection.builder()
                .sectionId(section.getSectionId())
                .title(section.getTitle())
                .type(section.getType())
                .content(section.getContent())
                .orderIndex(section.getOrder())
                .build();
    }

    private AgendaSectionResponse.AgendaSectionItem convertToAgendaSectionItem(AgendaSection section) {
        List<AgendaSectionResponse.AgendaSectionItem.TodoItem> todos = null;
        if (section.getTodos() != null) {
            todos = section.getTodos().stream()
                    .map(todo -> AgendaSectionResponse.AgendaSectionItem.TodoItem.builder()
                            .title(todo.getTitle())
                            .assignee(todo.getAssignee())
                            .dueDate(todo.getDueDate())
                            .description(todo.getDescription())
                            .priority(todo.getPriority())
                            .build())
                    .collect(Collectors.toList());
        }

        return AgendaSectionResponse.AgendaSectionItem.builder()
                .id(section.getId())
                .minutesId(section.getMinutesId())
                .agendaNumber(section.getAgendaNumber())
                .agendaTitle(section.getAgendaTitle())
                .aiSummaryShort(section.getAiSummaryShort())
                .summary(section.getSummary())
                .pendingItems(section.getPendingItems())
                .todos(todos)
                .createdAt(section.getCreatedAt())
                .updatedAt(section.getUpdatedAt())
                .build();
    }

    private MeetingStatisticsResponse buildMeetingStatistics(String meetingId) {
        Meeting meeting = meetingService.getMeeting(meetingId);
        List<AgendaSection> sections = agendaSectionService.getAgendaSectionsByMeeting(meetingId);

        // AI가 추출한 Todo 수 계산
        int todoCount = sections.stream()
                .mapToInt(s -> s.getTodos() != null ? s.getTodos().size() : 0)
                .sum();

        // 회의 시간 계산
        Integer durationMinutes = null;
        if (meeting.getStartedAt() != null && meeting.getEndedAt() != null) {
            durationMinutes = (int) java.time.Duration.between(
                meeting.getStartedAt(),
                meeting.getEndedAt()
            ).toMinutes();
        }

        return MeetingStatisticsResponse.builder()
                .meetingId(meetingId)
                .meetingTitle(meeting.getTitle())
                .startTime(meeting.getStartedAt())
                .endTime(meeting.getEndedAt())
                .durationMinutes(durationMinutes)
                .participantCount(meeting.getParticipants() != null ? meeting.getParticipants().size() : 0)
                .agendaCount(sections.size())
                .todoCount(todoCount)
                .build();
    }
}
