package kr.co.accura.wtm.domain.user.entity;

import jakarta.persistence.*;
import kr.co.accura.wbx.spring.common.BaseEntity;
import kr.co.accura.wtm.domain.user.EmploymentType;
import lombok.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Entity
@Table(name = "users")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User extends BaseEntity {

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

    @Column(name = "employee_id", unique = true, nullable = false, length = 50)
    private String employeeId;

    @Column(unique = true, nullable = false, length = 255)
    private String email;

    @Column(nullable = false, length = 100)
    private String username;

    @Column(name = "full_name", length = 255)
    private String fullName;

    @Column(name = "hashed_password", length = 255)
    private String hashedPassword;

    @Column(length = 100)
    private String department;

    @Column(length = 100)
    private String discipline;

    @Column(name = "position_title", length = 100)
    private String positionTitle;

    @Column(length = 50)
    private String location;

    @Enumerated(EnumType.STRING)
    @Column(name = "employment_type", length = 20)
    @Builder.Default
    private EmploymentType employmentType = EmploymentType.INTERNAL;

    @Column(name = "is_active")
    @Builder.Default
    private Boolean isActive = true;

    @Column(name = "is_locked")
    @Builder.Default
    private Boolean isLocked = false;

    @Column(name = "failed_attempts")
    @Builder.Default
    private Integer failedAttempts = 0;

    @Column(name = "last_login_at")
    private LocalDateTime lastLoginAt;

    @Column(name = "password_changed_at")
    private LocalDateTime passwordChangedAt;

    @Column(name = "azure_oid", length = 255)
    private String azureOid;

    @Column(name = "mfa_enabled")
    @Builder.Default
    private Boolean mfaEnabled = false;

    @OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
    @Builder.Default
    private List<UserRole> userRoles = new ArrayList<>();

    public boolean hasRole(String roleCode) {
        return userRoles.stream()
                .anyMatch(ur -> ur.getRole().getCode().equals(roleCode));
    }

    public boolean hasProjectRole(String roleCode, Long projectId) {
        return userRoles.stream()
                .anyMatch(ur -> ur.getRole().getCode().equals(roleCode)
                        && Objects.equals(ur.getProjectId(), projectId));
    }
}
