package dev.awesomedev.mirim.domain;

import jakarta.persistence.*;

import java.time.Instant;

/**
 * 이 파일이 하는 일:
 * 미림 수습 학습 플랫폼의 "사용자" 테이블을 표현하는 JPA 엔티티다.
 * 수습생(STUDENT)과 멘토(MENTOR) 모두 이 하나의 테이블에 저장된다.
 */
@Entity
@Table(name = "users") // 학습 포인트: "user"는 일부 DB(H2, Postgres)에서 예약어라 테이블명을 "users"로 피해간다.
public class User {

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

    /** 로그인 아이디. 중복될 수 없다. */
    @Column(nullable = false, unique = true)
    private String username;

    /**
     * 학습 포인트: 비밀번호는 절대 원문으로 저장하지 않는다.
     * BCrypt로 해시된 문자열만 저장하고, 로그인 시 PasswordEncoder.matches()로 비교한다.
     */
    @Column(nullable = false)
    private String passwordHash;

    /** 화면에 보여줄 이름 (예: 수습생1, 멘토) */
    @Column(nullable = false)
    private String name;

    /** 역할: "STUDENT" 또는 "MENTOR" */
    @Column(nullable = false)
    private String role;

    /** 트랙: "DEV" | "DESIGN" | "NONE" (멘토는 NONE) */
    @Column(nullable = false)
    private String track;

    /** 계정 생성 시각 */
    @Column(nullable = false)
    private Instant createdAt;

    /** 학습 포인트: JPA는 리플렉션으로 객체를 만들기 때문에 기본 생성자가 반드시 필요하다. */
    protected User() {
    }

    public User(String username, String passwordHash, String name, String role, String track) {
        this.username = username;
        this.passwordHash = passwordHash;
        this.name = name;
        this.role = role;
        this.track = track;
        this.createdAt = Instant.now();
    }

    /**
     * 비밀번호 변경 (비밀번호 재설정 기능에서 사용).
     *
     * 학습 포인트: 무분별한 setter를 다 열어두는 대신, "비밀번호를 바꾼다"는
     * 의미가 드러나는 메서드 하나만 연다. username이나 role을 바꾸는 setter가
     * 아예 없으면, 실수로라도 그런 코드를 쓸 수 없다(엔티티가 스스로 규칙을 지킨다).
     * 여기에는 반드시 "이미 해시된 값"만 들어와야 한다 — 인코딩은 서비스 계층의 책임이다.
     */
    /** 이름 변경 (내 정보 수정에서 오타 교정용). */
    public void rename(String newName) {
        this.name = newName;
    }

    public void changePassword(String newPasswordHash) {
        this.passwordHash = newPasswordHash;
    }

    public Long getId() {
        return id;
    }

    public String getUsername() {
        return username;
    }

    public String getPasswordHash() {
        return passwordHash;
    }

    public String getName() {
        return name;
    }

    public String getRole() {
        return role;
    }

    public String getTrack() {
        return track;
    }

    public Instant getCreatedAt() {
        return createdAt;
    }
}
