package com.ttstd.controlled.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;

import java.util.UUID;

/**
 * 设备信息工具类
 */
public class DeviceUtils {

    /**
     * 获取设备序列号（适用于系统签名应用）
     * <p>
     * 需要权限: android.permission.READ_PRIVILEGED_PHONE_STATE
     * 注意：普通应用即使有 READ_PHONE_STATE 权限，在 Android 10+ 也无法获取序列号。
     *
     * @return 设备序列号，获取失败可能返回 "unknown"
     */
    @SuppressLint({"MissingPermission", "HardwareIds"})
    public static String getSystemSerialNumber() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            try {
                // 对于系统应用，Build.getSerial() 应该能成功返回真实的硬件序列号
                return Build.getSerial();
            } catch (Exception e) {
                return Build.SERIAL;
            }
        }
        return Build.SERIAL;
    }

    /**
     * 获取设备标识（适用于普通应用）
     * <p>
     * 做了 Android 版本兼容。如果无法获取硬件序列号（如 Android 10+），
     * 则尝试使用 Android ID。如果 Android ID 也获取不到，则通过硬件信息生成 UUID。
     *
     * @param context 上下文
     * @return 设备唯一标识
     */
    @SuppressLint({"MissingPermission", "HardwareIds"})
    public static String getSerialNumber(Context context) {
        String serial = null;
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                // 尝试通过 getSerial 获取，Android 10+ 普通应用通常会抛异常或返回 unknown
                serial = Build.getSerial();
            } else {
                serial = Build.SERIAL;
            }
        } catch (Exception ignored) {
        }

        // 校验序列号是否有效
        if (!TextUtils.isEmpty(serial) && !Build.UNKNOWN.equalsIgnoreCase(serial)) {
            return serial;
        }

        // 尝试获取 Android ID
        String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
        // 排除某些设备上已知的错误 Android ID ("9774d56d682e549c")
        if (!TextUtils.isEmpty(androidId) && !"9774d56d682e549c".equals(androidId)) {
            return androidId;
        }

        // 如果上述方式都失败，则根据硬件机型信息生成 UUID
        return getDeviceUuid();
    }

    /**
     * 使用硬件机型信息生成 UUID
     * 这种方案在设备重启或刷机后通常能保持稳定，但在系统升级导致某些 Build 字段变化时可能会变。
     */
    private static String getDeviceUuid() {
        String devInfo = "35" + // 模拟 IMEI 的前缀
                Build.BOARD.length() % 10 +
                Build.BRAND.length() % 10 +
                Build.SUPPORTED_ABIS[0].length() % 10 +
                Build.DEVICE.length() % 10 +
                Build.DISPLAY.length() % 10 +
                Build.HOST.length() % 10 +
                Build.ID.length() % 10 +
                Build.MANUFACTURER.length() % 10 +
                Build.MODEL.length() % 10 +
                Build.PRODUCT.length() % 10 +
                Build.TAGS.length() % 10 +
                Build.TYPE.length() % 10 +
                Build.USER.length() % 10;

        // 使用 Build.SERIAL 参与 hash，增加独特性（即使它是 "unknown" 也是一种标识）
        return new UUID(devInfo.hashCode(), Build.SERIAL.hashCode()).toString();
    }
}
