package com.social.media.domain.campaign.entity;

import com.social.media.domain.campaign.valueobject.*;
import com.social.media.domain.shared.exception.BusinessRuleViolationException;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

/**
 * Campaign Execution Entity
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CampaignExecution {
    
    private Long id;
    private String executionCode;
    private Long campaignId;
    private ActionType actionType;
    private ExecutionStatus status;
    private String targetUserId;
    private String targetPostId;
    private String targetCommentId;
    private String actionParams;
    private String resultData;
    private LocalDateTime plannedExecutionDate;
    private LocalDateTime actualExecutionDate;
    private String errorMessage;
    private Integer retryCount;
    private Integer maxRetries;
    private Long executionDurationMs;
    private LocalDateTime createdAt;
    
    /**
     * Mark execution as completed
     */
    public void markAsCompleted(String resultData, Long durationMs) {
        this.status = ExecutionStatus.COMPLETED;
        this.resultData = resultData;
        this.actualExecutionDate = LocalDateTime.now();
        this.executionDurationMs = durationMs;
    }
    
    /**
     * Mark execution as failed
     */
    public void markAsFailed(String errorMessage) {
        this.status = ExecutionStatus.FAILED;
        this.errorMessage = errorMessage;
        this.actualExecutionDate = LocalDateTime.now();
    }
    
    /**
     * Retry execution
     */
    public void retry() {
        if (retryCount >= maxRetries) {
            throw new BusinessRuleViolationException("Maximum retry attempts reached");
        }
        this.retryCount++;
        this.status = ExecutionStatus.PENDING;
        this.errorMessage = null;
    }
    
    /**
     * Check if can retry
     */
    public boolean canRetry() {
        return status == ExecutionStatus.FAILED && retryCount < maxRetries;
    }
    
    /**
     * Check if execution is overdue
     */
    public boolean isOverdue() {
        return plannedExecutionDate != null && 
               plannedExecutionDate.isBefore(LocalDateTime.now()) &&
               status == ExecutionStatus.PENDING;
    }
}
