content: package com.activecourses.upwork.model;
  
  import jakarta.persistence.*;
  import jakarta.validation.constraints.Email;
  import jakarta.validation.constraints.NotBlank;
  import jakarta.validation.constraints.Size;
  import lombok.AllArgsConstructor;
  import lombok.Builder;
  import lombok.Data;
  import lombok.NoArgsConstructor;
  import org.springframework.data.annotation.CreatedDate;
  import org.springframework.data.annotation.LastModifiedDate;
  import org.springframework.data.jpa.domain.support.AuditingEntityListener;
  import org.springframework.security.core.GrantedAuthority;
  import org.springframework.security.core.authority.SimpleGrantedAuthority;
  import org.springframework.security.core.userdetails.UserDetails;
  
  import java.security.Principal;
  import java.time.LocalDateTime;
  import java.util.Collection;
  import java.util.List;
  import java.util.stream.Collectors;
  
  @Data
  @NoArgsConstructor
  @AllArgsConstructor
  @Entity
  @Builder
  @EntityListeners(AuditingEntityListener.class)
  @Table(name = "users", indexes = {
          @Index(name = "idx_users_email", columnList = "email")
  })
  public class User implements UserDetails, Principal {
  
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Integer id;
  
      @Column(nullable = false)
      @Size(max = 255)
      @NotBlank
      private String firstName;
  
      @Column(nullable = false)
      @Size(max = 255)
      @NotBlank
      private String lastName;
  
      @Column(unique = true, nullable = false)
      @Email
      @NotBlank
      private String email;
  
      @Column(nullable = false)
      @Size(min = 8)
      @NotBlank
      private String password;
  
      @Builder.Default
      private boolean accountLocked = false;
  
      @Builder.Default
      private boolean accountEnabled = true;
  
      private String verificationToken;
  
      @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, optional = true)
      private RefreshToken refreshToken;
      @OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
      private UserProfile userProfile;
      @ManyToMany(fetch = FetchType.EAGER)
      @JoinTable(
              name = "user_roles",
              joinColumns = @JoinColumn(name = "user_id"),
              inverseJoinColumns = @JoinColumn(name = "role_id")
      )
      private List<Role> roles;
  
      @CreatedDate
      @Column(nullable = false, updatable = false)
      private LocalDateTime createdAt;
  
      @LastModifiedDate
      @Column(insertable = false)
      private LocalDateTime lastModifiedAt;
  
      @Override
      public String getName() {
          return email;
      }
  
      @Override
      public Collection<? extends GrantedAuthority> getAuthorities() {
          return roles.stream()
                  .map(role -> new SimpleGrantedAuthority(role.getName()))
                  .collect(Collectors.toList());
      }
  
      @Override
      public String getUsername() {
          return email;
      }
  
      @Override
      public String getPassword() {
          return password;
      }
  
      @Override
      public boolean isAccountNonExpired() {
          return !accountLocked;
      }
  
      @Override
      public boolean isAccountNonLocked() {
          return !accountLocked;
      }
  
      @Override
      public boolean isCredentialsNonExpired() {
          return !accountLocked;
      }
  
      @Override
      public boolean isEnabled() {
          return accountEnabled;
      }
  
  
  }
  