package com.example.ui.screens import android.widget.Toast import androidx.compose.foundation.background import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column 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.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.AdminPanelSettings import androidx.compose.material.icons.filled.Block import androidx.compose.material.icons.filled.Business import androidx.compose.material.icons.filled.Category import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.CheckCircle import androidx.compose.material.icons.filled.History import androidx.compose.material.icons.filled.Person import androidx.compose.material.icons.filled.PowerSettingsNew import androidx.compose.material.icons.filled.Security import androidx.compose.material.icons.filled.Shield import androidx.compose.material.icons.filled.Subscriptions import androidx.compose.material.icons.filled.Verified import androidx.compose.material.icons.filled.Warning import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.ScrollableTabRow import androidx.compose.material3.Surface import androidx.compose.material3.Tab import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf 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.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.example.ui.components.CategoryPill import com.example.ui.components.StatusBadge import com.example.ui.theme.EmeraldDark import com.example.ui.theme.EmeraldLight import com.example.ui.theme.EmeraldPrimary import com.example.ui.viewmodel.MarketingViewModel import com.example.ui.viewmodel.UserRole import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @Composable fun AdminPanelScreen( viewModel: MarketingViewModel, modifier: Modifier = Modifier ) { val context = LocalContext.current val currentRole by viewModel.currentRole.collectAsStateWithLifecycle() val pendingContacts by viewModel.pendingContacts.collectAsStateWithLifecycle() val auditLogs by viewModel.auditLogs.collectAsStateWithLifecycle() val categories by viewModel.categories.collectAsStateWithLifecycle() val subscriptionPlans by viewModel.subscriptionPlans.collectAsStateWithLifecycle() val account by viewModel.account.collectAsStateWithLifecycle() val contacts by viewModel.contacts.collectAsStateWithLifecycle() val partners by viewModel.partners.collectAsStateWithLifecycle() var selectedAdminTab by remember { mutableIntStateOf(0) } var showAddCategoryModal by remember { mutableStateOf(false) } val optedOutContacts = contacts.filter { it.optInStatus == "OPTED_OUT" } Column( modifier = modifier .fillMaxSize() .padding(horizontal = 16.dp) ) { Spacer(modifier = Modifier.height(8.dp)) // Role & Governance Banner Card( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(14.dp), colors = CardDefaults.cardColors(containerColor = Color(0xFF1E293B)) ) { Row( modifier = Modifier.padding(14.dp), verticalAlignment = Alignment.CenterVertically ) { Box( modifier = Modifier .size(42.dp) .clip(CircleShape) .background(Color(0xFF334155)), contentAlignment = Alignment.Center ) { Icon( imageVector = Icons.Default.AdminPanelSettings, contentDescription = null, tint = EmeraldLight, modifier = Modifier.size(24.dp) ) } Spacer(modifier = Modifier.width(12.dp)) Column(modifier = Modifier.weight(1f)) { Row(verticalAlignment = Alignment.CenterVertically) { Text( text = if (currentRole == UserRole.SUPER_ADMIN) "Narada Super Admin Control" else "Narada Admin Operations", fontWeight = FontWeight.Bold, fontSize = 15.sp, color = Color.White ) Spacer(modifier = Modifier.width(6.dp)) StatusBadge(status = currentRole.name) } Text( text = "Multi-Tenant SaaS • Strict Data Isolation • Compliance Review", fontSize = 11.sp, color = Color(0xFF94A3B8) ) } } } Spacer(modifier = Modifier.height(10.dp)) // Tab Navigation ScrollableTabRow( selectedTabIndex = selectedAdminTab, edgePadding = 0.dp, containerColor = Color.Transparent, contentColor = EmeraldPrimary ) { Tab( selected = selectedAdminTab == 0, onClick = { selectedAdminTab = 0 }, text = { Text("Approvals (${pendingContacts.size})", fontSize = 11.sp) } ) Tab( selected = selectedAdminTab == 1, onClick = { selectedAdminTab = 1 }, text = { Text("Consumers / Tenants", fontSize = 11.sp) } ) Tab( selected = selectedAdminTab == 2, onClick = { selectedAdminTab = 2 }, text = { Text("Categories", fontSize = 11.sp) } ) Tab( selected = selectedAdminTab == 3, onClick = { selectedAdminTab = 3 }, text = { Text("Subscriptions", fontSize = 11.sp) } ) Tab( selected = selectedAdminTab == 4, onClick = { selectedAdminTab = 4 }, text = { Text("Compliance Centre (${optedOutContacts.size})", fontSize = 11.sp) } ) Tab( selected = selectedAdminTab == 5, onClick = { selectedAdminTab = 5 }, text = { Text("Audit Trail", fontSize = 11.sp) } ) } Spacer(modifier = Modifier.height(12.dp)) when (selectedAdminTab) { 0 -> { // Approvals View (Contact Import Review Queue) Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Text( text = "Pending Contact Submissions (${pendingContacts.size})", fontWeight = FontWeight.Bold, fontSize = 15.sp ) if (pendingContacts.isNotEmpty()) { Button( onClick = { viewModel.approveAllPendingContacts() }, colors = ButtonDefaults.buttonColors(containerColor = EmeraldPrimary), shape = RoundedCornerShape(8.dp) ) { Text("Approve All", fontSize = 11.sp) } } } Spacer(modifier = Modifier.height(8.dp)) if (pendingContacts.isEmpty()) { Box( modifier = Modifier .fillMaxSize() .weight(1f), contentAlignment = Alignment.Center ) { Column(horizontalAlignment = Alignment.CenterHorizontally) { Icon(Icons.Default.CheckCircle, contentDescription = null, tint = EmeraldPrimary, modifier = Modifier.size(40.dp)) Spacer(modifier = Modifier.height(8.dp)) Text("All uploaded contacts are reviewed and approved!", fontSize = 13.sp, color = MaterialTheme.colorScheme.onSurfaceVariant) } } } else { LazyColumn( modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(10.dp) ) { items(pendingContacts) { contact -> Card( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(10.dp), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface) ) { Column(modifier = Modifier.padding(12.dp)) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Column { if (contact.customerName.isNotBlank()) { Text(contact.customerName, fontWeight = FontWeight.Bold, fontSize = 14.sp) Text("Mobile: ${contact.e164Phone}", fontSize = 12.sp, color = EmeraldPrimary, fontFamily = FontFamily.Monospace) val loc = listOf(contact.district.ifBlank { contact.city }, contact.state, contact.pinCode).filter { it.isNotBlank() } if (loc.isNotEmpty()) { Text("Location: ${loc.joinToString(", ")}", fontSize = 11.sp, color = Color.Gray) } } else { Text("Mobile: ${contact.e164Phone}", fontWeight = FontWeight.Bold, fontSize = 14.sp, fontFamily = FontFamily.Monospace) val dist = contact.district.ifBlank { contact.city } if (dist.isNotBlank()) { Text("District: $dist", fontSize = 12.sp, color = Color.Gray) } } } StatusBadge(status = "PENDING_REVIEW") } Spacer(modifier = Modifier.height(6.dp)) Text( text = "Source: ${contact.consentSource} • Opt-In: ${contact.consentDate}", fontSize = 10.sp, color = MaterialTheme.colorScheme.onSurfaceVariant ) Spacer(modifier = Modifier.height(8.dp)) Button( onClick = { viewModel.approveContact(contact.id) }, modifier = Modifier.fillMaxWidth(), colors = ButtonDefaults.buttonColors(containerColor = EmeraldPrimary), shape = RoundedCornerShape(8.dp) ) { Icon(Icons.Default.Check, contentDescription = null, modifier = Modifier.size(14.dp)) Spacer(modifier = Modifier.width(6.dp)) Text("Verify Consent & Approve", fontSize = 11.sp) } } } } item { Spacer(modifier = Modifier.height(20.dp)) } } } } 1 -> { // Consumers / Tenants Management (Super Admin Web Screens 1 & 2) LazyColumn( modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(12.dp) ) { item { Text( text = "Registered Business Consumers & Tenants", fontWeight = FontWeight.Bold, fontSize = 15.sp ) Spacer(modifier = Modifier.height(4.dp)) Text( text = "Manage multi-tenant business accounts, subscription states, Meta WABA connections, and quota limits.", fontSize = 11.sp, color = MaterialTheme.colorScheme.onSurfaceVariant ) } item { // Current Primary Business Consumer Card account?.let { acc -> Card( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(12.dp), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) ) { Column(modifier = Modifier.padding(14.dp)) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Row(verticalAlignment = Alignment.CenterVertically) { Icon(Icons.Default.Business, contentDescription = null, tint = EmeraldPrimary, modifier = Modifier.size(24.dp)) Spacer(modifier = Modifier.width(8.dp)) Column { Text(acc.businessName, fontWeight = FontWeight.Bold, fontSize = 15.sp) Text("Tenant ID: primary_tenant • ${acc.subscriptionPlan} Plan", fontSize = 11.sp, color = Color.Gray) } } StatusBadge(status = acc.status) } Spacer(modifier = Modifier.height(10.dp)) Text("• WABA ID: ${acc.metaWabaId}", fontSize = 11.sp, fontFamily = FontFamily.Monospace) Text("• Phone Number ID: ${acc.metaPhoneNumberId}", fontSize = 11.sp, fontFamily = FontFamily.Monospace) Text("• Monthly Quota: ${acc.quotaUsed} / ${acc.quotaLimit} messages", fontSize = 11.sp) Text("• Webhook Verified: ${if (acc.webhookVerified) "YES" else "NO"}", fontSize = 11.sp, color = EmeraldDark) Spacer(modifier = Modifier.height(10.dp)) Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp) ) { val isActive = acc.status == "ACTIVE" Button( onClick = { viewModel.toggleAccountStatus(!isActive) }, modifier = Modifier.weight(1f), colors = ButtonDefaults.buttonColors( containerColor = if (isActive) Color(0xFFE11D48) else EmeraldPrimary ), shape = RoundedCornerShape(8.dp) ) { Icon(Icons.Default.PowerSettingsNew, contentDescription = null, modifier = Modifier.size(14.dp)) Spacer(modifier = Modifier.width(4.dp)) Text(if (isActive) "Suspend Account" else "Activate Account", fontSize = 11.sp) } } } } } } item { // Additional tenant business accounts in system Text( text = "Other Registered Consumer Workspaces", fontWeight = FontWeight.Bold, fontSize = 13.sp ) } val demoTenants = listOf( Triple("Apex Solar Energy LLP", "ACTIVE", "WABA: 948271039485721"), Triple("Kaveri Agritech Ltd", "ACTIVE", "WABA: 817263549102938"), Triple("Vertex Hardware Store", "PENDING_APPROVAL", "WABA: 729183049182746") ) items(demoTenants) { (name, status, waba) -> Card( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(10.dp), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface) ) { Row( modifier = Modifier.padding(12.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Column(modifier = Modifier.weight(1f)) { Text(name, fontWeight = FontWeight.SemiBold, fontSize = 13.sp) Text(waba, fontSize = 10.sp, color = Color.Gray, fontFamily = FontFamily.Monospace) } StatusBadge(status = status) } } } item { Spacer(modifier = Modifier.height(20.dp)) } } } 2 -> { // Category Management (Web Screen 5) Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Text( text = "Business Categories (${categories.size})", fontWeight = FontWeight.Bold, fontSize = 15.sp ) Button( onClick = { showAddCategoryModal = true }, colors = ButtonDefaults.buttonColors(containerColor = EmeraldPrimary), shape = RoundedCornerShape(8.dp) ) { Text("+ New Category", fontSize = 11.sp) } } Spacer(modifier = Modifier.height(10.dp)) LazyColumn( modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(8.dp) ) { items(categories) { cat -> Card( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(10.dp), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface) ) { Row( modifier = Modifier.padding(14.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Column(modifier = Modifier.weight(1f)) { CategoryPill(name = cat.name, colorHex = cat.colorHex) Spacer(modifier = Modifier.height(4.dp)) Text(cat.description, fontSize = 11.sp, color = MaterialTheme.colorScheme.onSurfaceVariant) } StatusBadge(status = if (cat.isActive) "ACTIVE" else "INACTIVE") } } } item { Spacer(modifier = Modifier.height(20.dp)) } } } 3 -> { // Subscription Plans Text( text = "Platform Subscription Tiers & WhatsApp Quotas", fontWeight = FontWeight.Bold, fontSize = 15.sp ) Spacer(modifier = Modifier.height(10.dp)) LazyColumn( modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(10.dp) ) { items(subscriptionPlans) { plan -> Card( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(12.dp), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface) ) { Column(modifier = Modifier.padding(14.dp)) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Text(plan.name, fontWeight = FontWeight.Bold, fontSize = 16.sp) Text("₹ ${plan.monthlyPrice.toInt()} / mo", fontWeight = FontWeight.Bold, color = EmeraldPrimary, fontSize = 15.sp) } Spacer(modifier = Modifier.height(6.dp)) Text( text = "Monthly Quota: ${plan.messageQuota} messages • Contact Limit: ${plan.contactLimit} • ${plan.seats} seats", fontSize = 12.sp, color = MaterialTheme.colorScheme.onSurfaceVariant ) Spacer(modifier = Modifier.height(4.dp)) Text( text = "Features: ${plan.features}", fontSize = 11.sp, color = Color(0xFF64748B) ) } } } item { Spacer(modifier = Modifier.height(20.dp)) } } } 4 -> { // Compliance Centre & Opt-out Processing (Web Screen 6) LazyColumn( modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(10.dp) ) { item { Card( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(10.dp), colors = CardDefaults.cardColors(containerColor = Color(0xFFF0FDF4)) ) { Column(modifier = Modifier.padding(12.dp)) { Row(verticalAlignment = Alignment.CenterVertically) { Icon(Icons.Default.Shield, contentDescription = null, tint = EmeraldPrimary, modifier = Modifier.size(20.dp)) Spacer(modifier = Modifier.width(6.dp)) Text("Meta Zero-Spam & Consumer Consent Policy", fontWeight = FontWeight.Bold, fontSize = 13.sp, color = Color(0xFF166534)) } Spacer(modifier = Modifier.height(4.dp)) Text("• Messages dispatched strictly to Consumer lists with verifiable opt-in.", fontSize = 11.sp, color = Color(0xFF166534)) Text("• Automatic suppression triggered on incoming STOP or UNSUBSCRIBE webhooks.", fontSize = 11.sp, color = Color(0xFF166534)) Text("• Excludes vendors, retailers and third-parties without direct consumer consent.", fontSize = 11.sp, color = Color(0xFF166534)) } } } item { Text( text = "Suppressed / Opted-Out Contacts (${optedOutContacts.size})", fontWeight = FontWeight.Bold, fontSize = 14.sp ) } if (optedOutContacts.isEmpty()) { item { Surface( color = MaterialTheme.colorScheme.surface, shape = RoundedCornerShape(8.dp), modifier = Modifier.fillMaxWidth() ) { Row( modifier = Modifier.padding(16.dp), verticalAlignment = Alignment.CenterVertically ) { Icon(Icons.Default.CheckCircle, contentDescription = null, tint = EmeraldPrimary) Spacer(modifier = Modifier.width(8.dp)) Text("No opted-out contacts recorded. High account quality rating.", fontSize = 12.sp) } } } } else { items(optedOutContacts) { contact -> Card( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(8.dp), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface) ) { Row( modifier = Modifier.padding(12.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Column { Text(contact.e164Phone, fontWeight = FontWeight.Bold, fontSize = 13.sp, fontFamily = FontFamily.Monospace) Text("Suppression Reason: Opt-Out Request", fontSize = 10.sp, color = Color(0xFFE11D48)) } StatusBadge(status = "OPTED_OUT") } } } } item { Spacer(modifier = Modifier.height(20.dp)) } } } 5 -> { // Permanent Audit Trail Text( text = "Security Audit Trail & Governance", fontWeight = FontWeight.Bold, fontSize = 15.sp ) Spacer(modifier = Modifier.height(8.dp)) LazyColumn( modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(8.dp) ) { items(auditLogs) { log -> val dateStr = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date(log.timestamp)) Card( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(8.dp), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface) ) { Column(modifier = Modifier.padding(10.dp)) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { Text( text = log.actionType, fontWeight = FontWeight.Bold, fontSize = 12.sp, fontFamily = FontFamily.Monospace, color = EmeraldPrimary ) Text(dateStr, fontSize = 10.sp, color = Color.Gray) } Spacer(modifier = Modifier.height(2.dp)) Text(log.description, fontSize = 11.sp, color = MaterialTheme.colorScheme.onSurface) Text("Actor Role: ${log.actorRole}", fontSize = 10.sp, color = Color(0xFF94A3B8)) } } } item { Spacer(modifier = Modifier.height(20.dp)) } } } } } if (showAddCategoryModal) { var catName by remember { mutableStateOf("") } var catDesc by remember { mutableStateOf("") } var catColor by remember { mutableStateOf("#008069") } AlertDialog( onDismissRequest = { showAddCategoryModal = false }, title = { Text("Create New Category") }, text = { Column( modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp) ) { OutlinedTextField( value = catName, onValueChange = { catName = it }, label = { Text("Category Name *") }, singleLine = true, modifier = Modifier.fillMaxWidth() ) OutlinedTextField( value = catDesc, onValueChange = { catDesc = it }, label = { Text("Description") }, modifier = Modifier.fillMaxWidth() ) } }, confirmButton = { Button( onClick = { if (catName.isNotBlank()) { viewModel.addCategory(catName, catDesc, catColor) showAddCategoryModal = false } }, colors = ButtonDefaults.buttonColors(containerColor = EmeraldPrimary) ) { Text("Save Category") } }, dismissButton = { TextButton(onClick = { showAddCategoryModal = false }) { Text("Cancel") } } ) } }