package com.xyzshell.andinfo.libs

import android.app.ActivityManager
import android.content.Context
import android.os.Build
import android.provider.Settings
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

 // 设备信息工具类
class DeviceInfo(private val context: Context) {

    // ActivityManager 用于获取内存等系统服务
    private val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager

    // 设备代号
    val device: String
        get() = Build.DEVICE

    // 品牌
    val brand: String
        get() = Build.BRAND

    // 机型
    val model: String
        get() = Build.MODEL

    // 制造商
    val manufacturer: String
        get() = Build.MANUFACTURER

    // 产品名称
    val productName: String
        get() = Build.PRODUCT

    // 硬件名称
    val hardwareName: String
        get() = Build.HARDWARE

    // 主板名称
    val boardName: String
        get() = Build.BOARD

    // 硬件SKU（Android 12及以上）
    val hardwareSku: String?
        get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SKU else null

    // ODM SKU（Android 12及以上）
    val odmSku: String?
        get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.ODM_SKU else null

    // SoC制造商（Android 12及以上）
    val socManufacturer: String?
        get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SOC_MANUFACTURER else null

    // SoC型号（Android 12及以上）
    val socModel: String?
        get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SOC_MODEL else null

    /**
     * 获取内存信息
     * @return ActivityManager.MemoryInfo 内存信息对象
     */
    fun getMemoryInfo(): ActivityManager.MemoryInfo {
        val memoryInfo = ActivityManager.MemoryInfo()
        activityManager.getMemoryInfo(memoryInfo)
        return memoryInfo
    }

    // ==================== 设备标识符 ====================

    /**
     * 获取 Android ID (Device ID)
     * 64位十六进制字符串，设备首次启动时随机生成
     *
     * 注意事项：
     * - 出厂重置后会改变
     * - Android 8.0+ 后，每个应用和用户组合都会获得不同的 Android ID
     * - 不需要特殊权限
     *
     * @return Android ID，如果获取失败则返回 "unknown"
     */
    @Suppress("HardwareIds")
    fun getAndroidId(): String {
        return try {
            Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID) ?: "unknown"
        } catch (e: Exception) {
            "unknown"
        }
    }

    /**
     * 获取 Google Advertising ID (GAID)
     * 用于广告追踪的匿名标识符
     *
     * 注意事项：
     * - 需要 Google Play Services
     * - 用户可以重置此 ID
     * - 用户可以选择限制广告追踪
     * - 必须在后台线程调用
     * - 需要添加依赖: com.google.android.gms:play-services-ads-identifier
     *
     * 使用示例：
     * ```kotlin
     * lifecycleScope.launch {
     *     val gaidInfo = deviceInfo.getAdvertisingId()
     *     if (gaidInfo != null) {
     *         println("GAID: ${gaidInfo.id}")
     *         println("是否限制追踪: ${gaidInfo.isLimitAdTrackingEnabled}")
     *     }
     * }
     * ```
     *
     * @return AdvertisingIdInfo 对象，包含 GAID 和追踪限制状态；如果获取失败则返回 null
     */
    suspend fun getAdvertisingId(): AdvertisingIdInfo? = withContext(Dispatchers.IO) {
        try {
            // 使用反射调用 AdvertisingIdClient，避免强制依赖
            val advertisingIdClientClass = Class.forName("com.google.android.gms.ads.identifier.AdvertisingIdClient")
            val getAdvertisingIdInfoMethod = advertisingIdClientClass.getMethod("getAdvertisingIdInfo", Context::class.java)
            val adInfo = getAdvertisingIdInfoMethod.invoke(null, context)

            // 获取 ID 和追踪限制状态
            val getId = adInfo.javaClass.getMethod("getId")
            val isLimitAdTrackingEnabled = adInfo.javaClass.getMethod("isLimitAdTrackingEnabled")

            val id = getId.invoke(adInfo) as? String
            val isLimited = isLimitAdTrackingEnabled.invoke(adInfo) as? Boolean ?: false

            if (id != null) {
                AdvertisingIdInfo(id, isLimited)
            } else {
                null
            }
        } catch (e: Exception) {
            // Google Play Services 不可用或其他错误
            null
        }
    }

    /**
     * 同步获取 GAID（不推荐，可能阻塞线程）
     * 仅用于特殊场景，建议使用 getAdvertisingId() 的协程版本
     *
     * @return AdvertisingIdInfo 对象或 null
     */
    fun getAdvertisingIdSync(): AdvertisingIdInfo? {
        return try {
            val advertisingIdClientClass = Class.forName("com.google.android.gms.ads.identifier.AdvertisingIdClient")
            val getAdvertisingIdInfoMethod = advertisingIdClientClass.getMethod("getAdvertisingIdInfo", Context::class.java)
            val adInfo = getAdvertisingIdInfoMethod.invoke(null, context)

            val getId = adInfo.javaClass.getMethod("getId")
            val isLimitAdTrackingEnabled = adInfo.javaClass.getMethod("isLimitAdTrackingEnabled")

            val id = getId.invoke(adInfo) as? String
            val isLimited = isLimitAdTrackingEnabled.invoke(adInfo) as? Boolean ?: false

            if (id != null) {
                AdvertisingIdInfo(id, isLimited)
            } else {
                null
            }
        } catch (e: Exception) {
            null
        }
    }

    /**
     * 广告标识符信息数据类
     *
     * @property id Google Advertising ID (GAID)
     * @property isLimitAdTrackingEnabled 用户是否限制广告追踪
     */
    data class AdvertisingIdInfo(
        val id: String,                        // GAID，示例: "38400000-8cf0-11bd-b23e-10b96e40000d"
        val isLimitAdTrackingEnabled: Boolean  // 是否限制广告追踪
    )

    /**
     * 获取所有可用的设备标识符
     *
     * @return DeviceIdentifiers 对象，包含所有标识符
     */
    suspend fun getDeviceIdentifiers(): DeviceIdentifiers {
        return DeviceIdentifiers(
            androidId = getAndroidId(),
            advertisingId = getAdvertisingId()
        )
    }

    /**
     * 设备标识符集合数据类
     *
     * @property androidId Android ID (设备标识符)
     * @property advertisingId 广告标识符信息（可能为 null）
     */
    data class DeviceIdentifiers(
        val androidId: String,                    // Android ID
        val advertisingId: AdvertisingIdInfo?     // 广告标识符（如果可用）
    )
}
