package com.social.media.application.analytics.handler;

import com.social.media.application.analytics.command.RegenerateAnalyticsReportCommand;
import com.social.media.application.analytics.dto.AnalyticsResponseDto;
import com.social.media.domain.analytics.aggregate.AnalyticsReport;
import com.social.media.domain.analytics.repository.AnalyticsReportRepository;
import com.social.media.domain.analytics.valueobject.AnalyticsId;
import com.social.media.domain.shared.exception.BusinessRuleViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * Handler for RegenerateAnalyticsReportCommand
 */
@Service
public class RegenerateAnalyticsReportCommandHandler {
    
    private final AnalyticsReportRepository analyticsReportRepository;
    
    public RegenerateAnalyticsReportCommandHandler(AnalyticsReportRepository analyticsReportRepository) {
        this.analyticsReportRepository = analyticsReportRepository;
    }
    
    @Transactional
    public AnalyticsResponseDto handle(RegenerateAnalyticsReportCommand command) {
        // Find existing analytics report
        AnalyticsId analyticsId = AnalyticsId.of(command.getAnalyticsId());
        AnalyticsReport analyticsReport = analyticsReportRepository.findById(analyticsId)
            .orElseThrow(() -> new BusinessRuleViolationException("Analytics report not found: " + command.getAnalyticsId()));
        
        // Check if regeneration is needed (unless forced)
        if (!command.isForceRegeneration() && analyticsReport.isRecentlyGenerated(24)) {
            throw new BusinessRuleViolationException("Report was recently generated. Use force regeneration if needed.");
        }
        
        // Mark as regenerated (this would trigger actual data regeneration in a real implementation)
        analyticsReport.markAsRegenerated();
        
        // Save updated analytics report
        AnalyticsReport savedReport = analyticsReportRepository.save(analyticsReport);
        
        // Return DTO
        return mapToDto(savedReport);
    }
    
    private AnalyticsResponseDto mapToDto(AnalyticsReport analyticsReport) {
        return AnalyticsResponseDto.builder(analyticsReport).build();
    }
}

