package com.xyzshell.andinfo.collector

import android.content.Context
import android.os.Build
import com.google.gson.Gson
import com.xyzshell.andinfo.AndInfo
import com.xyzshell.andinfo.models.ApiResponse
import com.xyzshell.andinfo.models.DeviceInfoRequest
import com.xyzshell.andinfo.models.EncryptedRequest
import com.xyzshell.andinfo.utils.WebService
import com.xyzshell.andinfo.utils.upload_info_api
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.withContext
import kotlinx.coroutines.coroutineScope

/**
 * 设备信息收集器
 * 负责异步收集所有设备信息并上传到服务器
 */
class DeviceInfoCollector(private val context: Context) {

    private val webService = WebService()
    private val gson = Gson()

    /**
     * 收集所有设备信息
     * 异步并发收集各类信息以提高性能
     *
     * @return DeviceInfoRequest 包含所有设备信息的数据对象
     */
    suspend fun collectAllInfo(): DeviceInfoRequest = coroutineScope {
        // 并发收集所有信息以提高性能
        val cpuInfoDeferred = async { collectCpuInfo() }
        val gpuInfoDeferred = async { collectGpuInfo() }
        val screenInfoDeferred = async { collectScreenInfo() }
        val memoryInfoDeferred = async { collectMemoryInfo() }
        val diskInfoDeferred = async { collectDiskInfo() }
        val networkInfoDeferred = async { collectNetworkInfo() }
        val batteryInfoDeferred = async { collectBatteryInfo() }
        val deviceInfoDeferred = async { collectDeviceInfo() }
        val appInfoDeferred = async { collectAppInfo() }
        val systemInfoDeferred = async { collectSystemInfo() }
        val locationInfoDeferred = async { collectLocationInfo() }
        val cameraInfoDeferred = async { collectCameraInfo() }
        val sensorInfoDeferred = async { collectSensorInfo() }
        val propsInfoDeferred = async { collectPropsInfo() }
        val bluetoothInfoDeferred = async { collectBluetoothInfo() }
        val wifiInfoDeferred = async { collectWifiInfo() }
        val nfcInfoDeferred = async { collectNfcInfo() }
        val usbInfoDeferred = async { collectUsbInfo() }
        val buildInfoDeferred = async { collectBuildInfo() }
        val drmInfoDeferred = async { collectDrmInfo() }
        val inputInfoDeferred = async { collectInputInfo() }
        val identifiersDeferred = async { collectIdentifiers() }

        // 等待所有信息收集完成
        val identifiers = identifiersDeferred.await()

        DeviceInfoRequest(
            cpuInfo = cpuInfoDeferred.await(),
            gpuInfo = gpuInfoDeferred.await(),
            screenInfo = screenInfoDeferred.await(),
            memoryInfo = memoryInfoDeferred.await(),
            diskInfo = diskInfoDeferred.await(),
            networkInfo = networkInfoDeferred.await(),
            batteryInfo = batteryInfoDeferred.await(),
            deviceInfo = deviceInfoDeferred.await(),
            appInfo = appInfoDeferred.await(),
            systemInfo = systemInfoDeferred.await(),
            locationInfo = locationInfoDeferred.await(),
            cameraInfo = cameraInfoDeferred.await(),
            sensorInfo = sensorInfoDeferred.await(),
            propsInfo = propsInfoDeferred.await(),
            bluetoothInfo = bluetoothInfoDeferred.await(),
            wifiInfo = wifiInfoDeferred.await(),
            nfcInfo = nfcInfoDeferred.await(),
            usbInfo = usbInfoDeferred.await(),
            buildInfo = buildInfoDeferred.await(),
            deviceId = identifiers.first,
            deviceName = identifiers.second,
            drmInfo = drmInfoDeferred.await(),
            inputInfo = inputInfoDeferred.await(),
            gaid = identifiers.third
        )
    }

    /**
     * 收集并上传设备信息到服务器
     *
     * @param callback 上传结果回调 (成功消息, 错误异常)
     */
    suspend fun collectAndUpload(callback: (String?, Exception?) -> Unit) {
        try {
            // 1. 收集所有信息
            val deviceInfo = collectAllInfo()

            // 2. 序列化为 JSON
            val jsonData = gson.toJson(deviceInfo)

            // 3. AES 加密
            val encrypted = withContext(Dispatchers.Default) {
                webService.encrypt(jsonData)
            }

            // 4. 构建加密请求
            val encryptedRequest = EncryptedRequest(encrypted)
            val requestJson = gson.toJson(encryptedRequest)

            // 5. 发送 POST 请求
            withContext(Dispatchers.IO) {
                webService.postData(upload_info_api, requestJson) { response, error ->
                    if (error != null) {
                        callback(null, error)
                    } else if (response != null) {
                        try {
                            val apiResponse = gson.fromJson(response, ApiResponse::class.java)
                            if (apiResponse.isSuccess()) {
                                callback(apiResponse.message, null)
                            } else {
                                callback(null, Exception("上传失败: ${apiResponse.message}"))
                            }
                        } catch (e: Exception) {
                            callback(null, Exception("解析响应失败: ${e.message}"))
                        }
                    } else {
                        callback(null, Exception("响应为空"))
                    }
                }
            }
        } catch (e: Exception) {
            callback(null, Exception("收集信息失败: ${e.message}"))
        }
    }

    /**
     * 收集 CPU 信息
     */
    private suspend fun collectCpuInfo(): String = withContext(Dispatchers.Default) {
        try {
            val cpuInfo = AndInfo.instance.cpu
            gson.toJson(mapOf<String, Any?>(
                "cores" to cpuInfo.cores.size,
                "processors" to cpuInfo.processors.size,
                "cpuAbi" to Build.SUPPORTED_ABIS.firstOrNull()
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集 GPU 信息
     */
    private suspend fun collectGpuInfo(): String = withContext(Dispatchers.Default) {
        try {
            val gpuInfo = AndInfo.instance.gpu
            gson.toJson(mapOf<String, Any?>(
                "vendor" to gpuInfo.getVendorName(),
                "renderer" to gpuInfo.getRendererName(),
                "vulkanSupported" to gpuInfo.isVulkanSupported(),
                "vulkanVersion" to gpuInfo.getVulkanApiVersion(),
                "openglVersion" to gpuInfo.getOpenGLVersion(),
                "openglExtensionCount" to gpuInfo.getOpenGLExtensionCount(),
                "eglVersion" to gpuInfo.getEglVersion()
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集磁盘信息 (phone.hardware_new 相关字段)
     */
    private suspend fun collectDiskInfo(): String = withContext(Dispatchers.Default) {
        try {
            val storageInfo = AndInfo.instance.storage

            // 计算存储空间 GB
            val totalStorageGB = String.format(java.util.Locale.US, "%.2f", storageInfo.internalStorageTotalSpace / (1024.0 * 1024.0 * 1024.0))
            val usedStorageGB = String.format(java.util.Locale.US, "%.2f", storageInfo.internalStorageUsedSpace / (1024.0 * 1024.0 * 1024.0))
            val freeStorageGB = String.format(java.util.Locale.US, "%.2f", storageInfo.internalStorageAvailableSpace / (1024.0 * 1024.0 * 1024.0))

            gson.toJson(mapOf<String, Any?>(
                // 内部存储（字节）
                "totalSpace" to storageInfo.internalStorageTotalSpace,
                "freeSpace" to storageInfo.internalStorageAvailableSpace,
                "usedSpace" to storageInfo.internalStorageUsedSpace,

                // GB 单位
                "totalStorageGB" to totalStorageGB,
                "usedStorageGB" to usedStorageGB,
                "freeStorageGB" to freeStorageGB,

                // 数据目录 (/data)
                "dataDirTotalSpace" to storageInfo.dataDirectoryTotalSpace,
                "dataDirUsedSpace" to storageInfo.dataDirectoryUsedSpace,

                // 文件系统类型
                "fileSystemType" to storageInfo.internalStorageFileSystemType
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集屏幕信息 (phone.hardware_new 相关字段)
     */
    private suspend fun collectScreenInfo(): String = withContext(Dispatchers.Default) {
        try {
            val displayInfo = AndInfo.instance.display.getDefaultDisplayInfo()
            gson.toJson(mapOf<String, Any?>(
                // 分辨率
                "maxWidthPixels" to (displayInfo?.widthPixels ?: -1),
                "maxHeightPixels" to (displayInfo?.heightPixels ?: -1),

                // DPI 和 PPI
                "dpi" to (displayInfo?.densityDpi ?: -1),
                "ppi" to (displayInfo?.ppi ?: -1),



                // 刷新率
                "maxRefreshRate" to (displayInfo?.refreshRate ?: -1),
                "supportedRefreshRates" to (displayInfo?.supportedRefreshRates ?: emptyList<Float>()),

                // HDR 支持
                "isHdr" to (displayInfo?.isHdr ?: false),
                "hdrTypes" to (displayInfo?.hdrTypes ?: emptyList<String>()),

                // 广色域
                "isWideColorGamut" to (displayInfo?.isWideColorGamut ?: false)
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集内存信息 (phone.hardware_new 相关字段)
     */
    private suspend fun collectMemoryInfo(): String = withContext(Dispatchers.Default) {
        try {
            val deviceInfo = AndInfo.instance.device
            val memoryInfo = AndInfo.instance.memory.getMemoryInfo()
            val mem = deviceInfo.getMemoryInfo()

            // 计算总内存 GB
            val totalMemoryGB = String.format(java.util.Locale.US, "%.2f", memoryInfo.totalRam / (1024.0 * 1024.0 * 1024.0))
            val availMemoryGB = String.format(java.util.Locale.US, "%.2f", memoryInfo.availableRam / (1024.0 * 1024.0 * 1024.0))

            gson.toJson(mapOf<String, Any?>(
                // 原始字节数
                "totalMem" to memoryInfo.totalRam,
                "availMem" to memoryInfo.availableRam,

                // GB 单位
                "totalMemoryGB" to totalMemoryGB,
                "availMemoryGB" to availMemoryGB,

                // RAM 类型（需要从系统属性推测）
                "ramType" to memoryInfo.memType,

                // 内存状态
                "lowMemory" to mem.lowMemory,
                "threshold" to mem.threshold
            ))
        } catch (_: Exception) {
            "{}"
        }
    }



    /**
     * 收集网络信息 (phone.hardware_new 相关字段)
     */
    private suspend fun collectNetworkInfo(): String = withContext(Dispatchers.Default) {
        try {
            val inputInfo = AndInfo.instance.input
            val bluetoothInfo = AndInfo.instance.bluetooth

            gson.toJson(mapOf<String, Any?>(
                // SIM 卡相关
                "simSlotCount" to getSimSlotCount(),
                "supportEsim" to isEsimSupported(),

                // 网络类型（5G/4G/3G）
                "cellularGen" to getCellularGeneration(),

                // WiFi 版本
                "maxWifiVersion" to getMaxWifiVersion(),

                // 蓝牙版本
                "bluetoothVersion" to bluetoothInfo.getBluetoothVersion(),

                // NFC 支持
                "hasNFC" to inputInfo.hasNfcSupport()
            ))
        } catch (_: Exception) {
            "{}"
        }
    }


    /**
     * 获取 SIM 卡槽数量
     */
    private fun getSimSlotCount(): Int {
        return try {
            val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as? android.telephony.TelephonyManager
            telephonyManager?.phoneCount ?: 0
        } catch (_: Exception) {
            0
        }
    }

    /**
     * 检测是否支持 eSIM
     */
    @android.annotation.SuppressLint("MissingPermission")
    private fun isEsimSupported(): Boolean {
        return try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as? android.telephony.TelephonyManager
                telephonyManager?.let {
                    it.isMultiSimSupported == android.telephony.TelephonyManager.MULTISIM_ALLOWED &&
                    context.packageManager.hasSystemFeature(android.content.pm.PackageManager.FEATURE_TELEPHONY_EUICC)
                } ?: false
            } else {
                false
            }
        } catch (_: Exception) {
            false
        }
    }

    /**
     * 获取最大蜂窝网络代数 (3/4/5)
     */
    private fun getCellularGeneration(): Int {
        return try {
            // 检查是否支持5G
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                if (context.packageManager.hasSystemFeature("android.hardware.telephony.5g")) {
                    return 5
                }
            }
            // 检查4G LTE
            if (context.packageManager.hasSystemFeature(android.content.pm.PackageManager.FEATURE_TELEPHONY_GSM)) {
                return 4
            }
            3 // 默认3G
        } catch (_: Exception) {
            4 // 默认返回4G
        }
    }

    /**
     * 获取最大 WiFi 版本
     * 8=WiFi 7, 7=WiFi 6E, 6=WiFi 6, 5=WiFi 5
     */
    private fun getMaxWifiVersion(): Int {
        return try {
            when {
                Build.VERSION.SDK_INT >= 34 && context.packageManager.hasSystemFeature("android.hardware.wifi.wifi7") -> 8 // WiFi 7
                Build.VERSION.SDK_INT >= 31 && context.packageManager.hasSystemFeature("android.hardware.wifi.wifi6e") -> 7 // WiFi 6E
                Build.VERSION.SDK_INT >= 30 && context.packageManager.hasSystemFeature("android.hardware.wifi.wifi6") -> 6 // WiFi 6
                context.packageManager.hasSystemFeature("android.hardware.wifi.wifi5") -> 5 // WiFi 5
                else -> 4 // WiFi 4 (802.11n)
            }
        } catch (_: Exception) {
            5 // 默认 WiFi 5
        }
    }

    /**
     * 收集电池信息 (phone.hardware_new 相关字段)
     */
    private suspend fun collectBatteryInfo(): String = withContext(Dispatchers.Default) {
        try {
            val batteryInfo = AndInfo.instance.battery
            val details = batteryInfo.getBatteryDetails()

            gson.toJson(mapOf<String, Any?>(
                // 电池状态
                "level" to details.percentage,
                "health" to details.health,
                "temperature" to details.temperature,
                "voltage" to details.voltage,
                "status" to details.status,

                // 电池容量（毫安时）
                "batteryDesignCapacity" to details.capacity,
                "batteryCurrentCapacity" to details.chargeCounter,

                // 充电相关
                "isCharging" to details.isCharging,
                "plugType" to details.plugType,

                // 无线充电支持（需要检测）
                "batteryWirelessSupported" to batteryInfo.isWirelessChargingSupported()
            ))
        } catch (_: Exception) {
            "{}"
        }
    }



    /**
     * 收集设备信息 (phone.hardware_new 表字段)
     */
    private suspend fun collectDeviceInfo(): String = withContext(Dispatchers.Default) {
        try {
            val deviceInfo = AndInfo.instance.device
            val buildInfo = AndInfo.instance.build
            gson.toJson(mapOf<String, Any?>(
                // 基本信息
                "brand" to deviceInfo.brand,
                "model" to deviceInfo.model,
                "manufacturer" to deviceInfo.manufacturer,
                "device" to buildInfo.device,

                // 硬件信息
                "hardware" to deviceInfo.hardwareName,
                "board" to deviceInfo.boardName,

                // 设备类型
                "formFactor" to buildInfo.formFactor,
                "isTablet" to buildInfo.isTablet,
                "isPhone" to buildInfo.isPhone,

                // 架构信息
                "linuxArchitecture" to buildInfo.kernelArchitecture,

                // SoC 信息
                "socManufacturer" to deviceInfo.socManufacturer,
                "socModel" to deviceInfo.socModel,

                // SKU 信息
                "sku" to deviceInfo.hardwareSku,
                "odmSku" to deviceInfo.odmSku
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集应用信息
     */
    private suspend fun collectAppInfo(): String = withContext(Dispatchers.Default) {
        try {
            gson.toJson(mapOf<String, Any?>(
                "packageName" to context.packageName,
                "versionName" to context.packageManager.getPackageInfo(context.packageName, 0).versionName
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集系统信息
     */
    private suspend fun collectSystemInfo(): String = withContext(Dispatchers.Default) {
        try {
            val buildInfo = AndInfo.instance.build
            gson.toJson(mapOf<String, Any?>(
                "androidVersion" to buildInfo.versionRelease,
                "sdkInt" to buildInfo.versionSdkInt,
                "securityPatch" to buildInfo.securityPatch
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集定位信息
     */
    private suspend fun collectLocationInfo(): String = withContext(Dispatchers.Default) {
        try {
            val inputInfo = AndInfo.instance.input
            gson.toJson(mapOf<String, Any?>(
                "gpsSupported" to inputInfo.hasGpsSupport(),
                "networkLocationSupported" to inputInfo.hasNetworkLocationSupport()
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集相机信息
     */
    private suspend fun collectCameraInfo(): String = withContext(Dispatchers.Default) {
        try {
            val cameraInfo = AndInfo.instance.camera
            val cameraIdList = cameraInfo.cameraIds
            val cameraList = cameraIdList.mapNotNull { cameraInfo.getCameraDetails(it) }
            gson.toJson(mapOf<String, Any?>(
                "cameraCount" to cameraList.size,
                "cameras" to cameraList.map { it.cameraId }
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集传感器信息
     */
    private suspend fun collectSensorInfo(): String = withContext(Dispatchers.Default) {
        try {
            val sensorInfo = AndInfo.instance.sensor
            val sensors = sensorInfo.getAllSensors()
            gson.toJson(mapOf<String, Any?>(
                "sensorCount" to sensors.size,
                "sensorTypes" to sensors.map { it.stringType }
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集系统属性信息
     */
    private suspend fun collectPropsInfo(): String = withContext(Dispatchers.Default) {
        try {
            val buildInfo = AndInfo.instance.build
            gson.toJson(mapOf<String, Any?>(
                "fingerprint" to buildInfo.fingerprint,
                "display" to buildInfo.display,
                "id" to buildInfo.id
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集蓝牙信息
     */
    private suspend fun collectBluetoothInfo(): String = withContext(Dispatchers.Default) {
        try {
            val bluetoothInfo = AndInfo.instance.bluetooth
            gson.toJson(mapOf<String, Any?>(
                "supported" to bluetoothInfo.isBluetoothLeSupported,
                "enabled" to bluetoothInfo.isEnabled,
                "name" to bluetoothInfo.adapterName
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集 WiFi 信息
     */
    private suspend fun collectWifiInfo(): String = withContext(Dispatchers.Default) {
        try {
            gson.toJson(mapOf<String, Any?>(
                "supported" to true
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集 NFC 信息
     */
    private suspend fun collectNfcInfo(): String = withContext(Dispatchers.Default) {
        try {
            val inputInfo = AndInfo.instance.input
            gson.toJson(mapOf<String, Any?>(
                "supported" to inputInfo.hasNfcSupport(),
                "hceSupported" to inputInfo.hasNfcHostCardEmulation(),
                "secureNfc" to inputInfo.hasSecureNfcSupport()
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集 USB 信息
     */
    private suspend fun collectUsbInfo(): String = withContext(Dispatchers.Default) {
        try {
            val inputInfo = AndInfo.instance.input
            gson.toJson(mapOf<String, Any?>(
                "hostSupported" to inputInfo.hasUsbHostSupport(),
                "accessorySupported" to inputInfo.hasUsbAccessorySupport()
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集构建信息 (phone.build 表字段)
     */
    private suspend fun collectBuildInfo(): String = withContext(Dispatchers.Default) {
        try {
            val buildInfo = AndInfo.instance.build
            gson.toJson(mapOf<String, Any?>(
                // 基本信息
                "brand" to buildInfo.brand,
                "model" to buildInfo.model,
                "device" to buildInfo.device,
                "product" to buildInfo.product,

                // SDK 和版本信息
                "sdkInt" to buildInfo.versionSdkInt,
                "androidVersion" to buildInfo.versionRelease,

                // 构建信息
                "buildId" to buildInfo.id,
                "bootloader" to buildInfo.bootloaderVersion,
                "display" to buildInfo.display,
                "buildUser" to buildInfo.user,
                "incremental" to buildInfo.incremental,
                "buildHost" to buildInfo.host,
                "buildFingerprint" to buildInfo.fingerprint,

                // RIL 和 CSC 信息（三星专用）
                "rilProductCode" to buildInfo.rilProductCode,
                "rilOfficialCscver" to buildInfo.rilOfficialCscver,
                "cscSalesCode" to buildInfo.cscSalesCode,
                "countryISO" to buildInfo.countryISO,

                // 内核和安全信息
                "kernelVersion" to buildInfo.kernelVersion,
                "securityPatch" to buildInfo.securityPatch,
                "releaseDate" to buildInfo.buildDate.time,

                // Treble 和系统更新
                "trebleEnabled" to buildInfo.isTrebleEnabled,
                "trebleVersion" to buildInfo.trebleVersion,
                "seamlessUpdate" to buildInfo.isSeamlessUpdateSupported,
                "currentSlot" to buildInfo.currentSlot,

                // Root 和安全
                "isRooted" to buildInfo.isRooted,
                "seLinuxStatus" to buildInfo.seLinuxStatus
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集 DRM 信息
     */
    private suspend fun collectDrmInfo(): String = withContext(Dispatchers.Default) {
        try {
            val drmInfo = AndInfo.instance.drm
            val drmSchemes = drmInfo.getSupportedDrmSchemes()
            gson.toJson(mapOf<String, Any?>(
                "supportedSchemes" to drmSchemes.size,
                "schemes" to drmSchemes.map { it.toString() }
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集输入设备信息
     */
    private suspend fun collectInputInfo(): String = withContext(Dispatchers.Default) {
        try {
            val inputInfo = AndInfo.instance.input
            val devices = inputInfo.getInputDevices()
            gson.toJson(mapOf<String, Any?>(
                "deviceCount" to devices.size,
                "hasFingerprint" to inputInfo.hasFingerprintSensor(),
                "hasInfrared" to inputInfo.hasInfraredSensor(),
                "hasUwb" to inputInfo.hasUwbSupport()
            ))
        } catch (_: Exception) {
            "{}"
        }
    }

    /**
     * 收集设备标识符（Device ID 和 GAID）
     *
     * @return Triple<DeviceId, DeviceName, GAID>
     */
    private suspend fun collectIdentifiers(): Triple<String, String, String> = withContext(Dispatchers.IO) {
        try {
            val deviceInfo = AndInfo.instance.device
            val androidId = deviceInfo.getAndroidId()
            val deviceName = "${deviceInfo.brand} ${deviceInfo.model}"
            val gaidInfo = deviceInfo.getAdvertisingId()
            val gaid = gaidInfo?.id ?: ""

            Triple(androidId, deviceName, gaid)
        } catch (_: Exception) {
            Triple("unknown", "unknown", "")
        }
    }
}

