package com.mytatvarnsdk.activity

import android.Manifest
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.app.Dialog
import android.bluetooth.BluetoothAdapter
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.util.Log
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.enableEdgeToEdge
import androidx.annotation.RequiresApi
import androidx.annotation.RequiresPermission
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toDrawable
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import cgmblelib.utils.ConstantsLibrary
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.CatalystInstance
import com.facebook.react.bridge.WritableMap
import com.facebook.react.modules.core.DeviceEventManagerModule
import com.mytatvarnsdk.CgmTrackyLibModule
import com.mytatvarnsdk.base.BasePermissionActivity
import com.mytatvarnsdk.databinding.ActivityPermissionBinding
import com.mytatvarnsdk.databinding.BluetoothDialogBottomsheetBinding
import com.mytatvarnsdk.databinding.ExitDialogBottomsheetBinding
import org.json.JSONObject

class PermissionActivity : BasePermissionActivity() {
    private lateinit var binding: ActivityPermissionBinding
    private val LOCATION_REQUEST_CODE = 101
    private val BLUETOOTH_REQUEST_CODE = 102

    private val REQUEST_ENABLE_BT = 1
    private val bluetoothAdapter: BluetoothAdapter? by lazy {
        BluetoothAdapter.getDefaultAdapter()
    }
    private val reactContext = CgmTrackyLibModule.mReactContext

    private var isForReconnect: Boolean = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityPermissionBinding.inflate(layoutInflater)

        enableEdgeToEdge()
        ViewCompat.setOnApplyWindowInsetsListener(binding.rlPopBottom) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
        setContentView(binding.root)

        initialize()
    }

    override fun getPermission(): Array<out Array<out String?>?>? {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            return arrayOf<Array<String?>?>(ConstantsLibrary.BLUETOOTH_S)
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            return arrayOf<Array<String?>?>(
                ConstantsLibrary.LOCAL_PERMISSION,
                ConstantsLibrary.BACKGROUND_LOCATION_Q
            )
        } else {
            return arrayOf<Array<String?>?>(ConstantsLibrary.LOCAL_PERMISSION)
        }
    }

    override fun onPermissionRequestSuccess() {
    }

    override fun onPermissionRequestFail(vararg permission: String?) {
    }

    override fun onPermissionRequestFailForever(vararg permission: String?) {
    }

    fun isBluetoothPermissionGranted(context: Context): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            val connectPermission = ContextCompat.checkSelfPermission(
                context,
                Manifest.permission.BLUETOOTH_CONNECT
            ) == PackageManager.PERMISSION_GRANTED

            val scanPermission = ContextCompat.checkSelfPermission(
                context,
                Manifest.permission.BLUETOOTH_SCAN
            ) == PackageManager.PERMISSION_GRANTED

            val advertisePermission = ContextCompat.checkSelfPermission(
                context,
                Manifest.permission.BLUETOOTH_ADVERTISE
            ) == PackageManager.PERMISSION_GRANTED

            // Include advertisePermission only if your app uses Bluetooth advertising
            connectPermission && scanPermission && advertisePermission
        } else {
            // For Android 11 and below, permission is granted at install time or via location
            true
        }
    }

    fun isLocationPermissionGranted(context: Context): Boolean {
        val fineLocationGranted = ContextCompat.checkSelfPermission(
            context,
            android.Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED

        val coarseLocationGranted = ContextCompat.checkSelfPermission(
            context,
            android.Manifest.permission.ACCESS_COARSE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED

        return fineLocationGranted || coarseLocationGranted
    }


    @SuppressLint("MissingPermission")
    private fun initialize() {
        isForReconnect = intent.getBooleanExtra("IsForReconnect", false)

        sendDataToRN("", "cgm_permissions_page_landing")

        bluetoothAdapter?.let {
            binding.switchBluetooth.isChecked = isBluetoothPermissionGranted(this) && it.isEnabled
        }

        binding.switchLocation.isChecked = isLocationPermissionGranted(this)

        binding.switchBluetooth.setOnCheckedChangeListener { _, isChecked ->
            if (isChecked) {
                requestBluetoothPermission()
            }
        }

        binding.switchLocation.setOnCheckedChangeListener { _, isChecked ->
            if (isChecked) {
                requestLocationPermission()
            }
        }

        binding.commonButton.btnProceed.setOnClickListener {
            val jsonObject = JSONObject()
            jsonObject.put("bluetooth_toggle_status", "ON")
            jsonObject.put("location_toggle_status", "ON")
            sendDataToRN(jsonObject.toString(), "cgm_permissions_proceed_clicked")

            startActivity(
                Intent(this@PermissionActivity, SearchTransmitterActivity::class.java)
                    .putExtra("IsForReconnect", isForReconnect)
            )
            finish()
        }

        binding.toolbar.btnWhatsapp.setOnClickListener {
            startActivity(
                Intent(this, HelpActivity::class.java)
                    .putExtra("ScreenName", "connection journey page")
            )
        }

        binding.toolbar.btnWatchDemo.setOnClickListener {
            sendDataToRN("", "cgm_watch_demo_clicked")

            startActivity(
                Intent(this, VideoActivity::class.java).putExtra(
                    "VideoId",
                    if (isForReconnect) "n_pUrFoZ1wQ" else "r5Zemc4R044"
                )
            )
        }

        binding.tvKnowMore.setOnClickListener {
            openBluetoothDialog()
        }

        binding.toolbar.btnClose.setOnClickListener {
            openExitDialog()
        }

        val callback: OnBackPressedCallback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                openExitDialog()
            }
        }
        onBackPressedDispatcher.addCallback(this, callback)
    }

    private fun sendDataToRN(data: String, status: String) {
        if (reactContext != null) {
            try {
                val catalystInstance: CatalystInstance = reactContext.catalystInstance
                val module = catalystInstance.getNativeModule(CgmTrackyLibModule::class.java)

                if (module == null) {
                    sendDataToRNDirectly(data, status)
                    Log.d("sendDataToRN: ", "Module null")
                } else {
                    module.sendDataToReact(data, status, "cgmDeviceEvent")
                    Log.d("sendDataToRN: ", "Module is not null")
                }
            } catch (e: Exception) {
                Log.e("sendDataToRN: Error ", e.message.toString())
            }
        } else {
            Log.e("TrackyActivity", "ReactApplicationContext is null")
        }
    }


    private fun sendDataToRNDirectly(data: String, status: String) {
        try {
            val map: WritableMap = Arguments.createMap().apply {
                putString("data", data)
                putString("status", status)
            }

            reactContext?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
                ?.emit("cgmDeviceEvent", map)
        } catch (e: Exception) {
            Log.e("sendDataToRNDirectly", "Error sending data to React", e)
        }
    }

    private fun openBluetoothDialog() {
        val binding = BluetoothDialogBottomsheetBinding.inflate(layoutInflater)

        val dialog = Dialog(this)
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog.setContentView(binding.root)

        val window = dialog.window
        window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
        window?.setGravity(Gravity.BOTTOM)
        window?.setBackgroundDrawable(Color.TRANSPARENT.toDrawable())

        binding.tvKnowMore.setOnClickListener {
            val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
                data = Uri.fromParts("package", packageName, null)
            }
            startActivity(intent)
        }

        binding.closeButton.setOnClickListener(View.OnClickListener { v: View? ->
            dialog.dismiss()
        })

        dialog.show()
    }

    private fun openExitDialog() {
        val binding = ExitDialogBottomsheetBinding.inflate(layoutInflater)

        val dialog = Dialog(this)
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog.setContentView(binding.root)

        val window = dialog.window
        window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
        window?.setGravity(Gravity.BOTTOM)
        window?.setBackgroundDrawable(Color.TRANSPARENT.toDrawable())

        binding.btnExit.tvProceed.text = "Exit"

        binding.btnExit.root.setOnClickListener(View.OnClickListener { v: View? ->
            finish()
            dialog.dismiss()
        })

        binding.btnCancel.root.setOnClickListener(View.OnClickListener { v: View? ->
            dialog.dismiss()
        })

        binding.closeButton.setOnClickListener(View.OnClickListener { v: View? ->
            dialog.dismiss()
        })

        dialog.show()
    }


    private fun requestForegroundLocationPermission() {
        val locationPermissions = PermissionUtils.LOCAL_PERMISSION

        if (hasPermissions(locationPermissions)) {
            onForegroundLocationGranted()
        } else {
            ActivityCompat.requestPermissions(
                this,
                locationPermissions,
                LOCATION_REQUEST_CODE
            )
        }
    }

    private fun requestLocationPermission() {
        val permissions = mutableListOf(*PermissionUtils.LOCAL_PERMISSION)

        val permissionArray = permissions.toTypedArray()

        if (hasPermissions(permissionArray)) {
            onLocationPermissionGranted()
        } else {
            val rationaleNeeded = permissionArray.any {
                ActivityCompat.shouldShowRequestPermissionRationale(this, it)
            }

            if (rationaleNeeded) {
                showPermissionRationale(
                    title = "Location Permission Needed",
                    message = "We need location access for Bluetooth scanning.",
                    onProceed = {
                        ActivityCompat.requestPermissions(
                            this,
                            permissionArray,
                            LOCATION_REQUEST_CODE
                        )
                    }
                )
            } else {
                ActivityCompat.requestPermissions(this, permissionArray, LOCATION_REQUEST_CODE)
            }
        }
    }

    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
    private fun requestBluetoothPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            val permissions = PermissionUtils.BLUETOOTH_S

            if (hasPermissions(permissions)) {
                onBluetoothPermissionGranted()
            } else {
                val rationaleNeeded = permissions.any {
                    ActivityCompat.shouldShowRequestPermissionRationale(this, it)
                }

                if (rationaleNeeded) {
                    showPermissionRationale(
                        title = "Bluetooth Permission Needed",
                        message = "We need Bluetooth access to connect your device.",
                        onProceed = {
                            ActivityCompat.requestPermissions(
                                this,
                                permissions,
                                BLUETOOTH_REQUEST_CODE
                            )
                        }
                    )
                } else {
                    ActivityCompat.requestPermissions(this, permissions, BLUETOOTH_REQUEST_CODE)
                }
            }
        } else {
            onBluetoothPermissionGranted()
        }
    }

    private fun showPermissionRationale(title: String, message: String, onProceed: () -> Unit) {
        AlertDialog.Builder(this)
            .setTitle(title)
            .setMessage(message)
            .setPositiveButton("OK") { _, _ -> onProceed() }
            .setNegativeButton("Cancel", null)
            .show()
    }


    private fun hasPermissions(permissions: Array<String>): Boolean {
        return permissions.all {
            ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
        }
    }

    private fun areAllPermissionsGranted(): Boolean {
        val requiredPermissions = mutableListOf<String>()

        // Add Bluetooth permissions
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            requiredPermissions.addAll(PermissionUtils.BLUETOOTH_S)
        }

        // Add location permissions
        requiredPermissions.addAll(PermissionUtils.LOCAL_PERMISSION)

        return requiredPermissions.all {
            ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
        }
    }

    private fun updateProceedButtonState() {
        if (areAllPermissionsGranted() && bluetoothAdapter!!.isEnabled) {
            binding.commonButton.btnProceed.alpha = 1f
            binding.commonButton.btnProceed.isEnabled = true
        } else {
            binding.commonButton.btnProceed.alpha = 0.5f
            binding.commonButton.btnProceed.isEnabled = false
        }
    }

    private fun onForegroundLocationGranted() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&
            ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION)
            != PackageManager.PERMISSION_GRANTED
        ) {
            onLocationPermissionGranted()
        } else {
            Log.d("Permission", "All location permissions granted")
        }
    }

    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED }

        when (requestCode) {
//      LOCATION_REQUEST_CODE -> {
//        if (grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
//          onForegroundLocationGranted()
//        } else {
//          Log.d("Permission", "Foreground location denied")
//        }
//      }

            LOCATION_REQUEST_CODE -> {
                if (allGranted) {
                    onLocationPermissionGranted()
                }
            }

            BLUETOOTH_REQUEST_CODE -> {
                if (allGranted) {
                    onBluetoothPermissionGranted()
                }
            }
        }
        updateProceedButtonState()
    }

    private fun onLocationPermissionGranted() {
        updateProceedButtonState()
        // Start location-based action
    }

    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
    private fun onBluetoothPermissionGranted() {
        if (bluetoothAdapter == null) {
            Toast.makeText(this, "Bluetooth not supported", Toast.LENGTH_SHORT).show()
        } else {
            if (!bluetoothAdapter!!.isEnabled) {
                val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
            }
        }

        updateProceedButtonState()
        // Start Bluetooth device scan or connect
    }

    override fun onResume() {
        super.onResume()
        updateProceedButtonState()
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_ENABLE_BT) {
            if (resultCode == RESULT_OK) {
                updateProceedButtonState()
            }
        }
    }
}

object PermissionUtils {
    @RequiresApi(Build.VERSION_CODES.S)
    val BLUETOOTH_S = arrayOf(
        Manifest.permission.BLUETOOTH_ADVERTISE,
        Manifest.permission.BLUETOOTH_CONNECT,
        Manifest.permission.BLUETOOTH_SCAN
    )

    val LOCAL_PERMISSION = arrayOf(
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_COARSE_LOCATION
    )


    val CAMERA_PERMISSION = arrayOf(
        Manifest.permission.CAMERA
    )
}
