package partisan.weforge.xyz.pulse

import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Bundle
import android.os.SystemClock
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import com.google.android.material.button.MaterialButton
import java.util.concurrent.TimeUnit
import nl.dionsegijn.konfetti.core.Party
import nl.dionsegijn.konfetti.core.Position
import nl.dionsegijn.konfetti.core.emitter.Emitter
import nl.dionsegijn.konfetti.xml.KonfettiView

class MainFragment : Fragment() {

    private lateinit var prefs: Preferences
    private var lastConfettiTime = 0L

    override fun onResume() {
        super.onResume()
        (requireActivity() as? MainActivity)?.setAppBarTitle(getString(R.string.app_name))
    }

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View {
        val view = inflater.inflate(R.layout.fragment_main, container, false)
        prefs = Preferences(requireContext())

        val toggle = view.findViewById<MaterialButton>(R.id.toggle)
        val konfetti = view.findViewById<KonfettiView>(R.id.confettiView)

        toggle.isCheckable = true
        toggle.isChecked = prefs.isServiceEnabledByUser

        toggle.setOnClickListener {
            // the button toggles itself internally since it's checkable
            val isNowChecked = toggle.isChecked
            prefs.isServiceEnabledByUser = isNowChecked

            if (isNowChecked && SystemClock.elapsedRealtime() - lastConfettiTime > 500) {
                konfetti.start(
                        Party(
                                emitter =
                                        Emitter(duration = 100, TimeUnit.MILLISECONDS)
                                                .perSecond(100),
                                speed = 25f,
                                maxSpeed = 30f,
                                damping = 0.85f,
                                spread = 360,
                                position = Position.Relative(0.5, 0.5)
                        )
                )
                lastConfettiTime = SystemClock.elapsedRealtime()
            }

            toggle.post {
                toggle.jumpDrawablesToCurrentState()
                toggle.invalidate()
            }
        }

        val warningText = view.findViewById<TextView>(R.id.warningText)
        val warnings = mutableListOf<String>()

        // 1. Check if contacts are available
        val contactCursor =
                requireContext()
                        .contentResolver
                        .query(
                                android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                null,
                                null,
                                null,
                                null
                        )

        if (contactCursor != null) {
            contactCursor.use {
                if (!it.moveToFirst()) {
                    warnings.add(getString(R.string.warn_no_contacts))
                }
            }
        } else {
            warnings.add(getString(R.string.warn_no_contacts))
        }

        // 2. Check internet connectivity
        if (!hasInternet()) {
            warnings.add(getString(R.string.warn_no_internet))
        }

        // Show warning if needed
        if (warnings.isNotEmpty()) {
            warningText.text = warnings.joinToString("\n")
            warningText.visibility = View.VISIBLE
        }

        return view
    }

    private fun hasInternet(): Boolean {
        val cm = requireContext().getSystemService(ConnectivityManager::class.java)
        val capabilities = cm?.getNetworkCapabilities(cm.activeNetwork) ?: return false
        return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
                capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
    }
}
