package com.ttstd.signaling.model;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

import java.time.Instant;

/**
 * 登录会话：记录一次登录产生的刷新令牌上下文，支持会话查看、单独踢出与刷新令牌轮转。
 * 同时作为 JPA 实体持久化到 MySQL。
 */
@Entity
@Table(name = "login_session")
public class LoginSession {

    @Id
    @Column(name = "session_id", length = 48, nullable = false)
    private String sessionId;

    @Column(name = "principal_id", length = 64, nullable = false)
    private String principalId;

    @Enumerated(EnumType.STRING)
    @Column(name = "principal_type", length = 16, nullable = false)
    private PrincipalType principalType;

    @Column(name = "created_at", nullable = false)
    private Instant createdAt;

    @Column(name = "ip", length = 64)
    private String ip;

    @Column(name = "user_agent", length = 256)
    private String userAgent;

    /** 当前有效刷新令牌的哈希；轮转后旧值失效 */
    @Column(name = "refresh_token_hash", length = 100, nullable = false)
    private String refreshTokenHash;

    @Column(name = "refresh_expires_at", nullable = false)
    private Instant refreshExpiresAt;

    @Column(name = "last_seen_at", nullable = false)
    private Instant lastSeenAt;

    @Column(name = "revoked", nullable = false)
    private boolean revoked;

    protected LoginSession() {
        this.sessionId = null;
        this.principalId = null;
        this.principalType = null;
        this.refreshTokenHash = null;
        this.refreshExpiresAt = Instant.now();
        this.ip = null;
        this.userAgent = null;
        this.createdAt = Instant.now();
        this.lastSeenAt = this.createdAt;
    }

    public LoginSession(String sessionId,
                        String principalId,
                        PrincipalType principalType,
                        String refreshTokenHash,
                        Instant refreshExpiresAt,
                        String ip,
                        String userAgent) {
        this.sessionId = sessionId;
        this.principalId = principalId;
        this.principalType = principalType;
        this.refreshTokenHash = refreshTokenHash;
        this.refreshExpiresAt = refreshExpiresAt;
        this.ip = ip;
        this.userAgent = userAgent;
        this.createdAt = Instant.now();
        this.lastSeenAt = this.createdAt;
    }

    public String getSessionId() { return sessionId; }
    public String getPrincipalId() { return principalId; }
    public PrincipalType getPrincipalType() { return principalType; }
    public Instant getCreatedAt() { return createdAt; }
    public String getIp() { return ip; }
    public String getUserAgent() { return userAgent; }

    public String getRefreshTokenHash() { return refreshTokenHash; }
    public void setRefreshTokenHash(String refreshTokenHash) { this.refreshTokenHash = refreshTokenHash; }

    public Instant getRefreshExpiresAt() { return refreshExpiresAt; }
    public void setRefreshExpiresAt(Instant refreshExpiresAt) { this.refreshExpiresAt = refreshExpiresAt; }

    public Instant getLastSeenAt() { return lastSeenAt; }
    public void setLastSeenAt(Instant lastSeenAt) { this.lastSeenAt = lastSeenAt; }

    public boolean isRevoked() { return revoked; }
    public void setRevoked(boolean revoked) { this.revoked = revoked; }

    public boolean isActive() {
        return !revoked && refreshExpiresAt != null && Instant.now().isBefore(refreshExpiresAt);
    }
}
