package com.example.ui.screens import androidx.compose.foundation.background import androidx.compose.foundation.clickable 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.layout.widthIn 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.Done import androidx.compose.material.icons.filled.DoneAll import androidx.compose.material.icons.filled.Send import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.FilterChip import androidx.compose.material3.FilterChipDefaults 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.Text import androidx.compose.runtime.Composable 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.platform.testTag 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.ConversationMessageEntity 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 java.text.SimpleDateFormat import java.util.Date import java.util.Locale @Composable fun CustomerInboxScreen( viewModel: MarketingViewModel, modifier: Modifier = Modifier ) { val messages by viewModel.conversations.collectAsStateWithLifecycle() val phones = messages.map { it.phone }.distinct() var selectedPhone by remember(phones) { mutableStateOf(phones.firstOrNull() ?: "") } var replyText by remember { mutableStateOf("") } val activeThread = messages.filter { it.phone == selectedPhone } val activeCustomer = activeThread.firstOrNull()?.customerName ?: "Customer" Column( modifier = modifier .fillMaxSize() .padding(horizontal = 16.dp) ) { Spacer(modifier = Modifier.height(8.dp)) // Phone Selector chips Text( text = "Customer Conversations (${phones.size})", fontWeight = FontWeight.Bold, fontSize = 15.sp, color = MaterialTheme.colorScheme.onSurface ) Spacer(modifier = Modifier.height(6.dp)) Row( modifier = Modifier .fillMaxWidth() .horizontalScroll(rememberScrollState()), horizontalArrangement = Arrangement.spacedBy(6.dp) ) { phones.forEach { ph -> val customerName = messages.firstOrNull { it.phone == ph }?.customerName ?: ph FilterChip( selected = selectedPhone == ph, onClick = { selectedPhone = ph }, label = { Text("$customerName ($ph)", fontSize = 11.sp) }, colors = FilterChipDefaults.filterChipColors( selectedContainerColor = EmeraldPrimary.copy(alpha = 0.15f), selectedLabelColor = EmeraldPrimary ) ) } } Spacer(modifier = Modifier.height(8.dp)) // Chat Box Canvas Card( modifier = Modifier .fillMaxWidth() .weight(1f), shape = RoundedCornerShape(16.dp), colors = CardDefaults.cardColors(containerColor = Color(0xFFEFEAE2)) // WhatsApp background ) { Column(modifier = Modifier.fillMaxSize()) { // Chat Header Row( modifier = Modifier .fillMaxWidth() .background(Color(0xFF075E54)) .padding(horizontal = 12.dp, vertical = 8.dp), verticalAlignment = Alignment.CenterVertically ) { Box( modifier = Modifier .size(34.dp) .clip(CircleShape) .background(Color.White), contentAlignment = Alignment.Center ) { Text( text = (activeCustomer.take(2)).uppercase(), color = Color(0xFF075E54), fontWeight = FontWeight.Bold, fontSize = 12.sp ) } Spacer(modifier = Modifier.width(10.dp)) Column { Text( text = activeCustomer, color = Color.White, fontWeight = FontWeight.Bold, fontSize = 13.sp ) Text( text = "$selectedPhone • 24hr Customer Service Window Active", color = Color(0xFFD4E7E4), fontSize = 10.sp ) } } // Messages list LazyColumn( modifier = Modifier .weight(1f) .padding(12.dp), verticalArrangement = Arrangement.spacedBy(8.dp) ) { items(activeThread) { msg -> ChatBubble(message = msg) } } // Quick reply suggestions Row( modifier = Modifier .fillMaxWidth() .background(Color.White) .padding(horizontal = 8.dp, vertical = 4.dp) .horizontalScroll(rememberScrollState()), horizontalArrangement = Arrangement.spacedBy(6.dp) ) { QuickChip("Send Quotation PDF") { replyText = "Hi $activeCustomer, here is our dealer quotation PDF: https://sunpower.example.com/quote-2026.pdf" } QuickChip("Confirm Site Visit") { replyText = "Our solar technical engineer has scheduled your site audit for tomorrow at 11 AM." } QuickChip("Dealer Margins") { replyText = "We offer 18% distributor margin on orders above 10 units with net-30 credit." } } // Reply input bar Row( modifier = Modifier .fillMaxWidth() .background(Color.White) .padding(8.dp), verticalAlignment = Alignment.CenterVertically ) { OutlinedTextField( value = replyText, onValueChange = { replyText = it }, placeholder = { Text("Type WhatsApp response...") }, modifier = Modifier .weight(1f) .testTag("chat_reply_input"), shape = RoundedCornerShape(24.dp), singleLine = true ) Spacer(modifier = Modifier.width(8.dp)) IconButton( onClick = { if (replyText.isNotBlank() && selectedPhone.isNotBlank()) { viewModel.sendSingleReply(selectedPhone, activeCustomer, replyText) replyText = "" } }, modifier = Modifier .size(44.dp) .clip(CircleShape) .background(EmeraldPrimary) .testTag("send_reply_button") ) { Icon(Icons.Default.Send, contentDescription = "Send", tint = Color.White) } } } } Spacer(modifier = Modifier.height(16.dp)) } } @Composable fun QuickChip(label: String, onClick: () -> Unit) { Surface( onClick = onClick, shape = RoundedCornerShape(12.dp), color = Color(0xFFF1F5F9) ) { Text( text = label, fontSize = 11.sp, color = Color(0xFF0F172A), modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp) ) } } @Composable fun ChatBubble(message: ConversationMessageEntity) { val isIncoming = message.isIncoming val alignment = if (isIncoming) Alignment.Start else Alignment.End val bubbleColor = if (isIncoming) Color.White else Color(0xFFD9FDD3) // WhatsApp outgoing light green val timeStr = SimpleDateFormat("hh:mm a", Locale.getDefault()).format(Date(message.timestamp)) Column( modifier = Modifier.fillMaxWidth(), horizontalAlignment = alignment ) { Column( modifier = Modifier .widthIn(max = 280.dp) .clip( RoundedCornerShape( topStart = 12.dp, topEnd = 12.dp, bottomStart = if (isIncoming) 0.dp else 12.dp, bottomEnd = if (isIncoming) 12.dp else 0.dp ) ) .background(bubbleColor) .padding(10.dp) ) { if (message.isInteractiveReply) { Surface( color = Color(0xFFE0F2FE), shape = RoundedCornerShape(6.dp), modifier = Modifier.padding(bottom = 6.dp) ) { Text( text = "Button Clicked: ${message.buttonPayload}", fontSize = 10.sp, fontWeight = FontWeight.Bold, color = Color(0xFF0284C7), modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp) ) } } Text( text = message.messageText, fontSize = 13.sp, color = Color(0xFF111B21), lineHeight = 17.sp ) Spacer(modifier = Modifier.height(4.dp)) Row( modifier = Modifier.align(Alignment.End), verticalAlignment = Alignment.CenterVertically ) { Text( text = timeStr, fontSize = 9.sp, color = Color.Gray ) if (!isIncoming) { Spacer(modifier = Modifier.width(4.dp)) Icon( imageVector = if (message.deliveryStatus == "READ") Icons.Default.DoneAll else Icons.Default.Done, contentDescription = null, tint = if (message.deliveryStatus == "READ") Color(0xFF53BDEB) else Color.Gray, modifier = Modifier.size(12.dp) ) } } } } }