package com.social.media.domain.analytics.repository;

import com.social.media.domain.analytics.aggregate.PostMetrics;
import com.social.media.domain.analytics.valueobject.PostMetricsId;
import com.social.media.domain.analytics.valueobject.MetricType;
import com.social.media.domain.company.valueobject.CompanyId;
import com.social.media.domain.content.valueobject.PostId;
import com.social.media.domain.socialaccount.valueobject.SocialAccountId;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * Repository interface for PostMetrics aggregate
 */
public interface PostMetricsRepository {
    
    PostMetrics save(PostMetrics postMetrics);
    
    Optional<PostMetrics> findById(PostMetricsId id);
    
    Optional<PostMetrics> findByPostId(PostId postId);
    
    List<PostMetrics> findByCompanyId(CompanyId companyId);
    
    List<PostMetrics> findBySocialAccountId(SocialAccountId socialAccountId);
    
    List<PostMetrics> findByCompanyIdAndSocialAccountId(CompanyId companyId, SocialAccountId socialAccountId);
    
    List<PostMetrics> findByPostIds(List<PostId> postIds);
    
    List<PostMetrics> findByCompanyIdAndCreatedBetween(CompanyId companyId, 
                                                       LocalDateTime start, LocalDateTime end);
    
    List<PostMetrics> findBySocialAccountIdAndCreatedBetween(SocialAccountId socialAccountId,
                                                             LocalDateTime start, LocalDateTime end);
    
    List<PostMetrics> findRecentlyUpdated(int hours);
    
    List<PostMetrics> findByCompanyIdRecentlyUpdated(CompanyId companyId, int hours);
    
    List<PostMetrics> findTopPerformingByCompanyId(CompanyId companyId, MetricType metricType, int limit);
    
    List<PostMetrics> findTopPerformingBySocialAccountId(SocialAccountId socialAccountId, 
                                                         MetricType metricType, int limit);
    
    List<PostMetrics> findHighEngagementPostsByCompanyId(CompanyId companyId, double minEngagementRate);
    
    List<PostMetrics> findViralPostsByCompanyId(CompanyId companyId);
    
    List<PostMetrics> findByCompanyIdOrderByEngagementDesc(CompanyId companyId);
    
    List<PostMetrics> findByCompanyIdOrderByViewsDesc(CompanyId companyId);
    
    List<PostMetrics> findByCompanyIdOrderByCreatedAtDesc(CompanyId companyId);
    
    void delete(PostMetrics postMetrics);
    
    void deleteById(PostMetricsId id);
    
    void deleteByPostId(PostId postId);
    
    void deleteOlderThan(LocalDateTime dateTime);
    
    long countByCompanyId(CompanyId companyId);
    
    long countBySocialAccountId(SocialAccountId socialAccountId);
    
    long countHighPerformingByCompanyId(CompanyId companyId);
    
    long countViralPostsByCompanyId(CompanyId companyId);
    
    double getAverageEngagementRateByCompanyId(CompanyId companyId);
    
    double getAverageEngagementRateBySocialAccountId(SocialAccountId socialAccountId);
    
    long getTotalEngagementByCompanyId(CompanyId companyId);
    
    long getTotalViewsByCompanyId(CompanyId companyId);
}
