package com.social.media.domain.analytics.repository;

import com.social.media.domain.analytics.aggregate.AccountMetrics;
import com.social.media.domain.analytics.valueobject.AccountMetricsId;
import com.social.media.domain.analytics.valueobject.TimePeriod;
import com.social.media.domain.analytics.valueobject.MetricType;
import com.social.media.domain.company.valueobject.CompanyId;
import com.social.media.domain.socialaccount.valueobject.SocialAccountId;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * Repository interface for AccountMetrics aggregate
 */
public interface AccountMetricsRepository {
    
    AccountMetrics save(AccountMetrics accountMetrics);
    
    Optional<AccountMetrics> findById(AccountMetricsId id);
    
    List<AccountMetrics> findByCompanyId(CompanyId companyId);
    
    List<AccountMetrics> findBySocialAccountId(SocialAccountId socialAccountId);
    
    List<AccountMetrics> findByCompanyIdAndPeriod(CompanyId companyId, TimePeriod period);
    
    List<AccountMetrics> findBySocialAccountIdAndPeriod(SocialAccountId socialAccountId, TimePeriod period);
    
    List<AccountMetrics> findByCompanyIdAndPeriodBetween(CompanyId companyId, 
                                                         LocalDateTime start, LocalDateTime end);
    
    List<AccountMetrics> findBySocialAccountIdAndPeriodBetween(SocialAccountId socialAccountId,
                                                               LocalDateTime start, LocalDateTime end);
    
    Optional<AccountMetrics> findBySocialAccountIdAndPeriodStartAndEnd(SocialAccountId socialAccountId,
                                                                       LocalDateTime periodStart,
                                                                       LocalDateTime periodEnd);
    
    List<AccountMetrics> findCurrentPeriodMetrics(TimePeriod period);
    
    List<AccountMetrics> findByCompanyIdCurrentPeriod(CompanyId companyId, TimePeriod period);
    
    List<AccountMetrics> findRecentlyCollected(int hours);
    
    List<AccountMetrics> findByCompanyIdRecentlyCollected(CompanyId companyId, int hours);
    
    List<AccountMetrics> findTopPerformingByCompanyId(CompanyId companyId, MetricType metricType, int limit);
    
    List<AccountMetrics> findByCompanyIdOrderByPeriodStartDesc(CompanyId companyId);
    
    void delete(AccountMetrics accountMetrics);
    
    void deleteById(AccountMetricsId id);
    
    void deleteOlderThan(LocalDateTime dateTime);
    
    long countByCompanyId(CompanyId companyId);
    
    long countBySocialAccountId(SocialAccountId socialAccountId);
    
    long countByCompanyIdAndPeriod(CompanyId companyId, TimePeriod period);
    
    double getAverageEngagementRateByCompanyId(CompanyId companyId);
    
    long getTotalFollowersByCompanyId(CompanyId companyId);
}
