package com.kt.event.content.infra.gateway.entity;

import com.kt.event.common.entity.BaseTimeEntity;
import com.kt.event.content.biz.domain.Job;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

/**
 * Job 엔티티
 * 이미지 생성 작업 정보를 저장
 */
@Entity
@Table(name = "jobs", indexes = {
        @Index(name = "idx_event_draft_id", columnList = "event_draft_id"),
        @Index(name = "idx_status", columnList = "status")
})
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class JobEntity extends BaseTimeEntity {

    @Id
    @Column(name = "id", length = 36)
    private String id;

    /**
     * 이벤트 ID (이벤트 초안 ID)
     */
    @Column(name = "event_draft_id", nullable = false)
    private Long eventDraftId;

    /**
     * Job 타입
     */
    @Column(name = "job_type", nullable = false, length = 50)
    private String jobType;

    /**
     * Job 상태
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    private Job.Status status;

    /**
     * 진행률 (0-100)
     */
    @Column(name = "progress", nullable = false)
    private int progress;

    /**
     * 결과 메시지
     */
    @Column(name = "result_message", columnDefinition = "TEXT")
    private String resultMessage;

    /**
     * 에러 메시지
     */
    @Column(name = "error_message", columnDefinition = "TEXT")
    private String errorMessage;

    /**
     * 정적 팩토리 메서드: 새 Job 생성
     *
     * @param id           Job ID (UUID)
     * @param eventDraftId 이벤트 초안 ID
     * @param jobType      Job 타입
     * @return JobEntity
     */
    public static JobEntity create(String id, Long eventDraftId, String jobType) {
        JobEntity entity = new JobEntity();
        entity.id = id;
        entity.eventDraftId = eventDraftId;
        entity.jobType = jobType;
        entity.status = Job.Status.PENDING;
        entity.progress = 0;
        return entity;
    }

    /**
     * 도메인 모델로 변환
     *
     * @return Job 도메인 모델
     */
    public Job toDomain() {
        return Job.builder()
                .id(id)
                .eventDraftId(eventDraftId)
                .jobType(jobType)
                .status(status)
                .progress(progress)
                .resultMessage(resultMessage)
                .errorMessage(errorMessage)
                .createdAt(getCreatedAt())
                .updatedAt(getUpdatedAt())
                .build();
    }

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

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

    /**
     * Job 완료 처리
     *
     * @param resultMessage 결과 메시지
     */
    public void complete(String resultMessage) {
        this.status = Job.Status.COMPLETED;
        this.progress = 100;
        this.resultMessage = resultMessage;
    }

    /**
     * Job 실패 처리
     *
     * @param errorMessage 에러 메시지
     */
    public void fail(String errorMessage) {
        this.status = Job.Status.FAILED;
        this.errorMessage = errorMessage;
    }

    /**
     * Job 상태 업데이트
     *
     * @param status   새 상태
     * @param progress 진행률
     */
    public void updateStatus(Job.Status status, int progress) {
        this.status = status;
        this.progress = progress;
    }

    /**
     * 결과 메시지 설정
     *
     * @param resultMessage 결과 메시지
     */
    public void setResultMessage(String resultMessage) {
        this.resultMessage = resultMessage;
    }

    /**
     * 에러 메시지 설정
     *
     * @param errorMessage 에러 메시지
     */
    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }
}
