package com.eactive.httpmockserver.user.entity;

import com.eactive.httpmockserver.common.entity.Auditable;
import com.eactive.httpmockserver.common.entity.EnabledStatus;
import org.hibernate.annotations.Type;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collection;

@MappedSuperclass
public abstract class User extends Auditable implements Serializable, UserDetails {
    private static final long serialVersionUID = 1L;

    /**
     * 고유ID
     */
    @Id
    @Column(name = "ESNTL_ID", nullable = false, updatable = false)
    private String esntlId;

    /**
     * 잠금여부
     */
    @Column(name = "LOCK_AT")
    @Enumerated(EnumType.STRING)
    private EnabledStatus lockAt;

    /**
     * 잠금회수
     */
    @Column(name = "LOCK_CNT")
    private Integer lockCnt;

    /**
     * 잠금최종시점
     */
    @Column(name = "LAST_LOCK_DATE")
    @Type(type = "org.hibernate.type.LocalDateTimeType")
    private LocalDateTime lastLockDate;

    @Column(name = "LAST_CHANGE_PASSWORD_DATE")
    @Type(type = "org.hibernate.type.LocalDateTimeType")
    private LocalDateTime lastPasswordChangeDate;

    @Transient
    private String ip;

    @Column(name = "USER_SECURITY")
    private String userSecurity;

    public String getEsntlId() {
        return esntlId;
    }

    public void setEsntlId(String esntlId) {
        this.esntlId = esntlId;
    }

    public abstract void setUserId(String userId);

    public abstract String getUserId();

    public abstract String getMobilePhone();

    public abstract String getUserSe();

    public abstract UserStatus getStatus();

    public abstract void setStatus(UserStatus status);

    public abstract String getPasswordHint();

    public abstract String getPasswordCnsr();

    public abstract void setPassword(String password);

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public EnabledStatus getLockAt() {
        return lockAt;
    }

    public void setLockAt(EnabledStatus lockAt) {
        this.lockAt = lockAt;
    }

    public Integer getLockCnt() {
        return lockCnt;
    }

    public void setLockCnt(Integer lockCnt) {
        this.lockCnt = lockCnt;
    }

    public LocalDateTime getLastLockDate() {
        return lastLockDate;
    }

    public void setLastLockDate(LocalDateTime lockLastPnttm) {
        this.lastLockDate = lockLastPnttm;
    }

    public LocalDateTime getLastPasswordChangeDate() {
        return lastPasswordChangeDate;
    }

    public void setLastPasswordChangeDate(LocalDateTime lastPasswordChangeDate) {
        this.lastPasswordChangeDate = lastPasswordChangeDate;
    }

    @Override
    @Transient
    public Collection<? extends GrantedAuthority> getAuthorities() {
        if (userSecurity != null) {
            return Arrays.asList(new SimpleGrantedAuthority(this.userSecurity));
        } else {
            return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
        }
    }

    @Override
    @Transient
    public boolean isAccountNonExpired() {
        return getStatus().equals(UserStatus.ACTIVE);
    }

    @Override
    @Transient
    public boolean isAccountNonLocked() {
        return getLockAt().equals(EnabledStatus.N);
    }

    @Override
    @Transient
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    @Transient
    public boolean isEnabled() {
        return getStatus().equals(UserStatus.ACTIVE);
    }

    public String getUserSecurity() {
        return userSecurity;
    }

    public void setUserSecurity(String userSecurity) {
        this.userSecurity = userSecurity;
    }
}
