package com.example.ui.admin import android.net.Uri import android.widget.Toast import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.CheckCircle import androidx.compose.material.icons.filled.CloudUpload import androidx.compose.material.icons.filled.Payment import androidx.compose.material.icons.filled.PhotoLibrary import androidx.compose.material.icons.filled.QrCode import androidx.compose.material.icons.filled.QrCode2 import androidx.compose.material.icons.filled.Refresh import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil.compose.AsyncImage import coil.request.ImageRequest import com.example.R import com.example.ui.theme.FreshVegGreen import com.example.ui.theme.LoveRedPrimary import com.example.ui.theme.TextPrimary import com.example.ui.theme.TextSecondary import com.example.viewmodel.AdminViewModel import androidx.compose.material.icons.filled.Language import androidx.compose.material.icons.filled.Link import androidx.compose.material.icons.filled.Dns import androidx.compose.material.icons.filled.ContentCopy import android.content.ClipData import android.content.ClipboardManager import android.content.Context import com.example.util.ShareAppHelper @Composable fun AdminPaymentQrScreen( adminViewModel: AdminViewModel, modifier: Modifier = Modifier ) { val context = LocalContext.current val settings by adminViewModel.adminSettings.collectAsState() var upiIdInput by remember(settings.upiId) { mutableStateOf(settings.upiId) } var qrUriInput by remember(settings.qrImageUri) { mutableStateOf(settings.qrImageUri) } var freeMinInput by remember(settings.freeDeliveryThreshold) { mutableStateOf(settings.freeDeliveryThreshold.toInt().toString()) } var feeInput by remember(settings.deliveryFee) { mutableStateOf(settings.deliveryFee.toInt().toString()) } var announcementInput by remember(settings.announcement) { mutableStateOf(settings.announcement) } var domainInput by remember(settings.customDomain) { mutableStateOf(settings.customDomain) } var savedMessage by remember { mutableStateOf(null) } val qrPickerLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.PickVisualMedia() ) { uri: Uri? -> if (uri != null) { qrUriInput = uri.toString() adminViewModel.updatePaymentQr(upiIdInput, uri.toString()) savedMessage = "Custom Payment QR Code uploaded successfully! 📸" } } Column( modifier = modifier .fillMaxSize() .verticalScroll(rememberScrollState()) .padding(16.dp) .padding(bottom = 60.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { // Title & Description Card( shape = RoundedCornerShape(16.dp), colors = CardDefaults.cardColors(containerColor = Color(0xFF1E102E)), modifier = Modifier.fillMaxWidth() ) { Row( modifier = Modifier.padding(16.dp), verticalAlignment = Alignment.CenterVertically ) { Box( modifier = Modifier .size(44.dp) .background(LoveRedPrimary, CircleShape), contentAlignment = Alignment.Center ) { Icon(Icons.Default.QrCode2, contentDescription = null, tint = Color.White, modifier = Modifier.size(24.dp)) } Spacer(modifier = Modifier.width(12.dp)) Column { Text(text = "Online Payment & QR Settings", color = Color.White, fontWeight = FontWeight.Bold, fontSize = 16.sp) Text(text = "Upload your custom UPI QR code so customers can scan & pay directly to your account.", color = Color(0xFFD1C4E9), fontSize = 11.sp) } } } if (savedMessage != null) { Surface( color = Color(0xFFE8F5E9), shape = RoundedCornerShape(10.dp), modifier = Modifier.fillMaxWidth() ) { Row( modifier = Modifier.padding(12.dp), verticalAlignment = Alignment.CenterVertically ) { Icon(Icons.Default.CheckCircle, contentDescription = null, tint = FreshVegGreen, modifier = Modifier.size(20.dp)) Spacer(modifier = Modifier.width(8.dp)) Text(text = savedMessage ?: "", color = FreshVegGreen, fontWeight = FontWeight.Bold, fontSize = 13.sp) } } } // Custom QR Upload & Live Preview Card Card( shape = RoundedCornerShape(16.dp), colors = CardDefaults.cardColors(containerColor = Color.White), elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), modifier = Modifier.fillMaxWidth() ) { Column( modifier = Modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = "CUSTOMER PAYMENT QR PREVIEW", fontWeight = FontWeight.Bold, fontSize = 12.sp, color = TextSecondary, letterSpacing = 1.sp ) Spacer(modifier = Modifier.height(12.dp)) // The QR Code Image Box Box( modifier = Modifier .size(200.dp) .background(Color.White, RoundedCornerShape(14.dp)) .border(2.5.dp, LoveRedPrimary, RoundedCornerShape(14.dp)) .padding(12.dp), contentAlignment = Alignment.Center ) { if (qrUriInput.isNotBlank()) { AsyncImage( model = ImageRequest.Builder(context) .data(if (qrUriInput.startsWith("content://") || qrUriInput.startsWith("file://")) Uri.parse(qrUriInput) else qrUriInput) .crossfade(true) .build(), contentDescription = "Custom QR", modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Fit, error = painterResource(id = R.drawable.qr_lovezone_upi) ) } else { Image( painter = painterResource(id = R.drawable.qr_lovezone_upi), contentDescription = "Default QR", modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Fit ) } } Spacer(modifier = Modifier.height(10.dp)) Text( text = if (qrUriInput.isNotBlank()) "✅ Custom UPI QR Code Active" else "Default Love Zone QR Active", fontSize = 12.sp, fontWeight = FontWeight.SemiBold, color = if (qrUriInput.isNotBlank()) FreshVegGreen else TextSecondary ) Spacer(modifier = Modifier.height(14.dp)) // Buttons: Upload Custom QR / Reset Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(10.dp) ) { Button( onClick = { qrPickerLauncher.launch( androidx.activity.result.PickVisualMediaRequest( ActivityResultContracts.PickVisualMedia.ImageOnly ) ) }, shape = RoundedCornerShape(10.dp), colors = ButtonDefaults.buttonColors(containerColor = LoveRedPrimary), modifier = Modifier.weight(1f).height(44.dp).testTag("upload_qr_button") ) { Icon(Icons.Default.CloudUpload, contentDescription = null, modifier = Modifier.size(18.dp)) Spacer(modifier = Modifier.width(6.dp)) Text(text = "Upload Custom QR", fontWeight = FontWeight.Bold, fontSize = 12.sp) } if (qrUriInput.isNotBlank()) { OutlinedButton( onClick = { qrUriInput = "" adminViewModel.updatePaymentQr(upiIdInput, "") savedMessage = "Reset to default QR code" }, shape = RoundedCornerShape(10.dp), modifier = Modifier.height(44.dp) ) { Icon(Icons.Default.Refresh, contentDescription = null, modifier = Modifier.size(16.dp)) Spacer(modifier = Modifier.width(4.dp)) Text("Reset", fontSize = 12.sp) } } } } } // UPI ID & Store Rules Configuration Card Card( shape = RoundedCornerShape(16.dp), colors = CardDefaults.cardColors(containerColor = Color.White), elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), modifier = Modifier.fillMaxWidth() ) { Column( modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(12.dp) ) { Text( text = "STORE & PAYMENT CONFIGURATION", fontWeight = FontWeight.Bold, fontSize = 12.sp, color = TextSecondary, letterSpacing = 1.sp ) OutlinedTextField( value = upiIdInput, onValueChange = { upiIdInput = it }, label = { Text("Restaurant UPI ID") }, placeholder = { Text("e.g. lovezonerestaurant@okaxis") }, singleLine = true, shape = RoundedCornerShape(10.dp), colors = OutlinedTextFieldDefaults.colors( focusedTextColor = Color(0xFF1E2022), unfocusedTextColor = Color(0xFF1E2022), focusedContainerColor = Color.White, unfocusedContainerColor = Color(0xFFF8FAFC), cursorColor = LoveRedPrimary, focusedBorderColor = LoveRedPrimary, unfocusedBorderColor = Color(0xFFCBD5E1) ), modifier = Modifier.fillMaxWidth().testTag("admin_upi_id_input") ) Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(10.dp) ) { OutlinedTextField( value = freeMinInput, onValueChange = { freeMinInput = it }, label = { Text("Free Delivery Min (₹)") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), singleLine = true, shape = RoundedCornerShape(10.dp), colors = OutlinedTextFieldDefaults.colors( focusedTextColor = Color(0xFF1E2022), unfocusedTextColor = Color(0xFF1E2022), focusedContainerColor = Color.White, unfocusedContainerColor = Color(0xFFF8FAFC), cursorColor = LoveRedPrimary, focusedBorderColor = LoveRedPrimary, unfocusedBorderColor = Color(0xFFCBD5E1) ), modifier = Modifier.weight(1f) ) OutlinedTextField( value = feeInput, onValueChange = { feeInput = it }, label = { Text("Delivery Fee (₹)") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), singleLine = true, shape = RoundedCornerShape(10.dp), colors = OutlinedTextFieldDefaults.colors( focusedTextColor = Color(0xFF1E2022), unfocusedTextColor = Color(0xFF1E2022), focusedContainerColor = Color.White, unfocusedContainerColor = Color(0xFFF8FAFC), cursorColor = LoveRedPrimary, focusedBorderColor = LoveRedPrimary, unfocusedBorderColor = Color(0xFFCBD5E1) ), modifier = Modifier.weight(1f) ) } OutlinedTextField( value = announcementInput, onValueChange = { announcementInput = it }, label = { Text("Top Header Announcement Banner") }, maxLines = 2, shape = RoundedCornerShape(10.dp), colors = OutlinedTextFieldDefaults.colors( focusedTextColor = Color(0xFF1E2022), unfocusedTextColor = Color(0xFF1E2022), focusedContainerColor = Color.White, unfocusedContainerColor = Color(0xFFF8FAFC), cursorColor = LoveRedPrimary, focusedBorderColor = LoveRedPrimary, unfocusedBorderColor = Color(0xFFCBD5E1) ), modifier = Modifier.fillMaxWidth() ) Spacer(modifier = Modifier.height(4.dp)) } } // Custom Domain & Name Server Settings Card Card( shape = RoundedCornerShape(16.dp), colors = CardDefaults.cardColors(containerColor = Color.White), elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), modifier = Modifier.fillMaxWidth() ) { Column( modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(12.dp) ) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp) ) { Box( modifier = Modifier .size(36.dp) .clip(RoundedCornerShape(8.dp)) .background(Color(0xFFE8F5E9)), contentAlignment = Alignment.Center ) { Icon( imageVector = Icons.Default.Language, contentDescription = "Domain & Server", tint = FreshVegGreen, modifier = Modifier.size(20.dp) ) } Column { Text( text = "Custom Domain & Name Server", fontWeight = FontWeight.Bold, fontSize = 15.sp, color = TextPrimary ) Text( text = "डोमेन और नेम सर्वर सेटिंग्स (Website / APK Download)", fontSize = 11.sp, color = TextSecondary ) } } HorizontalDivider(color = Color(0xFFF1F5F9)) OutlinedTextField( value = domainInput, onValueChange = { domainInput = it }, label = { Text("App Domain / Server URL") }, placeholder = { Text("https://lovezonerasturant.shop") }, singleLine = true, leadingIcon = { Icon(Icons.Default.Link, contentDescription = null, tint = LoveRedPrimary) }, shape = RoundedCornerShape(10.dp), colors = OutlinedTextFieldDefaults.colors( focusedTextColor = Color(0xFF1E2022), unfocusedTextColor = Color(0xFF1E2022), focusedContainerColor = Color.White, unfocusedContainerColor = Color(0xFFF8FAFC), cursorColor = LoveRedPrimary, focusedBorderColor = LoveRedPrimary, unfocusedBorderColor = Color(0xFFCBD5E1) ), modifier = Modifier.fillMaxWidth() ) // Current APK Direct Download Link val activeDownloadUrl = ShareAppHelper.getDownloadUrl() Surface( color = Color(0xFFF8FAFC), shape = RoundedCornerShape(10.dp), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFFE2E8F0)), modifier = Modifier.fillMaxWidth() ) { Row( modifier = Modifier .fillMaxWidth() .padding(12.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Column(modifier = Modifier.weight(1f)) { Text( text = "Active Direct Download Link", fontSize = 11.sp, fontWeight = FontWeight.Bold, color = TextSecondary ) Spacer(modifier = Modifier.height(2.dp)) Text( text = activeDownloadUrl, fontSize = 11.sp, fontWeight = FontWeight.Medium, color = TextPrimary ) } IconButton( onClick = { val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager clipboard?.setPrimaryClip(ClipData.newPlainText("APK Link", activeDownloadUrl)) Toast.makeText(context, "Download link copied! 📋", Toast.LENGTH_SHORT).show() } ) { Icon(Icons.Default.ContentCopy, contentDescription = "Copy Link", tint = LoveRedPrimary) } } } // Name Server & DNS Setup Instructions Surface( color = Color(0xFFFFF8E1), shape = RoundedCornerShape(10.dp), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFFFFE082)), modifier = Modifier.fillMaxWidth() ) { Column( modifier = Modifier.padding(12.dp), verticalArrangement = Arrangement.spacedBy(6.dp) ) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(6.dp) ) { Icon( imageVector = Icons.Default.Dns, contentDescription = "DNS Help", tint = Color(0xFFF57F17), modifier = Modifier.size(16.dp) ) Text( text = "Name Server / DNS Guide (नेम सर्वर कैसे सेट करें)", fontSize = 12.sp, fontWeight = FontWeight.Bold, color = Color(0xFFF57F17) ) } Text( text = "1. Agar aapne Godaddy / Hostinger / Namecheap se domain liya hai, to Cloudflare ya Registrar Default Nameservers use karein.\n" + "2. Apne domain ko APK download link par forward/redirect karein taaki koi bhi link khole to app turant download ho.\n" + "3. Yahan domain change karke 'SAVE ALL' dabaayein, sabhi customers aur WhatsApp share links turant update ho jayenge.", fontSize = 11.sp, color = Color(0xFF424242), lineHeight = 16.sp ) } } } } // Save All Button Button( onClick = { val min = freeMinInput.toDoubleOrNull() ?: 199.0 val fee = feeInput.toDoubleOrNull() ?: 30.0 adminViewModel.updatePaymentQr(upiIdInput, qrUriInput) adminViewModel.updateDeliverySettings(min, fee, announcementInput) adminViewModel.updateCustomDomain(domainInput) savedMessage = "All Payment, Delivery & Domain Settings updated successfully! 🎉" Toast.makeText(context, "Settings Saved!", Toast.LENGTH_SHORT).show() }, shape = RoundedCornerShape(10.dp), colors = ButtonDefaults.buttonColors(containerColor = LoveRedPrimary), modifier = Modifier .fillMaxWidth() .height(48.dp) .testTag("save_admin_settings_button") ) { Text( text = "SAVE ALL SETTINGS (पेमेंट, डिलीवरी व डोमेन सेव करें)", fontWeight = FontWeight.Bold, fontSize = 13.sp ) } } }