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 org.hibernate.annotations.GenericGenerator;

import java.time.LocalDateTime;
import java.util.UUID;

/**
 * 비동기 작업 엔티티
 *
 * 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
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "uuid2")
    @Column(name = "job_id", columnDefinition = "uuid")
    private UUID jobId;

    @Column(name = "event_id", nullable = false, columnDefinition = "uuid")
    private UUID 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;

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

    /**
     * 작업 시작
     */
    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();
    }
}
