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

import com.unicorn.hgzero.meeting.biz.domain.Dashboard;
import com.unicorn.hgzero.meeting.biz.usecase.out.DashboardReader;
import com.unicorn.hgzero.meeting.infra.gateway.repository.MeetingJpaRepository;
import com.unicorn.hgzero.meeting.infra.gateway.repository.MinutesJpaRepository;
import com.unicorn.hgzero.meeting.infra.gateway.repository.TodoJpaRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 대시보드 Gateway 구현체
 * DashboardReader 인터페이스 구현
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class DashboardGateway implements DashboardReader {

    private final MeetingJpaRepository meetingJpaRepository;
    private final MinutesJpaRepository minutesJpaRepository;
    private final TodoJpaRepository todoJpaRepository;

    @Override
    public Dashboard getDashboardByUserId(String userId) {
        log.debug("Getting dashboard for user: {}", userId);

        // 회의 통계 조회
        long totalMeetings = meetingJpaRepository.findByOrganizerId(userId).size();
        long scheduledMeetings = meetingJpaRepository.findByOrganizerIdAndStatus(userId, "SCHEDULED").size();
        long inProgressMeetings = meetingJpaRepository.findByOrganizerIdAndStatus(userId, "IN_PROGRESS").size();
        long completedMeetings = meetingJpaRepository.findByOrganizerIdAndStatus(userId, "COMPLETED").size();

        // 회의록 통계 조회
        long totalMinutes = minutesJpaRepository.findByCreatedBy(userId).size();
        long draftMinutes = minutesJpaRepository.findByCreatedBy(userId).stream()
                .filter(m -> "DRAFT".equals(m.getStatus()))
                .count();
        long finalizedMinutes = minutesJpaRepository.findByCreatedBy(userId).stream()
                .filter(m -> "FINALIZED".equals(m.getStatus()))
                .count();

        // Todo 통계 조회
        long totalTodos = todoJpaRepository.findByAssigneeId(userId).size();
        long pendingTodos = todoJpaRepository.findByAssigneeIdAndStatus(userId, "PENDING").size();
        long completedTodos = todoJpaRepository.findByAssigneeIdAndStatus(userId, "COMPLETED").size();
        long overdueTodos = todoJpaRepository.findByAssigneeId(userId).stream()
                .filter(todo -> todo.getDueDate() != null
                        && LocalDate.now().isAfter(todo.getDueDate())
                        && !"COMPLETED".equals(todo.getStatus()))
                .count();

        // 통계 객체 생성
        Dashboard.Statistics statistics = Dashboard.Statistics.builder()
                .totalMeetings((int) totalMeetings)
                .scheduledMeetings((int) scheduledMeetings)
                .inProgressMeetings((int) inProgressMeetings)
                .completedMeetings((int) completedMeetings)
                .totalMinutes((int) totalMinutes)
                .draftMinutes((int) draftMinutes)
                .finalizedMinutes((int) finalizedMinutes)
                .totalTodos((int) totalTodos)
                .pendingTodos((int) pendingTodos)
                .completedTodos((int) completedTodos)
                .overdueTodos((int) overdueTodos)
                .build();

        // 대시보드 생성
        return Dashboard.builder()
                .userId(userId)
                .statistics(statistics)
                .build();
    }

    @Override
    public Dashboard getDashboardByUserIdAndPeriod(String userId, String period) {
        log.debug("Getting dashboard for user: {} with period: {}", userId, period);

        // 기간 계산
        LocalDateTime startTime = calculateStartTime(period);
        LocalDateTime endTime = LocalDateTime.now();

        // 기간 내 회의 통계 조회
        long totalMeetings = meetingJpaRepository.findByOrganizerId(userId).stream()
                .filter(m -> m.getScheduledAt().isAfter(startTime) && m.getScheduledAt().isBefore(endTime))
                .count();

        long scheduledMeetings = meetingJpaRepository.findByOrganizerIdAndStatus(userId, "SCHEDULED").stream()
                .filter(m -> m.getScheduledAt().isAfter(startTime) && m.getScheduledAt().isBefore(endTime))
                .count();

        long inProgressMeetings = meetingJpaRepository.findByOrganizerIdAndStatus(userId, "IN_PROGRESS").stream()
                .filter(m -> m.getScheduledAt().isAfter(startTime) && m.getScheduledAt().isBefore(endTime))
                .count();

        long completedMeetings = meetingJpaRepository.findByOrganizerIdAndStatus(userId, "COMPLETED").stream()
                .filter(m -> m.getScheduledAt().isAfter(startTime) && m.getScheduledAt().isBefore(endTime))
                .count();

        // 회의록 통계 조회 (전체 기간)
        long totalMinutes = minutesJpaRepository.findByCreatedBy(userId).size();
        long draftMinutes = minutesJpaRepository.findByCreatedBy(userId).stream()
                .filter(m -> "DRAFT".equals(m.getStatus()))
                .count();
        long finalizedMinutes = minutesJpaRepository.findByCreatedBy(userId).stream()
                .filter(m -> "FINALIZED".equals(m.getStatus()))
                .count();

        // Todo 통계 조회 (전체 기간)
        long totalTodos = todoJpaRepository.findByAssigneeId(userId).size();
        long pendingTodos = todoJpaRepository.findByAssigneeIdAndStatus(userId, "PENDING").size();
        long completedTodos = todoJpaRepository.findByAssigneeIdAndStatus(userId, "COMPLETED").size();
        long overdueTodos = todoJpaRepository.findByAssigneeId(userId).stream()
                .filter(todo -> todo.getDueDate() != null
                        && LocalDate.now().isAfter(todo.getDueDate())
                        && !"COMPLETED".equals(todo.getStatus()))
                .count();

        // 통계 객체 생성
        Dashboard.Statistics statistics = Dashboard.Statistics.builder()
                .totalMeetings((int) totalMeetings)
                .scheduledMeetings((int) scheduledMeetings)
                .inProgressMeetings((int) inProgressMeetings)
                .completedMeetings((int) completedMeetings)
                .totalMinutes((int) totalMinutes)
                .draftMinutes((int) draftMinutes)
                .finalizedMinutes((int) finalizedMinutes)
                .totalTodos((int) totalTodos)
                .pendingTodos((int) pendingTodos)
                .completedTodos((int) completedTodos)
                .overdueTodos((int) overdueTodos)
                .build();

        // 대시보드 생성
        return Dashboard.builder()
                .userId(userId)
                .period(period)
                .statistics(statistics)
                .build();
    }

    /**
     * 기간 문자열로부터 시작 시간 계산
     */
    private LocalDateTime calculateStartTime(String period) {
        LocalDateTime now = LocalDateTime.now();

        return switch (period.toUpperCase()) {
            case "WEEK" -> now.minusWeeks(1);
            case "MONTH" -> now.minusMonths(1);
            case "QUARTER" -> now.minusMonths(3);
            case "YEAR" -> now.minusYears(1);
            default -> now.minusMonths(1); // 기본값: 1개월
        };
    }
}
