package com.social.media.domain.campaign.repository;

import com.social.media.domain.campaign.aggregate.Campaign;
import com.social.media.domain.campaign.valueobject.CampaignId;
import com.social.media.domain.campaign.valueobject.CampaignInteractionStatus;
import com.social.media.domain.campaign.valueobject.CampaignInteractionType;
import com.social.media.domain.user.valueobject.UserId;
import com.social.media.domain.socialaccount.valueobject.SocialAccountId;
import com.social.media.domain.bot.valueobject.BotId;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * Repository interface for Campaign aggregate
 */
public interface CampaignRepository {
    
    /**
     * Save a campaign
     */
    Campaign save(Campaign campaign);
    
    /**
     * Find campaign by ID
     */
    Optional<Campaign> findById(CampaignId campaignId);
    
    /**
     * Find all campaigns by user
     */
    List<Campaign> findByUserId(UserId userId);
    
    /**
     * Find campaigns by user and status
     */
    List<Campaign> findByUserIdAndStatus(UserId userId, CampaignInteractionStatus status);
    
    /**
     * Find campaigns by user and interaction type
     */
    List<Campaign> findByUserIdAndInteractionType(UserId userId, CampaignInteractionType interactionType);
    
    /**
     * Find campaigns by bot
     */
    List<Campaign> findByBotId(BotId botId);
    
    /**
     * Find campaigns by social account
     */
    List<Campaign> findByAccountNetworkId(SocialAccountId accountNetworkId);
    
    /**
     * Find active campaigns (running status)
     */
    List<Campaign> findActiveCampaigns();
    
    /**
     * Find campaigns scheduled for a specific date
     */
    List<Campaign> findScheduledForDate(LocalDate date);
    
    /**
     * Find campaigns in execution period
     */
    List<Campaign> findInExecutionPeriod(LocalDateTime dateTime);
    
    /**
     * Find campaigns by date range
     */
    List<Campaign> findByDateRange(LocalDate startDate, LocalDate endDate);
    
    /**
     * Find campaigns by user and date range
     */
    List<Campaign> findByUserIdAndDateRange(UserId userId, LocalDate startDate, LocalDate endDate);
    
    /**
     * Find campaigns that need to be started (status WAIT and dateStart <= current date)
     */
    List<Campaign> findCampaignsToStart(LocalDateTime currentDateTime);
    
    /**
     * Find campaigns that need to be stopped (status RUNNING and dateEnd <= current date)
     */
    List<Campaign> findCampaignsToStop(LocalDateTime currentDateTime);
    
    /**
     * Check if a campaign name exists for a user
     */
    boolean existsByUserIdAndName(UserId userId, String name);
    
    /**
     * Count campaigns by user
     */
    long countByUserId(UserId userId);
    
    /**
     * Count campaigns by user and status
     */
    long countByUserIdAndStatus(UserId userId, CampaignInteractionStatus status);
    
    /**
     * Delete campaign by ID
     */
    void deleteById(CampaignId campaignId);
    
    /**
     * Check if campaign exists
     */
    boolean existsById(CampaignId campaignId);
}
