package com.devjob.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

/**
 * 채용 공고.
 *
 * EP13: companyId(Long) FK 컬럼을 @ManyToOne(LAZY) Company 연관관계로 전환.
 * job.getCompany().getName() 처럼 객체 참조로 접근하면 JPA가 JOIN을 자동 처리한다.
 * LAZY 로딩이 기본이므로, N+1을 피하려면 JobRepository의 fetch join 쿼리를 사용한다(EP13 검색 메서드 참고).
 */
@Entity
@Table(name = "job")
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@EntityListeners(AuditingEntityListener.class)
public class Job {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "company_id", nullable = false)
    private Company company;

    /**
     * 이 공고를 등록한 회원 ID(작성자). 수정·삭제는 작성자 본인 또는 관리자만 가능하다.
     */
    @Column(nullable = false)
    private Long registeredBy;

    @Column(nullable = false, length = 200)
    private String title;

    @Column(columnDefinition = "TEXT")
    private String description;

    private Integer salary;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false, length = 20)
    private JobStatus status = JobStatus.OPEN;

    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime updatedAt;

    /**
     * EP16: PUT /api/jobs/{id} — title/description/salary를 한 번에 교체한다.
     * 영속 상태의 엔티티 필드를 변경하면 트랜잭션 커밋 시 변경 감지(dirty checking)로 UPDATE 쿼리가 나간다.
     */
    public void update(String title, String description, Integer salary) {
        this.title = title;
        this.description = description;
        this.salary = salary;
    }
}
