package pt.whatsms.gateway.ui

import android.app.Activity
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.zxing.integration.android.IntentIntegrator
import com.google.zxing.integration.android.IntentResult
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import pt.whatsms.gateway.R
import pt.whatsms.gateway.modules.gateway.GatewaySettings
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import org.koin.android.ext.android.inject

class ScanPairingActivity : AppCompatActivity() {
    private val settings: GatewaySettings by inject()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        IntentIntegrator(this).apply {
            setPrompt(getString(R.string.scan_qr_to_pair))
            setBeepEnabled(true)
            setOrientationLocked(false)
            initiateScan()
        }
    }

    @Suppress("OVERRIDE_DEPRECATION")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        val result: IntentResult =
            IntentIntegrator.parseActivityResult(requestCode, resultCode, data)
                ?: return super.onActivityResult(requestCode, resultCode, data)
        if (result.contents == null) {
            Toast.makeText(this, R.string.pairing_cancelled, Toast.LENGTH_SHORT).show()
            setResult(Activity.RESULT_CANCELED)
            finish()
            return
        }
        claimDevice(result.contents)
    }

    private fun claimDevice(qrContent: String) {
        val deviceId = settings.deviceId
        val username = settings.username
        val password = settings.password
        if (deviceId == null || username == null || password == null) {
            Toast.makeText(this, R.string.pairing_not_registered, Toast.LENGTH_LONG).show()
            setResult(Activity.RESULT_CANCELED)
            finish()
            return
        }
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val qr = JSONObject(qrContent)
                val claimUrl = qr.getString("claimUrl")
                val pairingToken = qr.getString("pairingToken")
                val body = JSONObject().apply {
                    put("pairingToken", pairingToken)
                    put("deviceId", deviceId)
                    put("username", username)
                    put("password", password)
                    put("deviceName", Build.MODEL)
                }.toString()
                val client = OkHttpClient()
                val request = Request.Builder()
                    .url(claimUrl)
                    .post(body.toRequestBody("application/json".toMediaType()))
                    .build()
                val response = client.newCall(request).execute()
                val ok = response.isSuccessful
                withContext(Dispatchers.Main) {
                    if (ok) {
                        Toast.makeText(this@ScanPairingActivity, R.string.pairing_success, Toast.LENGTH_SHORT).show()
                        setResult(Activity.RESULT_OK)
                    } else {
                        Toast.makeText(this@ScanPairingActivity, R.string.pairing_failed, Toast.LENGTH_LONG).show()
                        setResult(Activity.RESULT_CANCELED)
                    }
                    finish()
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    Toast.makeText(this@ScanPairingActivity, getString(R.string.pairing_error, e.message), Toast.LENGTH_LONG).show()
                    setResult(Activity.RESULT_CANCELED)
                    finish()
                }
            }
        }
    }
}
