package com.kt.event.user.entity;

import com.kt.event.common.entity.BaseTimeEntity;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.GenericGenerator;

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

/**
 * 사용자 엔티티
 *
 * 소상공인 사용자 정보를 저장하는 엔티티
 *
 * @author Backend Developer
 * @since 1.0
 */
@Entity
@Table(name = "users", indexes = {
    @Index(name = "idx_user_phone", columnList = "phone_number", unique = true),
    @Index(name = "idx_user_email", columnList = "email", unique = true)
})
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class User extends BaseTimeEntity {

    /**
     * 사용자 ID (Primary Key)
     */
    @Id
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "uuid2")
    @Column(name = "user_id", columnDefinition = "uuid")
    private UUID id;

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

    /**
     * 전화번호 (로그인 ID로도 사용)
     */
    @Column(name = "phone_number", nullable = false, unique = true, length = 20)
    private String phoneNumber;

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

    /**
     * 비밀번호 (bcrypt 해시)
     */
    @Column(name = "password_hash", nullable = false, length = 255)
    private String passwordHash;

    /**
     * 사용자 역할 (기본값: OWNER)
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "role", nullable = false, length = 20)
    @Builder.Default
    private UserRole role = UserRole.OWNER;

    /**
     * 계정 상태 (기본값: ACTIVE)
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    @Builder.Default
    private UserStatus status = UserStatus.ACTIVE;

    /**
     * 최종 로그인 일시
     */
    @Column(name = "last_login_at")
    private LocalDateTime lastLoginAt;

    /**
     * 매장 정보 (One-to-One)
     */
    @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    private Store store;

    /**
     * 최종 로그인 시각 업데이트
     */
    public void updateLastLoginAt() {
        this.lastLoginAt = LocalDateTime.now();
    }

    /**
     * 비밀번호 변경
     *
     * @param newPasswordHash 새 비밀번호 해시
     */
    public void changePassword(String newPasswordHash) {
        this.passwordHash = newPasswordHash;
    }

    /**
     * 프로필 정보 수정
     *
     * @param name 이름
     * @param email 이메일
     * @param phoneNumber 전화번호
     */
    public void updateProfile(String name, String email, String phoneNumber) {
        if (name != null) {
            this.name = name;
        }
        if (email != null) {
            this.email = email;
        }
        if (phoneNumber != null) {
            this.phoneNumber = phoneNumber;
        }
    }

    /**
     * 매장 정보 연결
     *
     * @param store 매장 정보
     */
    public void setStore(Store store) {
        this.store = store;
        if (store != null) {
            store.setUser(this);
        }
    }

    /**
     * 사용자 역할 Enum
     */
    public enum UserRole {
        /**
         * 매장 소유주
         */
        OWNER,

        /**
         * 시스템 관리자
         */
        ADMIN
    }

    /**
     * 사용자 계정 상태 Enum
     */
    public enum UserStatus {
        /**
         * 활성 상태
         */
        ACTIVE,

        /**
         * 비활성 상태
         */
        INACTIVE,

        /**
         * 잠금 상태 (보안상 이유)
         */
        LOCKED,

        /**
         * 탈퇴 상태
         */
        WITHDRAWN
    }
}
