package com.xyzshell.andinfo.libs

import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.os.Build
import android.os.storage.StorageManager
import java.io.File

data class PermissionInfo(
    val name: String,
    val description: String?,
    val status: String
)

data class AppDetails(
    val appName: String,
    val packageName: String,
    val versionName: String?,
    val versionCode: Long,
    val targetSdkVersion: Int,
    val minSdkVersion: Int?,
    val installer: String?,
    val lastUpdateTime: Long,
    val size: Long,
    val uid: Int,
    val permissions: List<PermissionInfo>,
    val icon: Any // Placeholder for the app's icon
)

class AppInfo(private val context: Context) {

    fun getInstalledApps(): List<AppDetails> {
        val packageManager = context.packageManager
        val apps = packageManager.getInstalledApplications(PackageManager.GET_META_DATA)
        val appDetailsList = mutableListOf<AppDetails>()

        for (app in apps) {
            // 过滤掉系统应用
            if ((app.flags and ApplicationInfo.FLAG_SYSTEM) != 0) {
                continue
            }
            val packageInfo = packageManager.getPackageInfo(app.packageName, PackageManager.GET_PERMISSIONS)
            val appName = app.loadLabel(packageManager).toString()
            val versionName = packageInfo.versionName
            val versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                packageInfo.longVersionCode
            } else {
                @Suppress("DEPRECATION")
                packageInfo.versionCode.toLong()
            }
            val targetSdkVersion = app.targetSdkVersion
            val minSdkVersion = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                app.minSdkVersion
            } else {
                null
            }
            val installer = packageManager.getInstallerPackageName(app.packageName)
            val lastUpdateTime = packageInfo.lastUpdateTime
            val size = getAppSize(app.sourceDir)
            val uid = app.uid
            // val permissions = packageInfo.requestedPermissions?.toList() ?: emptyList()
            val icon = app.loadIcon(packageManager)
            val permissions = packageInfo.requestedPermissions?.map { permission ->
                val permissionInfo = try {
                    packageManager.getPermissionInfo(permission, 0)
                } catch (e: PackageManager.NameNotFoundException) {
                    null
                }

                val permissionDescription = if (permissionInfo != null) {
                    permissionInfo.loadDescription(packageManager)?.toString() ?: "No description available"
                } else {
                    "No description available"
                }

                val permissionStatus = when {
                    context.checkPermission(permission, android.os.Process.myPid(), android.os.Process.myUid()) == PackageManager.PERMISSION_GRANTED -> {
                        "Allowed"
                    }
                    Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context.checkSelfPermission(permission) == PackageManager.PERMISSION_DENIED -> {
                        "Denied"
                    }
                    else -> {
                        "Special Access"
                    }
                }

                PermissionInfo(
                    name = permission,
                    description = permissionDescription,
                    status = permissionStatus
                )
            } ?: emptyList()

            appDetailsList.add(
                AppDetails(
                    appName = appName,
                    packageName = app.packageName,
                    versionName = versionName,
                    versionCode = versionCode,
                    targetSdkVersion = targetSdkVersion,
                    minSdkVersion = minSdkVersion,
                    installer = installer,
                    lastUpdateTime = lastUpdateTime,
                    size = size,
                    uid = uid,
                    permissions = permissions,
                    icon = icon
                )
            )
        }

        return appDetailsList
    }

    private fun getAppSize(sourceDir: String): Long {
        val file = File(sourceDir)
        return if (file.exists()) file.length() else 0L
    }
}