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）。
 *
 * <p>SN 由系统签名应用获取，仅作为服务端内部主键使用；对外一律使用高熵、不可枚举的
 * {@code deviceUid}，避免主控端通过猜测 SN 定位并骚扰被控端。
 */
@Entity
@Table(name = "device_account")
public class DeviceAccount {

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

    @Column(name = "sn", length = 64, unique = true, nullable = false)
    private String sn;

    @Column(name = "secret_hash", length = 100, nullable = false)
    private String secretHash;

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

    @Column(name = "provisioned_at", nullable = false)
    private Instant provisionedAt;

    @Enumerated(EnumType.STRING)
    @Column(name = "status", length = 16, nullable = false)
    private AccountStatus status = AccountStatus.ACTIVE;

    /** 封禁到期时间（仅 SUSPENDED 有效），为空表示不自动恢复 */
    @Column(name = "status_until")
    private Instant statusUntil;

    @Column(name = "status_reason", length = 255)
    private String statusReason;

    @Column(name = "token_version", nullable = false)
    private long tokenVersion = 1L;

    @Column(name = "last_online_at")
    private Instant lastOnlineAt;

    protected DeviceAccount() {
        this.deviceUid = null;
        this.sn = null;
        this.secretHash = null;
        this.model = null;
        this.provisionedAt = Instant.now();
    }

    public DeviceAccount(String deviceUid, String sn, String secretHash, String model) {
        this.deviceUid = deviceUid;
        this.sn = sn;
        this.secretHash = secretHash;
        this.model = model;
        this.provisionedAt = Instant.now();
    }

    public String getDeviceUid() { return deviceUid; }
    public String getSn() { return sn; }
    public Instant getProvisionedAt() { return provisionedAt; }

    public String getSecretHash() { return secretHash; }
    public void setSecretHash(String secretHash) { this.secretHash = secretHash; }

    public String getModel() { return model; }
    public void setModel(String model) { this.model = model; }

    public AccountStatus getStatus() { return status; }
    public void setStatus(AccountStatus status) { this.status = status; }

    public Instant getStatusUntil() { return statusUntil; }
    public void setStatusUntil(Instant statusUntil) { this.statusUntil = statusUntil; }

    public String getStatusReason() { return statusReason; }
    public void setStatusReason(String statusReason) { this.statusReason = statusReason; }

    public long getTokenVersion() { return tokenVersion; }
    public void setTokenVersion(long tokenVersion) { this.tokenVersion = tokenVersion; }

    public Instant getLastOnlineAt() { return lastOnlineAt; }
    public void setLastOnlineAt(Instant lastOnlineAt) { this.lastOnlineAt = lastOnlineAt; }

    public boolean isUsable() {
        if (status == AccountStatus.BANNED) {
            return false;
        }
        if (status == AccountStatus.SUSPENDED) {
            return statusUntil != null && Instant.now().isAfter(statusUntil);
        }
        return true;
    }

    /** 日志脱敏：SN 仅展示后 4 位。 */
    public String maskedSn() {
        return maskSn(sn);
    }

    public static String maskSn(String sn) {
        if (sn == null || sn.isEmpty()) {
            return "unknown";
        }
        if (sn.length() <= 4) {
            return "****";
        }
        return "****" + sn.substring(sn.length() - 4);
    }
}
