package de.storchp.fdroidbuildstatus

import android.Manifest
import android.content.pm.PackageManager
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.updatePadding
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreferenceCompat
import androidx.recyclerview.widget.RecyclerView
import dagger.hilt.android.AndroidEntryPoint
import de.storchp.fdroidbuildstatus.databinding.SettingsActivityBinding
import de.storchp.fdroidbuildstatus.utils.PreferencesService
import de.storchp.fdroidbuildstatus.utils.addInsetsListener
import javax.inject.Inject

@AndroidEntryPoint
class SettingsActivity : AppCompatActivity() {

    private lateinit var binding: SettingsActivityBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        enableEdgeToEdge()
        super.onCreate(savedInstanceState)
        binding = SettingsActivityBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setSupportActionBar(binding.topAppBar)
        binding.topAppBar.addInsetsListener {
            updatePadding(left = it.left, right = it.right)
        }
        binding.appBarLayout.liftOnScrollTargetViewId = androidx.preference.R.id.recycler_view
        if (savedInstanceState == null) {
            supportFragmentManager
                .beginTransaction()
                .replace(R.id.settings, SettingsFragment())
                .commit()
        }
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
    }

    @AndroidEntryPoint
    class SettingsFragment : PreferenceFragmentCompat() {

        @Inject
        lateinit var preferencesService: PreferencesService

        private var notifyPublishPref: SwitchPreferenceCompat? = null
        private var notifyRunningBuildsPref: SwitchPreferenceCompat? = null
        private var notifyFunishedBuildsPref: SwitchPreferenceCompat? = null

        private val requestNotificationPermissionLauncher =
            registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean? ->
                if (!isGranted!!) {
                    disableNotifications()
                    Toast.makeText(
                        requireContext(),
                        R.string.notification_permission_needed,
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            view.findViewById<RecyclerView>(androidx.preference.R.id.recycler_view).addInsetsListener {
                updatePadding(left = it.left, right = it.right, bottom = it.bottom)
            }
        }

        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey)
            if (VERSION.SDK_INT >= VERSION_CODES.TIRAMISU) {
                notifyPublishPref =
                    findAndListenToNotificationPreference(R.string.PREF_NOTIFY_PUBLISH)
                notifyRunningBuildsPref =
                    findAndListenToNotificationPreference(R.string.PREF_NOTIFY_RUNNING_BUILDS)
                notifyFunishedBuildsPref =
                    findAndListenToNotificationPreference(R.string.PREF_NOTIFY_FINISHED_BUILDS)
                if (isNotificationPermissionDenied) {
                    disableNotifications()
                }
            }
            val nightModePref = findPreference<Preference>(getString(R.string.night_mode_key))!!
            nightModePref.onPreferenceChangeListener =
                Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
                    requireActivity().runOnUiThread { preferencesService.applyNightMode((newValue as String).toInt()) }
                    true
                }
        }

        @RequiresApi(api = VERSION_CODES.TIRAMISU)
        private fun findAndListenToNotificationPreference(preferenceKey: Int): SwitchPreferenceCompat? =
            findPreference<SwitchPreferenceCompat>(getString(preferenceKey))?.apply {
                onPreferenceChangeListener = preferenceChangeListener
            }

        @RequiresApi(api = VERSION_CODES.TIRAMISU)
        private val preferenceChangeListener: Preference.OnPreferenceChangeListener =
            Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
                if (newValue as Boolean && isNotificationPermissionDenied) {
                    requestNotificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
                }
                true
            }

        private fun disableNotifications() {
            notifyPublishPref?.isChecked = false
            notifyRunningBuildsPref?.isChecked = false
            notifyFunishedBuildsPref?.isChecked = false
        }

        @get:RequiresApi(api = VERSION_CODES.TIRAMISU)
        private val isNotificationPermissionDenied: Boolean
            get() = ContextCompat.checkSelfPermission(
                requireContext(),
                Manifest.permission.POST_NOTIFICATIONS
            ) != PackageManager.PERMISSION_GRANTED
    }
}