package com.dmc.callcrm.ui import android.Manifest import android.content.pm.PackageManager import android.os.Bundle import android.widget.TextView import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import com.dmc.callcrm.R import com.dmc.callcrm.data.Prefs import com.dmc.callcrm.network.ApiClient import com.dmc.callcrm.network.LinkClaimRequest import com.journeyapps.barcodescanner.ScanContract import com.journeyapps.barcodescanner.ScanOptions import kotlinx.coroutines.launch /** * Pairing screen for the Quick Call browser extension — the BROWSER shows a * QR code (see extension/connect.html); this screen scans it with the * phone's camera and claims it against this employee's account. */ class LinkExtensionActivity : AppCompatActivity() { private lateinit var prefs: Prefs private lateinit var statusText: TextView private val scanLauncher = registerForActivityResult(ScanContract()) { result -> val content = result.contents if (content == null) { statusText.text = "Scan cancelled." } else { handleScanned(content) } } private val cameraPermissionLauncher = registerForActivityResult( ActivityResultContracts.RequestPermission() ) { granted -> if (granted) launchScan() else statusText.text = "Camera permission is needed to scan the code." } private val callPermissionLauncher = registerForActivityResult( ActivityResultContracts.RequestPermission() ) { /* no-op either way — CallMonitorService falls back to opening the dialer if this is denied */ } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_link_extension) prefs = Prefs(this) statusText = findViewById(R.id.statusText) if (!prefs.isRegistered) { statusText.text = "Register the app first (see the setup screen) before linking a browser." } // So a browser click can dial directly instead of just opening the dialer. // Safe to ask here even if the user hasn't paired yet — it's a one-time prompt. if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { callPermissionLauncher.launch(Manifest.permission.CALL_PHONE) } findViewById(R.id.btnScan).setOnClickListener { if (!prefs.isRegistered) { Toast.makeText(this, "Register the app first.", Toast.LENGTH_SHORT).show() return@setOnClickListener } if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { launchScan() } else { cameraPermissionLauncher.launch(Manifest.permission.CAMERA) } } } private fun launchScan() { statusText.text = "" val options = ScanOptions() options.setDesiredBarcodeFormats(ScanOptions.QR_CODE) options.setPrompt("Scan the QR code shown in your browser") options.setBeepEnabled(false) options.setOrientationLocked(false) scanLauncher.launch(options) } private fun handleScanned(content: String) { val parts = content.split("|") if (parts.size != 3 || parts[0] != "DMCQC1") { statusText.text = "That doesn't look like a Quick Call pairing code." return } val extToken = parts[2] statusText.text = "Linking…" lifecycleScope.launch { var debugInfo = "" val resp = try { ApiClient.service.linkClaim(prefs.bearer(), LinkClaimRequest(extToken)) } catch (e: Exception) { debugInfo = "Exception: ${e.javaClass.simpleName}: ${e.message}" null } val body = resp?.body() if (debugInfo.isEmpty()) { val errBody = try { resp?.errorBody()?.string() } catch (_: Exception) { null } debugInfo = "HTTP ${resp?.code()} | ok=${body?.ok} | error=${body?.error} | raw=$errBody" } Toast.makeText(this@LinkExtensionActivity, debugInfo, Toast.LENGTH_LONG).show() android.util.Log.d("LinkExtension", debugInfo) statusText.text = when { body?.ok == true -> "✅ Linked! You can go back to your browser now." body?.error != null -> body.error else -> "Couldn't reach the server — check your connection and try again.\n\n$debugInfo" } } } }