-- User-device lifecycle and device-initiated unbinding support (MySQL 8+).
CREATE TABLE app_device_binding (
    id                      bigint       NOT NULL,
    device_no               varchar(64)  NOT NULL COMMENT '设备编号',
    user_id                 bigint       NOT NULL COMMENT '用户ID',
    binding_id              varchar(64)  NOT NULL COMMENT '本次绑定标识',
    binding_status          varchar(16)  NOT NULL COMMENT 'BINDING/ACTIVE/BIND_FAILED/UNBINDING/UNBOUND',
    binding_started_time    datetime     NULL COMMENT '本次绑定开始时间',
    last_bind_command_time  datetime     NULL COMMENT '最近一次绑定命令下发时间',
    device_name_snapshot    varchar(255) NULL COMMENT '列表显示名称快照',
    unbound_time            datetime     NULL COMMENT '解绑完成时间',
    unbind_source           varchar(16)  NULL COMMENT 'DEVICE/APP/ADMIN',
    unbind_command_id       varchar(64)  NULL COMMENT '触发解绑的命令编号',
    cleanup_attempts        int          NOT NULL DEFAULT 0 COMMENT '清理尝试次数',
    cleanup_error           varchar(500) NULL COMMENT '最近清理错误',
    create_dept             bigint       NULL,
    create_by               bigint       NULL,
    create_time             datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP,
    update_by               bigint       NULL,
    update_time             datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    exclusive_device_no varchar(64) GENERATED ALWAYS AS (
        CASE WHEN binding_status IN ('BINDING', 'ACTIVE', 'UNBINDING') THEN device_no ELSE NULL END
    ) STORED,
    PRIMARY KEY (id),
    UNIQUE KEY uk_app_device_binding_user_device (user_id, device_no),
    UNIQUE KEY uk_app_device_binding_binding_id (binding_id),
    UNIQUE KEY uk_app_device_binding_exclusive (exclusive_device_no),
    KEY idx_app_device_binding_device_status (device_no, binding_status),
    KEY idx_app_device_binding_recovery (binding_status, binding_started_time, last_bind_command_time)
) COMMENT='用户设备绑定生命周期';

CREATE TABLE app_device_unbind_command (
    id                bigint       NOT NULL,
    device_no         varchar(64)  NOT NULL COMMENT '设备编号',
    command_id        varchar(64)  NOT NULL COMMENT '设备解绑命令编号',
    binding_id        varchar(64)  NOT NULL COMMENT '命令目标绑定标识',
    command_status    varchar(16)  NOT NULL COMMENT 'PROCESSING/APPLIED/STALE/FAILED',
    message           varchar(500) NULL COMMENT '处理结果',
    attempt_count     int          NOT NULL DEFAULT 0 COMMENT '处理次数',
    completed_time    datetime     NULL COMMENT '完成时间',
    create_dept       bigint       NULL,
    create_by         bigint       NULL,
    create_time       datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP,
    update_by         bigint       NULL,
    update_time       datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uk_app_device_unbind_command (device_no, command_id),
    KEY idx_app_device_unbind_binding (device_no, binding_id)
) COMMENT='设备解绑命令处理记录';

-- Existing bindings must re-establish the device-side bindingId before becoming ACTIVE.
INSERT INTO app_device_binding (
    id, device_no, user_id, binding_id, binding_status, device_name_snapshot,
    binding_started_time, cleanup_attempts, create_time, update_time
)
SELECT
    UUID_SHORT(), device_no, user_id, REPLACE(UUID(), '-', ''), 'BINDING', device_name,
    NOW(), 0, NOW(), NOW()
FROM app_device
WHERE user_id IS NOT NULL;

-- Keep the legacy column during the rollout, but remove it as a relationship source.
UPDATE app_device SET user_id = NULL WHERE user_id IS NOT NULL;
