package com.example.modifier

import android.app.role.RoleManager
import android.content.DialogInterface
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.util.Log
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.NavigationUI.setupWithNavController
import com.example.modifier.databinding.ActivityMainBinding
import com.example.modifier.databinding.DialogProgressBinding
import com.example.modifier.databinding.DialogUpdateBinding
import com.example.modifier.service.ModifierService
import com.example.modifier.utils.ADB
import com.example.modifier.utils.ROOT_ACCESS
import com.example.modifier.utils.enableAccessibility
import com.example.modifier.utils.enableOverlay
import com.example.modifier.utils.getIPAddress
import com.example.modifier.utils.hasRootAccess
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class MainActivity : AppCompatActivity() {
    companion object {
        const val TAG = "MainActivity"
        const val CODE_CLEAN = 100
    }

    private lateinit var mBinding: ActivityMainBinding
    private var mTmpCallback: ((success: Boolean) -> Unit)? = null
    var a11yRegister = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
        if (it.resultCode == RESULT_OK) {

        } else {

        }
    }
    var smsRegister = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
        if (it.resultCode == RESULT_OK) {
            deleteAllSms(mTmpCallback)
        } else {
            mTmpCallback?.invoke(false)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        Log.i(TAG, "onCreate")
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        mBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(mBinding.root)

        val navHostFragment =
            supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        val controller = navHostFragment.navController
        setupWithNavController(mBinding.nav, controller)
        CoroutineScope(Dispatchers.IO).launch {
            if (hasRootAccess()) {
                ROOT_ACCESS = true
                if (!enableAccessibility()) {
                    val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    startActivity(intent)
                    delay(1000);
                    finish();
                }
                enableOverlay()
            } else {
                val dialog = withContext(Dispatchers.Main) {
                    val dialogBinding = DialogProgressBinding.inflate(layoutInflater)
                    dialogBinding.progressDialogText.text = "Waiting for ADB connection"
                    MaterialAlertDialogBuilder(this@MainActivity)
                        .setView(dialogBinding.root)
                        .setCancelable(false)
                        .show()
                }

                if (ADB.connect()) {
                    dialog.dismiss()
                    if (!enableAccessibility()) {
                        val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                        startActivity(intent)
                        delay(1000);
                        finish();
                    }
                } else {
                    dialog.dismiss()
                    withContext(Dispatchers.Main) {
                        MaterialAlertDialogBuilder(this@MainActivity)
                            .setTitle("Error")
                            .setMessage("Failed to connect to ADB")
                            .setCancelable(false)
                            .setPositiveButton("Exit") { _, _ ->
                                finish()
                            }
                            .show()
                    }
                }
//                if (ModifierService.instance != null) {
//                    return@launch
//                }
//
//                withContext(Dispatchers.Main) {
//                    requestAccessibilityPermission()
//                }
            }
            Log.i("getIPAddress", getIPAddress().joinToString())
        }
        checkCleanIntent(intent)
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        Log.i(TAG, "onNewIntent")
        checkCleanIntent(intent)
    }

    fun checkCleanIntent(intent: Intent) {
        if (intent.getBooleanExtra("clean", false)) {
            intent.removeExtra("clean")
            checkPermissionAndClean {
                if (it) {
                    Log.i(TAG, "SMS Cleaned")
                    Toast.makeText(this, "SMS Cleaned", Toast.LENGTH_SHORT).show()
                } else {
                    Log.e(TAG, "Failed to clean SMS")
                    Toast.makeText(this, "Failed to clean SMS", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    private fun requestAccessibilityPermission(): Boolean {
        if (ModifierService.instance == null) {
            MaterialAlertDialogBuilder(this@MainActivity)
                .setTitle("Operation Needed")
                .setMessage("Enable Accessibility Service")
                .setCancelable(false)
                .setPositiveButton("Open Settings") { _: DialogInterface?, _: Int ->
                    val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
                    a11yRegister.launch(intent)
                }
                .show()
            return false
        }
        return true
    }

    private fun checkPermissionAndClean(callback: (success: Boolean) -> Unit) {
        mTmpCallback = callback
        val roleManager = applicationContext.getSystemService(RoleManager::class.java)
        if (roleManager.isRoleAvailable(RoleManager.ROLE_SMS)) {
            if (roleManager.isRoleHeld(RoleManager.ROLE_SMS)) {
                deleteAllSms(callback)
            } else {
                val roleRequestIntent = roleManager.createRequestRoleIntent(RoleManager.ROLE_SMS)
                smsRegister.launch(roleRequestIntent)
            }
        }
    }

    private fun deleteAllSms(callback: ((success: Boolean) -> Unit)?) {
        try {
            val cr = contentResolver
            cr.delete(Uri.parse("content://sms/"), null, null)
            callback?.invoke(true)
        } catch (e: Exception) {
            Log.wtf(TAG, "Error: " + e.message, e)
            callback?.invoke(false)
        }
    }
}