package com.unicorn.hgzero.user.repository.entity;

import com.unicorn.hgzero.common.entity.BaseTimeEntity;
import com.unicorn.hgzero.user.domain.User;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

/**
 * 사용자 Entity
 * 사용자 인증 정보를 데이터베이스에 저장
 */
@Entity
@Table(name = "users")
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserEntity extends BaseTimeEntity {

    /**
     * 사용자 ID (Primary Key)
     */
    @Id
    @Column(name = "user_id", length = 50)
    private String userId;

    /**
     * 사용자 이름
     */
    @Column(name = "username", length = 100, nullable = false)
    private String username;

    /**
     * 이메일
     */
    @Column(name = "email", length = 100, nullable = false)
    private String email;

    /**
     * 권한 (USER, ADMIN)
     */
    @Column(name = "authority", length = 20, nullable = false)
    @Builder.Default
    private String authority = "USER";

    /**
     * 계정 잠금 여부
     */
    @Column(name = "locked", nullable = false)
    @Builder.Default
    private Boolean locked = false;

    /**
     * 로그인 실패 횟수
     */
    @Column(name = "failed_login_attempts", nullable = false)
    @Builder.Default
    private Integer failedLoginAttempts = 0;

    /**
     * 마지막 로그인 일시
     */
    @Column(name = "last_login_at")
    private LocalDateTime lastLoginAt;

    /**
     * 계정 잠금 일시
     */
    @Column(name = "locked_at")
    private LocalDateTime lockedAt;

    /**
     * Entity를 Domain으로 변환
     *
     * @return User 도메인 객체
     */
    public User toDomain() {
        return User.builder()
                .userId(this.userId)
                .username(this.username)
                .email(this.email)
                .authority(this.authority)
                .locked(this.locked)
                .failedLoginAttempts(this.failedLoginAttempts)
                .lastLoginAt(this.lastLoginAt)
                .lockedAt(this.lockedAt)
                .build();
    }

    /**
     * Domain을 Entity로 변환
     *
     * @param user User 도메인 객체
     * @return UserEntity
     */
    public static UserEntity fromDomain(User user) {
        return UserEntity.builder()
                .userId(user.getUserId())
                .username(user.getUsername())
                .email(user.getEmail())
                .authority(user.getAuthority())
                .locked(user.getLocked())
                .failedLoginAttempts(user.getFailedLoginAttempts())
                .lastLoginAt(user.getLastLoginAt())
                .lockedAt(user.getLockedAt())
                .build();
    }

    /**
     * 계정 잠금 해제
     */
    public void unlock() {
        this.locked = false;
        this.failedLoginAttempts = 0;
        this.lockedAt = null;
    }

    /**
     * 로그인 실패 기록
     */
    public void recordLoginFailure() {
        this.failedLoginAttempts++;
        if (this.failedLoginAttempts >= 5) {
            this.locked = true;
            this.lockedAt = LocalDateTime.now();
        }
    }

    /**
     * 로그인 성공 기록
     */
    public void recordLoginSuccess() {
        this.failedLoginAttempts = 0;
        this.lastLoginAt = LocalDateTime.now();
    }

    /**
     * LDAP 정보로 사용자 정보 업데이트
     *
     * @param username 사용자 이름
     * @param email 이메일
     */
    public void updateFromLdap(String username, String email) {
        this.username = username;
        this.email = email;
    }
}
