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

import com.unicorn.hgzero.meeting.biz.domain.Dashboard;
import com.unicorn.hgzero.meeting.biz.domain.Meeting;
import com.unicorn.hgzero.meeting.biz.domain.Minutes;
import com.unicorn.hgzero.meeting.infra.dto.response.DashboardResponse;
import org.springframework.stereotype.Component;

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

/**
 * Dashboard 도메인 객체를 Response DTO로 변환하는 매퍼
 */
@Component
public class DashboardResponseMapper {

    /**
     * Dashboard 도메인 객체를 DashboardResponse로 변환
     */
    public DashboardResponse toResponse(Dashboard dashboard) {
        if (dashboard == null) {
            return null;
        }

        return DashboardResponse.builder()
                .upcomingMeetings(toUpcomingMeetingResponses(dashboard.getUpcomingMeetings()))
                .myMinutes(toRecentMinutesResponses(dashboard.getRecentMinutes()))
                .statistics(toStatisticsResponse(dashboard.getStatistics()))
                .build();
    }

    /**
     * Meeting 목록을 UpcomingMeetingResponse 목록으로 변환
     */
    private List<DashboardResponse.UpcomingMeetingResponse> toUpcomingMeetingResponses(List<Meeting> meetings) {
        if (meetings == null || meetings.isEmpty()) {
            return Collections.emptyList();
        }

        return meetings.stream()
                .map(this::toUpcomingMeetingResponse)
                .collect(Collectors.toList());
    }

    /**
     * Meeting을 UpcomingMeetingResponse로 변환
     */
    private DashboardResponse.UpcomingMeetingResponse toUpcomingMeetingResponse(Meeting meeting) {
        return DashboardResponse.UpcomingMeetingResponse.builder()
                .meetingId(meeting.getMeetingId())
                .title(meeting.getTitle())
                .startTime(meeting.getScheduledAt())
                .endTime(meeting.getEndTime())
                .location(meeting.getLocation())
                .participantCount(meeting.getParticipants() != null ? meeting.getParticipants().size() : 0)
                .status(meeting.getStatus())
                .build();
    }


    /**
     * Minutes 목록을 RecentMinutesResponse 목록으로 변환
     */
    private List<DashboardResponse.RecentMinutesResponse> toRecentMinutesResponses(List<Minutes> minutesList) {
        if (minutesList == null || minutesList.isEmpty()) {
            return Collections.emptyList();
        }

        return minutesList.stream()
                .map(this::toRecentMinutesResponse)
                .collect(Collectors.toList());
    }

    /**
     * Minutes를 RecentMinutesResponse로 변환
     */
    private DashboardResponse.RecentMinutesResponse toRecentMinutesResponse(Minutes minutes) {
        return DashboardResponse.RecentMinutesResponse.builder()
                .minutesId(minutes.getMinutesId())
                .title(minutes.getTitle())
                .meetingDate(minutes.getCreatedAt())
                .status(minutes.getStatus())
                .participantCount(0) // Meeting 정보가 필요한데 현재 Minutes에 직접적인 참석자 정보가 없음
                .lastModified(minutes.getLastModifiedAt() != null ? 
                        minutes.getLastModifiedAt() : minutes.getCreatedAt())
                .build();
    }

    /**
     * Dashboard.Statistics를 StatisticsResponse로 변환
     */
    private DashboardResponse.StatisticsResponse toStatisticsResponse(Dashboard.Statistics statistics) {
        if (statistics == null) {
            return DashboardResponse.StatisticsResponse.builder()
                    .upcomingMeetingsCount(0)
                    .todoCompletionRate(0.0)
                    .build();
        }

        // Todo 완료율 계산
        double todoCompletionRate = 0.0;
        int totalTodos = statistics.getTotalTodos() != null ? statistics.getTotalTodos() : 0;
        int completedTodos = statistics.getCompletedTodos() != null ? statistics.getCompletedTodos() : 0;
        
        if (totalTodos > 0) {
            todoCompletionRate = (double) completedTodos / totalTodos * 100.0;
        }

        return DashboardResponse.StatisticsResponse.builder()
                .upcomingMeetingsCount(statistics.getScheduledMeetings() != null ? 
                        statistics.getScheduledMeetings() : 0)
                .todoCompletionRate(todoCompletionRate)
                .build();
    }
}