package com.Intaleq.intaleq

import android.app.AlertDialog
import android.os.Bundle
import android.util.Log
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.TextView
import androidx.core.view.setPadding
import com.scottyab.rootbeer.RootBeer
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import java.io.File
import java.util.Timer
import kotlin.concurrent.schedule

class MainActivity : FlutterFragmentActivity() {

    // The channel name is updated to use your new package name.
    private val CHANNEL_NAME = "com.Intaleq.intaleq/security"
    private lateinit var channel: MethodChannel

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        // Initialize the MethodChannel with the new name
        channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_NAME)

        // Set a MethodCallHandler to handle method calls from Flutter
        channel.setMethodCallHandler { call, result ->
            when (call.method) {
                "isNativeRooted" -> {
                    val isCompromised = isDeviceCompromised()
                    result.success(isCompromised) // Send the result back to Flutter
                }
                else -> {
                    result.notImplemented() // Handle unknown method calls
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Perform all checks. The order can matter; you might want to prioritize
        // the faster checks first.
        if (isDeviceCompromised()) {
            showSecurityWarningDialog()
        }
    }

    private fun isDeviceCompromised(): Boolean {
        return try {
            // NOTE: The SafetyNet check is commented out, just like in your old code.
            nativeRootCheck() || rootBeerCheck() // || !safetyNetCheck()
        } catch (e: Exception) {
            Log.e("SecurityCheck", "Error during security checks: ${e.message}", e)
            true // Consider the device compromised on error
        }
    }

    private fun nativeRootCheck(): Boolean {
        Log.d("SecurityCheck", "Starting native root detection...")
        return try {
            // This assumes you have a 'RootDetection' object/class in your project.
            val isNativeRooted = RootDetection.isNativeRooted()
            Log.d("SecurityCheck", "Native root detection result: $isNativeRooted")
            isNativeRooted
        } catch (e: Exception) {
            Log.e("SecurityCheck", "Error in native root detection: ${e.message}", e)
            true // Consider rooted on exception
        }
    }

    private fun rootBeerCheck(): Boolean {
        Log.d("SecurityCheck", "Starting RootBeer root detection...")
        val rootBeer = RootBeer(this)
        val isRooted = rootBeer.isRooted
        Log.d("SecurityCheck", "RootBeer detection result: $isRooted")
        return isRooted
    }

    // IMPORTANT: The SafetyNet API is deprecated. It's recommended to migrate to the Play Integrity
    // API.
    // This function is kept here from your old code for reference.
    private fun safetyNetCheck(): Boolean {
        Log.d("SecurityCheck", "Starting SafetyNet check...")
        var isSafe = false // Initialize a variable to store result
        val semaphore = java.util.concurrent.Semaphore(0) // Create a semaphore

        SafetyNetCheck.checkSafetyNet(this, getString(R.string.api_key_safety)) { result ->
            isSafe = result
            Log.d("SecurityCheck", "SafetyNet check result: $isSafe")
            semaphore.release() // Release the semaphore when the callback is executed
        }

        try {
            semaphore.acquire() // Wait for the callback to complete
        } catch (e: InterruptedException) {
            Log.e("SecurityCheck", "Interrupted while waiting for SafetyNet check", e)
            return false // Or handle as appropriate for your app
        }
        return isSafe
    }

    private fun showSecurityWarningDialog() {
        var secondsRemaining = 10 // Start at 10 seconds

        // Create views programmatically
        val progressBar = ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal)
        progressBar.max = 10 // Set max to 10 for 10 seconds
        progressBar.progress = 10 // Start full
        val textView = TextView(this)
        textView.text = getString(R.string.security_warning_message) // Your message
        textView.textAlignment = TextView.TEXT_ALIGNMENT_CENTER

        val layout = LinearLayout(this)
        layout.orientation = LinearLayout.VERTICAL
        layout.setPadding(48)
        layout.addView(textView)
        layout.addView(progressBar)

        val dialog =
                AlertDialog.Builder(this)
                        .setTitle(getString(R.string.security_warning_title)) // Your title
                        .setView(layout) // Set the custom layout
                        .setCancelable(
                                false
                        ) // Prevent dismissing by tapping outside or back button
                        .create()

        dialog.show()

        // Use a Timer to update the progress bar and countdown
        val timer = Timer()
        timer.schedule(0, 1000) { // Update every 1000ms (1 second)
            secondsRemaining--
            runOnUiThread { // Update UI on the main thread
                progressBar.progress =
                        secondsRemaining // Set the progress bar to show remaining seconds
                if (secondsRemaining <= 0) {
                    timer.cancel() // Stop the timer
                    dialog.dismiss() // Dismiss the dialog
                    clearAppDataAndExit() // Clear data and exit
                }
            }
        }
    }

    private fun clearAppDataAndExit() {
        try {
            // Note: This command often requires system permissions and may fail on user apps.
            // The fallback methods below will be used if it fails.
            val packageName = applicationContext.packageName
            val runtime = Runtime.getRuntime()
            runtime.exec("pm clear $packageName") // Clear app data
        } catch (e: Exception) {
            // Fallback to manual deletion if 'pm clear' fails
            clearCache()
            clearAppData()
        }

        finishAffinity() // Finish all activities from this app
        System.exit(0) // Terminate the app's process
    }

    private fun clearCache() {
        try {
            deleteDir(cacheDir)
            deleteDir(externalCacheDir)
        } catch (e: Exception) {
            Log.e("SecurityCheck", "Error clearing cache: ${e.message}", e)
        }
    }

    private fun clearAppData() {
        try {
            // Be careful with this, as it deletes everything in the app's data directory.
            deleteDir(applicationContext.dataDir)
        } catch (e: Exception) {
            Log.e("SecurityCheck", "Error clearing app data: ${e.message}", e)
        }
    }

    private fun deleteDir(dir: File?): Boolean {
        if (dir != null && dir.isDirectory) {
            val children = dir.list()
            if (children != null) {
                for (child in children) {
                    if (!deleteDir(File(dir, child))) {
                        return false
                    }
                }
            }
        }
        return dir?.delete() ?: false
    }
}
