package partisan.weforge.xyz.pulse

import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.browser.customtabs.CustomTabsIntent
import androidx.fragment.app.Fragment
import okhttp3.*
import partisan.weforge.xyz.pulse.databinding.FragmentDonateBinding
import java.io.IOException


class DonateFragment : Fragment() {

    private val client = OkHttpClient()
    private val apiBase = "https://api.weforge.xyz/api"
    private var _binding: FragmentDonateBinding? = null
    private val binding get() = _binding!!
    private lateinit var prefs: Preferences

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentDonateBinding.inflate(inflater, container, false)
        return binding.root
    }

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        prefs = Preferences(requireContext())

        // Pre-fill token field
        binding.tokenInput.setText(prefs.donationToken)

        // Show toast and open Ko-fi
        binding.kofiButton.setOnClickListener {
            Toast.makeText(
                requireContext(),
                getString(R.string.donate_toast_reminder),
                Toast.LENGTH_LONG
            ).show()
            val customTab = CustomTabsIntent.Builder().build()
            customTab.launchUrl(requireContext(), Uri.parse("https://ko-fi.com/internetaddict"))
        }

        binding.tokenDisplay.text = "token:${prefs.donationToken}"
        binding.tokenDisplay.setOnClickListener {
            val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as android.content.ClipboardManager
            val clip = android.content.ClipData.newPlainText("Ko-fi token", "token:${prefs.donationToken}")
            clipboard.setPrimaryClip(clip)
            Toast.makeText(context, getString(R.string.donate_token_copied), Toast.LENGTH_SHORT).show()
        }

        // If already donated, update UI to show activation message and hide token entry controls
        if (prefs.isDonationActivated) {
            binding.postDonatePrompt.text = getString(R.string.donate_token_activated)
            binding.openTokenSection.visibility = View.GONE
            binding.tokenSection.visibility = View.GONE
        } else {
            // Show token entry section button if not activated
            binding.openTokenSection.setOnClickListener {
                binding.tokenSection.visibility = View.VISIBLE
                binding.openTokenSection.visibility = View.GONE
            }
        }
        
        binding.verifyButton.setOnClickListener {
            var token = binding.tokenInput.text.toString().trim()

            // Strip optional "token:" prefix
            if (token.startsWith("token:")) {
                token = token.removePrefix("token:")
            }

            // Validate token format
            if (token.length != 16) {
                Toast.makeText(context, getString(R.string.donate_token_invalid_format), Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            prefs.donationToken = token

            if (prefs.isDonationActivated) {
                binding.resultText.text = getString(R.string.donate_token_already_activated)
                return@setOnClickListener
            }

            // Step 0: Check INTERNET permission
            if (!hasInternetPermission(requireContext())) {
                binding.resultText.text = getString(R.string.donate_missing_permission)
                return@setOnClickListener
            }

            // Step 1: Try activation server first
            val aliveRequest = Request.Builder().url("$apiBase/alive").build()
            client.newCall(aliveRequest).enqueue(object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    // If server unreachable, fallback to internet check
                    val internetCheck = Request.Builder()
                        .url("https://deb.debian.org/")
                        .build()

                    client.newCall(internetCheck).enqueue(object : Callback {
                        override fun onFailure(call: Call, e: IOException) {
                            activity?.runOnUiThread {
                                binding.resultText.text = getString(R.string.donate_no_internet)
                            }
                        }

                        override fun onResponse(call: Call, response: Response) {
                            activity?.runOnUiThread {
                                if (!response.isSuccessful || response.body?.string().isNullOrBlank()) {
                                    binding.resultText.text = getString(R.string.donate_no_internet)
                                } else {
                                    binding.resultText.text = getString(R.string.donate_server_unreachable)
                                }
                            }
                        }
                    })
                }

                override fun onResponse(call: Call, response: Response) {
                    if (response.body?.string()?.trim() != "true") {
                        activity?.runOnUiThread {
                            binding.resultText.text = getString(R.string.donate_server_not_responding)
                        }
                        return
                    }

                    // Step 2: Check token
                    val checkRequest = Request.Builder()
                        .url("$apiBase/check?token=$token")
                        .build()

                    client.newCall(checkRequest).enqueue(object : Callback {
                        override fun onFailure(call: Call, e: IOException) {
                            activity?.runOnUiThread {
                                binding.resultText.text = getString(R.string.donate_token_check_failed)
                            }
                        }

                        override fun onResponse(call: Call, response: Response) {
                            val result = response.body?.string()?.trim()
                            if (result == "0") {
                                activity?.runOnUiThread {
                                    binding.resultText.text = getString(R.string.donate_token_invalid)
                                }
                                return
                            }

                            // Step 3: Activate
                            val activateRequest = Request.Builder()
                                .url("$apiBase/activate?token=$token")
                                .build()

                            client.newCall(activateRequest).enqueue(object : Callback {
                                override fun onFailure(call: Call, e: IOException) {
                                    activity?.runOnUiThread {
                                        binding.resultText.text = getString(R.string.donate_activation_failed)
                                    }
                                }

                                override fun onResponse(call: Call, response: Response) {
                                    val activateResult = response.body?.string()?.trim()
                                    if (activateResult == "success") {
                                        prefs.isDonationActivated = true
                                        activity?.runOnUiThread {
                                            val remaining = (result?.toIntOrNull() ?: 1) - 1
                                            binding.resultText.text =
                                                getString(R.string.donate_token_activated) + "\n" +
                                                getString(R.string.donate_token_left, remaining.toString())
                                        }
                                    } else {
                                        activity?.runOnUiThread {
                                            binding.resultText.text = getString(R.string.donate_activation_failed)
                                        }
                                    }
                                }
                            })
                        }
                    })
                }
            })
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    private fun hasInternetPermission(context: Context): Boolean {
        return ContextCompat.checkSelfPermission(
            context,
            Manifest.permission.INTERNET
        ) == PackageManager.PERMISSION_GRANTED
    }
}
