package com.example.ui.screens import android.widget.Toast import androidx.compose.foundation.background 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.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Business import androidx.compose.material.icons.filled.CheckCircle import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Handshake import androidx.compose.material.icons.filled.PauseCircle import androidx.compose.material.icons.filled.Phone import androidx.compose.material.icons.filled.Place import androidx.compose.material.icons.filled.Search 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.FilterChip import androidx.compose.material3.FilterChipDefaults import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface import androidx.compose.material3.Switch import androidx.compose.material3.SwitchDefaults 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.data.local.entity.PartnerEntity import com.example.ui.theme.EmeraldDark import com.example.ui.theme.EmeraldLight import com.example.ui.theme.EmeraldPrimary import com.example.ui.viewmodel.MarketingViewModel @Composable fun PartnerManagementScreen( viewModel: MarketingViewModel, modifier: Modifier = Modifier ) { val context = LocalContext.current val partners by viewModel.partners.collectAsStateWithLifecycle() val account by viewModel.account.collectAsStateWithLifecycle() var showAddDialog by remember { mutableStateOf(false) } var partnerToDelete by remember { mutableStateOf(null) } var searchQuery by remember { mutableStateOf("") } var filterTab by remember { mutableIntStateOf(0) } // 0: All, 1: Active, 2: Deactive val isAccountActive = account?.status == "ACTIVE" val filteredPartners = partners.filter { p -> val matchesSearch = searchQuery.isBlank() || p.name.contains(searchQuery, ignoreCase = true) || p.mobileNumber.contains(searchQuery) || p.district.contains(searchQuery, ignoreCase = true) || p.organization.contains(searchQuery, ignoreCase = true) val matchesStatus = when (filterTab) { 1 -> p.isActive 2 -> !p.isActive else -> true } matchesSearch && matchesStatus } Box(modifier = modifier.fillMaxSize()) { Column( modifier = Modifier .fillMaxSize() .padding(horizontal = 16.dp) ) { Spacer(modifier = Modifier.height(10.dp)) // Account Active / Deactive Global Controller Card Card( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(14.dp), colors = CardDefaults.cardColors( containerColor = if (isAccountActive) Color(0xFFF0FDF4) else Color(0xFFFEF2F2) ), elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) ) { Row( modifier = Modifier.padding(14.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.weight(1f) ) { Box( modifier = Modifier .size(40.dp) .clip(CircleShape) .background(if (isAccountActive) EmeraldPrimary else Color(0xFFE11D48)), contentAlignment = Alignment.Center ) { Icon( imageVector = if (isAccountActive) Icons.Default.CheckCircle else Icons.Default.PauseCircle, contentDescription = null, tint = Color.White, modifier = Modifier.size(22.dp) ) } Spacer(modifier = Modifier.width(12.dp)) Column { Row(verticalAlignment = Alignment.CenterVertically) { Text( text = "System Status: ", fontWeight = FontWeight.Bold, fontSize = 14.sp ) Text( text = if (isAccountActive) "ACTIVE" else "DEACTIVE", fontWeight = FontWeight.Bold, fontSize = 14.sp, color = if (isAccountActive) EmeraldPrimary else Color(0xFFE11D48) ) } Text( text = if (isAccountActive) "Messaging & operations running normally" else "Broadcasting & partner operations paused", fontSize = 11.sp, color = MaterialTheme.colorScheme.onSurfaceVariant ) } } Switch( checked = isAccountActive, onCheckedChange = { newState -> viewModel.toggleAccountStatus(newState) }, colors = SwitchDefaults.colors( checkedThumbColor = Color.White, checkedTrackColor = EmeraldPrimary, uncheckedThumbColor = Color.White, uncheckedTrackColor = Color(0xFF94A3B8) ), modifier = Modifier.testTag("account_active_switch") ) } } Spacer(modifier = Modifier.height(14.dp)) // Partner Management Header & Search Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Row(verticalAlignment = Alignment.CenterVertically) { Icon( imageVector = Icons.Default.Handshake, contentDescription = null, tint = EmeraldPrimary, modifier = Modifier.size(20.dp) ) Spacer(modifier = Modifier.width(6.dp)) Text( text = "Partner Management (${partners.size})", fontWeight = FontWeight.Bold, fontSize = 16.sp ) } Surface( shape = RoundedCornerShape(12.dp), color = EmeraldPrimary.copy(alpha = 0.12f) ) { Text( text = "${partners.count { it.isActive }} Active", fontSize = 11.sp, fontWeight = FontWeight.Bold, color = EmeraldDark, modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp) ) } } Spacer(modifier = Modifier.height(8.dp)) // Search Bar OutlinedTextField( value = searchQuery, onValueChange = { searchQuery = it }, placeholder = { Text("Search partner name, mobile, district...") }, leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) }, singleLine = true, shape = RoundedCornerShape(12.dp), modifier = Modifier .fillMaxWidth() .testTag("search_partner_input") ) Spacer(modifier = Modifier.height(8.dp)) // Filter Chips: All, Active, Deactive Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp) ) { FilterChip( selected = filterTab == 0, onClick = { filterTab = 0 }, label = { Text("All (${partners.size})", fontSize = 11.sp) }, colors = FilterChipDefaults.filterChipColors( selectedContainerColor = EmeraldPrimary.copy(alpha = 0.15f), selectedLabelColor = EmeraldPrimary ) ) FilterChip( selected = filterTab == 1, onClick = { filterTab = 1 }, label = { Text("Active (${partners.count { it.isActive }})", fontSize = 11.sp) }, colors = FilterChipDefaults.filterChipColors( selectedContainerColor = EmeraldPrimary.copy(alpha = 0.15f), selectedLabelColor = EmeraldPrimary ) ) FilterChip( selected = filterTab == 2, onClick = { filterTab = 2 }, label = { Text("Deactive (${partners.count { !it.isActive }})", fontSize = 11.sp) }, colors = FilterChipDefaults.filterChipColors( selectedContainerColor = Color(0xFFFFE4E6), selectedLabelColor = Color(0xFFE11D48) ) ) } Spacer(modifier = Modifier.height(8.dp)) // Partners List if (filteredPartners.isEmpty()) { Box( modifier = Modifier .fillMaxSize() .weight(1f), contentAlignment = Alignment.Center ) { Text("No partners found matching criteria.", color = Color.Gray) } } else { LazyColumn( modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(10.dp) ) { items(filteredPartners) { partner -> PartnerItemCard( partner = partner, onToggleActive = { active -> viewModel.togglePartnerActive(partner.id, active) }, onDelete = { partnerToDelete = partner } ) } item { Spacer(modifier = Modifier.height(80.dp)) } } } } // Floating Action Button to Add Partner FloatingActionButton( onClick = { showAddDialog = true }, modifier = Modifier .align(Alignment.BottomEnd) .padding(20.dp) .testTag("add_partner_fab"), containerColor = EmeraldPrimary, contentColor = Color.White ) { Icon(Icons.Default.Add, contentDescription = "Add Partner") } // Add Partner Dialog if (showAddDialog) { AddPartnerDialog( onDismiss = { showAddDialog = false }, onAdd = { newPartner -> viewModel.addPartner(newPartner) showAddDialog = false Toast.makeText(context, "Partner '${newPartner.name}' created!", Toast.LENGTH_SHORT).show() } ) } // Delete Partner Confirmation Dialog partnerToDelete?.let { partner -> AlertDialog( onDismissRequest = { partnerToDelete = null }, title = { Text("Remove Partner") }, text = { Text("Are you sure you want to remove partner '${partner.name}' (${partner.district})?") }, confirmButton = { Button( onClick = { viewModel.deletePartner(partner) partnerToDelete = null }, colors = ButtonDefaults.buttonColors(containerColor = Color(0xFFE11D48)) ) { Text("Remove") } }, dismissButton = { TextButton(onClick = { partnerToDelete = null }) { Text("Cancel") } } ) } } } @Composable fun PartnerItemCard( partner: PartnerEntity, onToggleActive: (Boolean) -> Unit, onDelete: () -> Unit ) { 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.Top ) { Column(modifier = Modifier.weight(1f)) { Text( text = partner.name, fontWeight = FontWeight.Bold, fontSize = 15.sp, color = MaterialTheme.colorScheme.onSurface ) if (partner.organization.isNotBlank()) { Text( text = partner.organization, fontSize = 12.sp, color = MaterialTheme.colorScheme.onSurfaceVariant ) } Spacer(modifier = Modifier.height(2.dp)) Row(verticalAlignment = Alignment.CenterVertically) { Icon( imageVector = Icons.Default.Phone, contentDescription = null, tint = EmeraldPrimary, modifier = Modifier.size(13.dp) ) Spacer(modifier = Modifier.width(4.dp)) Text( text = partner.mobileNumber, fontSize = 12.sp, fontFamily = FontFamily.Monospace, fontWeight = FontWeight.SemiBold, color = EmeraldPrimary ) } } // Active / Deactive Switch Column(horizontalAlignment = Alignment.End) { Row(verticalAlignment = Alignment.CenterVertically) { Text( text = if (partner.isActive) "Active" else "Deactive", fontSize = 11.sp, fontWeight = FontWeight.Bold, color = if (partner.isActive) EmeraldDark else Color(0xFFE11D48) ) Spacer(modifier = Modifier.width(6.dp)) Switch( checked = partner.isActive, onCheckedChange = onToggleActive, colors = SwitchDefaults.colors( checkedThumbColor = Color.White, checkedTrackColor = EmeraldPrimary, uncheckedThumbColor = Color.White, uncheckedTrackColor = Color(0xFF94A3B8) ) ) } } } Spacer(modifier = Modifier.height(8.dp)) // District, State, PIN and Partner Type Row Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { Row(verticalAlignment = Alignment.CenterVertically) { Icon( imageVector = Icons.Default.Place, contentDescription = null, tint = Color.Gray, modifier = Modifier.size(13.dp) ) Spacer(modifier = Modifier.width(4.dp)) val loc = listOf(partner.district, partner.state, partner.pinCode).filter { it.isNotBlank() } Text( text = if (loc.isNotEmpty()) loc.joinToString(", ") else "Location Unspecified", fontSize = 12.sp, color = MaterialTheme.colorScheme.onSurfaceVariant ) } Row(verticalAlignment = Alignment.CenterVertically) { Surface( shape = RoundedCornerShape(8.dp), color = Color(0xFFE0F2FE) ) { Text( text = partner.partnerType, fontSize = 10.sp, fontWeight = FontWeight.SemiBold, color = Color(0xFF0369A1), modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp) ) } Spacer(modifier = Modifier.width(8.dp)) IconButton( onClick = onDelete, modifier = Modifier.size(28.dp) ) { Icon( imageVector = Icons.Default.Delete, contentDescription = "Remove Partner", tint = Color(0xFFEF4444), modifier = Modifier.size(18.dp) ) } } } } } } @Composable fun AddPartnerDialog( onDismiss: () -> Unit, onAdd: (PartnerEntity) -> Unit ) { var name by remember { mutableStateOf("") } var organization by remember { mutableStateOf("") } var mobile by remember { mutableStateOf("") } var district by remember { mutableStateOf("") } var state by remember { mutableStateOf("") } var pinCode by remember { mutableStateOf("") } var partnerType by remember { mutableStateOf("Channel Partner") } AlertDialog( onDismissRequest = onDismiss, title = { Row(verticalAlignment = Alignment.CenterVertically) { Icon(Icons.Default.Business, contentDescription = null, tint = EmeraldPrimary) Spacer(modifier = Modifier.width(8.dp)) Text("Add Business Partner") } }, text = { Column( modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp) ) { OutlinedTextField( value = name, onValueChange = { name = it }, label = { Text("Partner Name *") }, singleLine = true, modifier = Modifier.fillMaxWidth() ) OutlinedTextField( value = organization, onValueChange = { organization = it }, label = { Text("Business / Firm Name") }, singleLine = true, modifier = Modifier.fillMaxWidth() ) OutlinedTextField( value = mobile, onValueChange = { mobile = it }, label = { Text("Mobile Number (10 digits) *") }, singleLine = true, modifier = Modifier.fillMaxWidth() ) Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp) ) { OutlinedTextField( value = district, onValueChange = { district = it }, label = { Text("District *") }, singleLine = true, modifier = Modifier.weight(1f) ) OutlinedTextField( value = state, onValueChange = { state = it }, label = { Text("State") }, singleLine = true, modifier = Modifier.weight(1f) ) } OutlinedTextField( value = pinCode, onValueChange = { pinCode = it }, label = { Text("PIN Code") }, singleLine = true, modifier = Modifier.fillMaxWidth() ) Text("Partner Type:", fontSize = 11.sp, fontWeight = FontWeight.SemiBold) Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(6.dp) ) { listOf("Channel Partner", "Distributor", "Franchise").forEach { type -> FilterChip( selected = partnerType == type, onClick = { partnerType = type }, label = { Text(type, fontSize = 10.sp) } ) } } } }, confirmButton = { Button( onClick = { if (name.isNotBlank() && mobile.isNotBlank()) { val cleanMobile = if (mobile.startsWith("+")) mobile else "+91${mobile.takeLast(10)}" onAdd( PartnerEntity( name = name.trim(), organization = organization.trim(), mobileNumber = cleanMobile, district = district.trim(), state = state.trim(), pinCode = pinCode.trim(), partnerType = partnerType, isActive = true ) ) } }, colors = ButtonDefaults.buttonColors(containerColor = EmeraldPrimary) ) { Text("Save Partner") } }, dismissButton = { TextButton(onClick = onDismiss) { Text("Cancel") } } ) }