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;

/**
 * 绑定关系：主控端账号与受控端设备之间的授权连接。
 *
 * <p>只有存在 {@code ACTIVE} 绑定的主控端，才被允许向该设备发起信令（OFFER）。
 * 绑定关系由被控端（设备令牌）或管理员创建，可从 {@code REVOKED} 恢复为 {@code ACTIVE}。
 */
@Entity
@Table(name = "device_binding")
public class DeviceBinding {

    /** 绑定标识（对外 ID，高熵不可枚举） */
    @Id
    @Column(name = "binding_id", length = 48, nullable = false)
    private String bindingId;

    /** 被控端设备 UID */
    @Column(name = "device_uid", length = 48, nullable = false)
    private String deviceUid;

    /** 主控端用户 ID（对应 user_account.user_id） */
    @Column(name = "user_id", length = 48, nullable = false)
    private String userId;

    /** 绑定角色：OWNER（可管理其他绑定）/ MEMBER（仅连接） */
    @Enumerated(EnumType.STRING)
    @Column(name = "role", length = 16, nullable = false)
    private BindingRole role = BindingRole.MEMBER;

    /** 主控端为设备设置的别名 */
    @Column(name = "alias", length = 64)
    private String alias;

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

    /** 创建者（设备 UID 或 admin 标识） */
    @Column(name = "bound_by", length = 64)
    private String boundBy;

    @Column(name = "bound_at", nullable = false)
    private Instant boundAt = Instant.now();

    @Column(name = "expire_at")
    private Instant expireAt;

    protected DeviceBinding() {
    }

    public DeviceBinding(String bindingId, String deviceUid, String userId,
                         BindingRole role, String alias, String boundBy) {
        this.bindingId = bindingId;
        this.deviceUid = deviceUid;
        this.userId = userId;
        this.role = role;
        this.alias = alias;
        this.boundBy = boundBy;
        this.boundAt = Instant.now();
    }

    public String getBindingId() { return bindingId; }
    public String getDeviceUid() { return deviceUid; }
    public String getUserId() { return userId; }

    public BindingRole getRole() { return role; }
    public void setRole(BindingRole role) { this.role = role; }

    public String getAlias() { return alias; }
    public void setAlias(String alias) { this.alias = alias; }

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

    public String getBoundBy() { return boundBy; }
    public void setBoundBy(String boundBy) { this.boundBy = boundBy; }

    public Instant getBoundAt() { return boundAt; }
    public Instant getExpireAt() { return expireAt; }
    public void setExpireAt(Instant expireAt) { this.expireAt = expireAt; }

    public boolean isActive() {
        if (status != BindingStatus.ACTIVE) {
            return false;
        }
        return expireAt == null || Instant.now().isBefore(expireAt);
    }

    public enum BindingRole { OWNER, MEMBER }
    public enum BindingStatus { ACTIVE, REVOKED }
}
