package com.kt.event.eventservice.domain.entity;

import com.kt.event.common.entity.BaseTimeEntity;
import com.kt.event.eventservice.domain.enums.JobStatus;
import com.kt.event.eventservice.domain.enums.JobType;
import jakarta.persistence.*;
import lombok.*;

import java.time.LocalDateTime;

/**
 * 비동기 작업 엔티티
 *
 * AI 추천 생성, 이미지 생성 등의 비동기 작업 상태를 관리합니다.
 *
 * @author Event Service Team
 * @version 1.0.0
 * @since 2025-10-23
 */
@Entity
@Table(name = "jobs")
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class Job extends BaseTimeEntity {

    @Id
    @Column(name = "job_id", length = 50)
    private String jobId;

    @Column(name = "event_id", nullable = false, length = 50)
    private String eventId;

    @Enumerated(EnumType.STRING)
    @Column(name = "job_type", nullable = false, length = 30)
    private JobType jobType;

    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    @Builder.Default
    private JobStatus status = JobStatus.PENDING;

    @Column(name = "progress", nullable = false)
    @Builder.Default
    private int progress = 0;

    @Column(name = "result_key", length = 200)
    private String resultKey;

    @Column(name = "error_message", length = 500)
    private String errorMessage;

    @Column(name = "completed_at")
    private LocalDateTime completedAt;

    @Column(name = "retry_count", nullable = false)
    @Builder.Default
    private int retryCount = 0;

    @Column(name = "max_retry_count", nullable = false)
    @Builder.Default
    private int maxRetryCount = 3;

    // ==== 비즈니스 로직 ==== //

    /**
     * 작업 시작
     */
    public void start() {
        this.status = JobStatus.PROCESSING;
        this.progress = 0;
    }

    /**
     * 진행률 업데이트
     */
    public void updateProgress(int progress) {
        if (progress < 0 || progress > 100) {
            throw new IllegalArgumentException("진행률은 0~100 사이여야 합니다.");
        }
        this.progress = progress;
    }

    /**
     * 작업 완료
     */
    public void complete(String resultKey) {
        this.status = JobStatus.COMPLETED;
        this.progress = 100;
        this.resultKey = resultKey;
        this.completedAt = LocalDateTime.now();
    }

    /**
     * 작업 실패
     */
    public void fail(String errorMessage) {
        this.status = JobStatus.FAILED;
        this.errorMessage = errorMessage;
        this.completedAt = LocalDateTime.now();
    }

    /**
     * 재시도 가능 여부 확인
     */
    public boolean canRetry() {
        return this.retryCount < this.maxRetryCount;
    }

    /**
     * 재시도 카운트 증가
     */
    public void incrementRetryCount() {
        this.retryCount++;
    }

    /**
     * 재시도 준비 (상태를 PENDING으로 변경)
     */
    public void prepareRetry() {
        if (!canRetry()) {
            throw new IllegalStateException("최대 재시도 횟수를 초과했습니다.");
        }
        incrementRetryCount();
        this.status = JobStatus.PENDING;
        this.errorMessage = null;
    }
}
