package com.social.media.application.analytics.handler;

import com.social.media.application.analytics.dto.AnalyticsResponseDto;
import com.social.media.application.analytics.query.GetAnalyticsReportsByCompanyQuery;
import com.social.media.domain.analytics.aggregate.AnalyticsReport;
import com.social.media.domain.analytics.repository.AnalyticsReportRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Handler for GetAnalyticsReportsByCompanyQuery
 */
@Service
@Transactional(readOnly = true)
public class GetAnalyticsReportsByCompanyQueryHandler {
    
    private final AnalyticsReportRepository analyticsReportRepository;
    
    public GetAnalyticsReportsByCompanyQueryHandler(AnalyticsReportRepository analyticsReportRepository) {
        this.analyticsReportRepository = analyticsReportRepository;
    }
    
    public List<AnalyticsResponseDto> handle(GetAnalyticsReportsByCompanyQuery query) {
        List<AnalyticsReport> analyticsReports;
        
        // Check if filters are provided and use appropriate repository method
        if (hasMultipleFilters(query)) {
            analyticsReports = analyticsReportRepository.findByCompanyIdWithFilters(
                query.getCompanyId(),
                query.getReportType(),
                query.getMetricType(),
                query.getPeriodStart(),
                query.getPeriodEnd(),
                query.getPage(),
                query.getSize()
            );
        } else if (query.getReportType() != null) {
            analyticsReports = analyticsReportRepository.findByCompanyIdAndReportType(
                query.getCompanyId(),
                query.getReportType(),
                query.getPage(),
                query.getSize()
            );
        } else if (query.getMetricType() != null) {
            analyticsReports = analyticsReportRepository.findByCompanyIdAndMetricType(
                query.getCompanyId(),
                query.getMetricType(),
                query.getPage(),
                query.getSize()
            );
        } else if (query.getPeriodStart() != null && query.getPeriodEnd() != null) {
            analyticsReports = analyticsReportRepository.findByCompanyIdAndPeriod(
                query.getCompanyId(),
                query.getPeriodStart(),
                query.getPeriodEnd(),
                query.getPage(),
                query.getSize()
            );
        } else {
            analyticsReports = analyticsReportRepository.findByCompanyId(
                query.getCompanyId(),
                query.getPage(),
                query.getSize()
            );
        }
        
        // Convert to DTOs
        return analyticsReports.stream()
            .map(this::mapToDto)
            .collect(Collectors.toList());
    }
    
    private boolean hasMultipleFilters(GetAnalyticsReportsByCompanyQuery query) {
        int filterCount = 0;
        if (query.getReportType() != null) filterCount++;
        if (query.getMetricType() != null) filterCount++;
        if (query.getPeriodStart() != null && query.getPeriodEnd() != null) filterCount++;
        return filterCount > 1;
    }
    
    private AnalyticsResponseDto mapToDto(AnalyticsReport analyticsReport) {
        return AnalyticsResponseDto.builder(analyticsReport).build();
    }
}

