package com.ttstd.controlled.utils;

import android.content.Context;

import com.tencent.mmkv.MMKV;

/**
 * 被控端凭据安全存储。
 *
 * 使用「Android Keystore 供给密钥 + 加密 MMKV」替代已废弃的 EncryptedSharedPreferences，
 * 安全性等价（密钥由系统安全区保管，落盘仅为密文），且为同步 API，对调用方零侵入。
 *
 * 兼容性：加密 MMKV 的密钥取自 {@link KeystoreHelper}，其底层为 Android Keystore（minSdk 21+ 支持）。
 * 当 Keystore 不可用时（极端机型/系统异常）降级为「内存持有、不落盘」，避免像旧实现那样
 * 静默退化成明文 SharedPreferences。调用方应通过 {@link #isSecurelyStored()} 感知该状态，
 * 在无法安全存储时要求重新激活而非依赖本地凭据。
 */
public final class DeviceSecretStore {

    private static final String STORE_ID = "ttstd_device_secrets";
    private static final String KEY_DEVICE_UID = "device_uid";
    private static final String KEY_DEVICE_SECRET = "device_secret";
    private static final String KEY_ACCESS_TOKEN = "access_token";
    private static final String KEY_ACTIVATED = "activated";

    private final MMKV mmkv;
    private final boolean securelyStored;

    /** 内存兜底（Keystore 不可用时使用，进程死亡即丢失）。 */
    private String memUid;
    private String memSecret;
    private String memToken;
    private boolean memActivated;

    public DeviceSecretStore(Context context) {
        String cryptKey = KeystoreHelper.getCryptKey();
        this.securelyStored = KeystoreHelper.isKeystoreBacked();
        this.mmkv = MMKV.mmkvWithID(STORE_ID, MMKV.MULTI_PROCESS_MODE,
                cryptKey, MMKV.getRootDir());
    }

    /** Keystore 是否可用（凭据是否真正安全落盘）。 */
    public boolean isSecurelyStored() {
        return securelyStored;
    }

    public void saveDevice(String deviceUid, String deviceSecret) {
        if (securelyStored) {
            mmkv.encode(KEY_DEVICE_UID, deviceUid);
            mmkv.encode(KEY_DEVICE_SECRET, deviceSecret);
            mmkv.encode(KEY_ACTIVATED, true);
        } else {
            memUid = deviceUid;
            memSecret = deviceSecret;
            memActivated = true;
        }
    }

    public void saveAccessToken(String token) {
        if (securelyStored) {
            mmkv.encode(KEY_ACCESS_TOKEN, token);
        } else {
            memToken = token;
        }
    }

    public String getDeviceUid() {
        return securelyStored ? mmkv.decodeString(KEY_DEVICE_UID, null) : memUid;
    }

    public String getDeviceSecret() {
        return securelyStored ? mmkv.decodeString(KEY_DEVICE_SECRET, null) : memSecret;
    }

    public String getAccessToken() {
        return securelyStored ? mmkv.decodeString(KEY_ACCESS_TOKEN, null) : memToken;
    }

    public boolean isActivated() {
        if (securelyStored) {
            return mmkv.decodeBool(KEY_ACTIVATED, false)
                    && mmkv.decodeString(KEY_DEVICE_UID, null) != null
                    && mmkv.decodeString(KEY_DEVICE_SECRET, null) != null;
        }
        return memActivated && memUid != null && memSecret != null;
    }

    public void clear() {
        if (securelyStored) {
            mmkv.clear();
        }
        memUid = null;
        memSecret = null;
        memToken = null;
        memActivated = false;
    }
}
