/* (C) 2022 YiRing, Inc. */
package com.yiring.auth.domain.user;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.yiring.auth.domain.role.Role;
import com.yiring.common.domain.BasicEntity;
import jakarta.persistence.*;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import lombok.*;
import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants;
import lombok.experimental.SuperBuilder;
import org.hibernate.annotations.Comment;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLRestriction;
import org.hibernate.proxy.HibernateProxy;

/**
 * 用户
 *
 * @author ifzm
 * 2018/9/3 15:27
 */

@Getter
@Setter
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
@FieldNameConstants
@FieldDefaults(level = AccessLevel.PRIVATE)
@SQLDelete(sql = User.DELETE_SQL + BasicEntity.Where.WHERE_ID)
//@SQLDeleteAll(sql = Permission.DELETE_SQL)
@SQLRestriction(BasicEntity.Where.EXIST)
@Entity
@Table(
    name = User.TABLE_NAME,
    indexes = { @Index(columnList = User.Fields.disabled), @Index(columnList = BasicEntity.Fields.deleted) },
    uniqueConstraints = {
        @UniqueConstraint(columnNames = { User.Fields.username, BasicEntity.Fields.deleted }),
        @UniqueConstraint(columnNames = { User.Fields.mobile, BasicEntity.Fields.deleted }),
        @UniqueConstraint(columnNames = { User.Fields.email, BasicEntity.Fields.deleted }),
    }
)
@Comment("系统用户")
public class User extends BasicEntity implements Serializable {

    public static final String TABLE_NAME = "SYS_USER";
    public static final String DELETE_SQL = "update " + TABLE_NAME + BasicEntity.Where.DELETE_SET;

    @Serial
    private static final long serialVersionUID = -5787847701210907511L;

    @Comment("头像")
    String avatar;

    @Comment("真实姓名")
    String realName;

    @Comment("用户名")
    String username;

    @Comment("手机号")
    String mobile;

    @Comment("邮箱")
    String email;

    @Comment("密码")
    String password;

    @Comment("是否禁用")
    Boolean disabled;

    @JsonIgnore
    @Builder.Default
    @Comment("角色集合")
    @ManyToMany
    @JoinTable(
        name = "SYS_USER_ROLES",
        joinColumns = @JoinColumn(name = "user_id"),
        inverseJoinColumns = @JoinColumn(name = "role_id")
    )
    Set<Role> roles = new HashSet<>(0);

    @Comment("最后登录IP地址")
    String lastLoginIp;

    @Comment("最后登录时间")
    LocalDateTime lastLoginTime;

    @Override
    public final boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null) {
            return false;
        }
        Class<?> oEffectiveClass = o instanceof HibernateProxy
            ? ((HibernateProxy) o).getHibernateLazyInitializer().getPersistentClass()
            : o.getClass();
        Class<?> thisEffectiveClass = this instanceof HibernateProxy
            ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass()
            : this.getClass();
        if (thisEffectiveClass != oEffectiveClass) {
            return false;
        }
        User user = (User) o;
        return getId() != null && Objects.equals(getId(), user.getId());
    }

    @Override
    public final int hashCode() {
        return this instanceof HibernateProxy
            ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode()
            : getClass().hashCode();
    }
}
