package com.social.media.domain.bot.repository;

import com.social.media.domain.bot.aggregate.BotExecution;
import com.social.media.domain.bot.valueobject.BotExecutionId;
import com.social.media.domain.bot.valueobject.BotId;
import com.social.media.domain.bot.valueobject.ExecutionStatus;
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 BotExecution aggregate
 */
public interface BotExecutionRepository {
    
    BotExecution save(BotExecution botExecution);
    
    Optional<BotExecution> findById(BotExecutionId id);
    
    List<BotExecution> findByCompanyId(CompanyId companyId);
    
    List<BotExecution> findByBotId(BotId botId);
    
    List<BotExecution> findByCompanyIdAndStatus(CompanyId companyId, ExecutionStatus status);
    
    List<BotExecution> findByBotIdAndStatus(BotId botId, ExecutionStatus status);
    
    List<BotExecution> findByCompanyIdAndSocialAccountId(CompanyId companyId, SocialAccountId socialAccountId);
    
    List<BotExecution> findRunningExecutions();
    
    List<BotExecution> findRunningExecutionsByCompanyId(CompanyId companyId);
    
    List<BotExecution> findByCompanyIdAndStartedBetween(CompanyId companyId, LocalDateTime start, LocalDateTime end);
    
    List<BotExecution> findByBotIdAndStartedBetween(BotId botId, LocalDateTime start, LocalDateTime end);
    
    List<BotExecution> findRecentExecutionsByBotId(BotId botId, int limit);
    
    List<BotExecution> findFailedExecutionsByCompanyId(CompanyId companyId);
    
    List<BotExecution> findSuccessfulExecutionsByBotId(BotId botId);
    
    List<BotExecution> findByCompanyIdOrderByStartedAtDesc(CompanyId companyId);
    
    Optional<BotExecution> findLatestByBotId(BotId botId);
    
    Optional<BotExecution> findLatestSuccessfulByBotId(BotId botId);
    
    void delete(BotExecution botExecution);
    
    void deleteById(BotExecutionId id);
    
    void deleteOlderThan(LocalDateTime dateTime);
    
    long countByCompanyId(CompanyId companyId);
    
    long countByBotId(BotId botId);
    
    long countByCompanyIdAndStatus(CompanyId companyId, ExecutionStatus status);
    
    long countSuccessfulByBotId(BotId botId);
    
    long countFailedByBotId(BotId botId);
    
    long countByCompanyIdAndStartedToday(CompanyId companyId);
    
    double getAverageExecutionTimeByBotId(BotId botId);
    
    int getTotalActionsPerformedByBotId(BotId botId);
}
