package com.example.ui.admin import androidx.compose.foundation.background 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.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.Call import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.DeliveryDining import androidx.compose.material.icons.filled.LocationOn import androidx.compose.material.icons.filled.Person import androidx.compose.material.icons.filled.Restaurant 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.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton 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.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 com.example.data.model.DeliveryRider import com.example.data.model.Order import com.example.data.model.OrderStatus import com.example.data.model.RiderStatus import com.example.ui.components.VegNonVegBadge import com.example.ui.customer.OrderStatusBadge 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 java.text.SimpleDateFormat import java.util.Date import java.util.Locale @Composable fun AdminOrdersScreen( adminViewModel: AdminViewModel, modifier: Modifier = Modifier ) { val orders by adminViewModel.orders.collectAsState() val riders by adminViewModel.allRiders.collectAsState() var filterStatus by remember { mutableStateOf("ALL") } var orderToAssignRider by remember { mutableStateOf(null) } val filteredOrders = orders.filter { when (filterStatus) { "ACTIVE" -> it.orderStatus != OrderStatus.DELIVERED && it.orderStatus != OrderStatus.CANCELLED "DELIVERED" -> it.orderStatus == OrderStatus.DELIVERED else -> true } } Column( modifier = modifier .fillMaxSize() .padding(horizontal = 16.dp, vertical = 8.dp) ) { // Filter tabs Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp) ) { listOf("ALL" to "All (${orders.size})", "ACTIVE" to "Active (${orders.count { it.orderStatus != OrderStatus.DELIVERED && it.orderStatus != OrderStatus.CANCELLED }})", "DELIVERED" to "Delivered (${orders.count { it.orderStatus == OrderStatus.DELIVERED }})").forEach { (key, label) -> Surface( color = if (filterStatus == key) LoveRedPrimary else Color.White, shape = RoundedCornerShape(10.dp), border = androidx.compose.foundation.BorderStroke(1.dp, if (filterStatus == key) LoveRedPrimary else Color(0xFFE2E8F0)), modifier = Modifier.clickable { filterStatus = key } ) { Text( text = label, fontSize = 12.sp, fontWeight = FontWeight.Bold, color = if (filterStatus == key) Color.White else TextPrimary, modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp) ) } } } Spacer(modifier = Modifier.height(12.dp)) if (filteredOrders.isEmpty()) { Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { Text(text = "No orders found in this filter", color = TextSecondary, fontSize = 14.sp) } } else { LazyColumn( modifier = Modifier.fillMaxSize(), contentPadding = PaddingValues(bottom = 72.dp), verticalArrangement = Arrangement.spacedBy(12.dp) ) { items(filteredOrders) { order -> AdminOrderCard( order = order, onUpdateStatus = { newStatus -> adminViewModel.updateOrderStatus(order.orderId, newStatus) }, onAssignRiderClick = { orderToAssignRider = order }, onVerifyPayment = { adminViewModel.verifyPayment(order.orderId, order.upiTransactionId.ifBlank { "UPI-REC-${System.currentTimeMillis() % 10000}" }) } ) } } } } // Assign Rider Modal orderToAssignRider?.let { order -> AssignRiderDialog( order = order, riders = riders, onDismiss = { orderToAssignRider = null }, onAssign = { rider -> adminViewModel.assignRiderToOrder(order.orderId, rider) orderToAssignRider = null } ) } } @Composable fun AdminOrderCard( order: Order, onUpdateStatus: (OrderStatus) -> Unit, onAssignRiderClick: () -> Unit, onVerifyPayment: () -> Unit = {} ) { val dateStr = SimpleDateFormat("dd MMM, hh:mm a", Locale.getDefault()).format(Date(order.timestamp)) Card( shape = RoundedCornerShape(16.dp), colors = CardDefaults.cardColors(containerColor = Color.White), elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), modifier = Modifier.fillMaxWidth().testTag("admin_order_card_${order.orderId}") ) { Column(modifier = Modifier.padding(14.dp)) { // Header Row: Order ID, Time & Status Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Column { Text(text = order.orderId, fontWeight = FontWeight.Black, fontSize = 14.sp, color = TextPrimary) Text(text = dateStr, fontSize = 11.sp, color = TextSecondary) } OrderStatusBadge(status = order.orderStatus) } HorizontalDivider(color = Color(0xFFF1F5F9), modifier = Modifier.padding(vertical = 8.dp)) // Customer Info Row(verticalAlignment = Alignment.CenterVertically) { Icon(Icons.Default.LocationOn, contentDescription = null, tint = LoveRedPrimary, modifier = Modifier.size(16.dp)) Spacer(modifier = Modifier.width(6.dp)) Column { Text( text = "${order.customerName} • ${order.customerPhone}", fontWeight = FontWeight.Bold, fontSize = 13.sp, color = TextPrimary ) Text( text = order.deliveryAddress, fontSize = 11.sp, color = TextSecondary ) } } // Assigned Rider Info if assigned if (order.assignedRiderName.isNotBlank()) { Spacer(modifier = Modifier.height(6.dp)) Surface( color = Color(0xFFE8F5E9), shape = RoundedCornerShape(8.dp), modifier = Modifier.fillMaxWidth() ) { Row( modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp), verticalAlignment = Alignment.CenterVertically ) { Icon(Icons.Default.DeliveryDining, contentDescription = null, tint = FreshVegGreen, modifier = Modifier.size(16.dp)) Spacer(modifier = Modifier.width(6.dp)) Text( text = "Rider: ${order.assignedRiderName} (${order.assignedRiderVehicle}) • ${order.assignedRiderPhone}", fontSize = 11.sp, fontWeight = FontWeight.Bold, color = FreshVegGreen ) } } } Spacer(modifier = Modifier.height(8.dp)) // Ordered Items Surface( color = Color(0xFFF8FAFC), shape = RoundedCornerShape(8.dp), modifier = Modifier.fillMaxWidth() ) { Column(modifier = Modifier.padding(10.dp)) { order.items.forEach { item -> Row( modifier = Modifier.fillMaxWidth().padding(vertical = 2.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Row(verticalAlignment = Alignment.CenterVertically) { VegNonVegBadge(isVeg = item.isVeg, size = 10.dp) Spacer(modifier = Modifier.width(6.dp)) Text(text = "${item.quantity} x ${item.foodName}", fontSize = 12.sp, color = TextPrimary) } Text(text = "₹${(item.price * item.quantity).toInt()}", fontSize = 12.sp, fontWeight = FontWeight.SemiBold) } } } } Spacer(modifier = Modifier.height(8.dp)) // Bill & Payment status Spacer(modifier = Modifier.height(6.dp)) if (order.paymentMethod != "CASH_ON_DELIVERY") { val isPaymentVerified = order.paymentStatus == "CUSTOMER_PAYMENT_RECEIVED" || order.paymentStatus == "PAID" Surface( color = if (isPaymentVerified) Color(0xFFE8F5E9) else Color(0xFFFFF3E0), shape = RoundedCornerShape(10.dp), border = androidx.compose.foundation.BorderStroke(1.dp, if (isPaymentVerified) FreshVegGreen else Color(0xFFFF9800)), modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp) ) { Column(modifier = Modifier.padding(10.dp)) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth() ) { Text( text = if (isPaymentVerified) "✅ CUSTOMER PAYMENT RECEIVED: ₹${order.grandTotal.toInt()}" else "⏳ ONLINE PAYMENT PENDING: ₹${order.grandTotal.toInt()}", fontWeight = FontWeight.Bold, fontSize = 12.sp, color = if (isPaymentVerified) FreshVegGreen else Color(0xFFE65100) ) Surface( color = if (isPaymentVerified) FreshVegGreen else Color(0xFFFF9800), shape = RoundedCornerShape(6.dp) ) { Text( text = if (isPaymentVerified) "PAID" else "PENDING", color = Color.White, fontSize = 10.sp, fontWeight = FontWeight.Bold, modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp) ) } } if (order.upiTransactionId.isNotBlank()) { Spacer(modifier = Modifier.height(4.dp)) Text( text = "Txn / UTR ID: ${order.upiTransactionId} (${order.paymentMethod})", fontSize = 11.sp, color = TextSecondary, fontWeight = FontWeight.Medium ) } if (!isPaymentVerified) { Spacer(modifier = Modifier.height(8.dp)) Button( onClick = onVerifyPayment, colors = ButtonDefaults.buttonColors(containerColor = FreshVegGreen), shape = RoundedCornerShape(8.dp), modifier = Modifier.fillMaxWidth().height(34.dp) ) { Text("✅ Customer Payment Received (Confirm ₹${order.grandTotal.toInt()})", fontSize = 11.sp, fontWeight = FontWeight.Bold, color = Color.White) } } } } } else { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Text( text = "Total: ₹${order.grandTotal.toInt()} • Cash on Delivery", fontWeight = FontWeight.Bold, fontSize = 12.sp, color = Color(0xFFE65100) ) } } Spacer(modifier = Modifier.height(10.dp)) // Admin Status Progression Action Buttons Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp) ) { when (order.orderStatus) { OrderStatus.PLACED -> { Button( onClick = { onUpdateStatus(OrderStatus.PREPARING) }, shape = RoundedCornerShape(10.dp), colors = ButtonDefaults.buttonColors(containerColor = Color(0xFFFF6D00)), modifier = Modifier.weight(1f).height(38.dp) ) { Icon(Icons.Default.Restaurant, contentDescription = null, modifier = Modifier.size(16.dp)) Spacer(modifier = Modifier.width(6.dp)) Text("Accept & Cook", fontWeight = FontWeight.Bold, fontSize = 12.sp) } } OrderStatus.PREPARING -> { Button( onClick = onAssignRiderClick, shape = RoundedCornerShape(10.dp), colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF0288D1)), modifier = Modifier.weight(1f).height(38.dp).testTag("assign_rider_btn_${order.orderId}") ) { Icon(Icons.Default.DeliveryDining, contentDescription = null, modifier = Modifier.size(16.dp)) Spacer(modifier = Modifier.width(6.dp)) Text("Assign Rider", fontWeight = FontWeight.Bold, fontSize = 12.sp) } } OrderStatus.OUT_FOR_DELIVERY -> { Button( onClick = { onUpdateStatus(OrderStatus.DELIVERED) }, shape = RoundedCornerShape(10.dp), colors = ButtonDefaults.buttonColors(containerColor = FreshVegGreen), modifier = Modifier.weight(1f).height(38.dp) ) { Icon(Icons.Default.Check, contentDescription = null, modifier = Modifier.size(16.dp)) Spacer(modifier = Modifier.width(6.dp)) Text("Mark Delivered", fontWeight = FontWeight.Bold, fontSize = 12.sp) } } OrderStatus.DELIVERED, OrderStatus.CANCELLED -> { // Completed } } if (order.orderStatus != OrderStatus.DELIVERED && order.orderStatus != OrderStatus.CANCELLED) { OutlinedButton( onClick = { onUpdateStatus(OrderStatus.CANCELLED) }, shape = RoundedCornerShape(10.dp), modifier = Modifier.height(38.dp) ) { Text("Cancel", color = Color.Red, fontSize = 12.sp) } } } } } } @Composable fun AssignRiderDialog( order: Order, riders: List, onDismiss: () -> Unit, onAssign: (DeliveryRider) -> Unit ) { AlertDialog( onDismissRequest = onDismiss, title = { Column { Text(text = "Assign Rider to Order", fontWeight = FontWeight.Bold, fontSize = 16.sp) Text(text = "Order #${order.orderId} • To: ${order.customerName}", fontSize = 12.sp, color = TextSecondary) } }, text = { Column( modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp) ) { Text(text = "Select a Kumarghat Delivery Partner:", fontSize = 12.sp, color = TextSecondary) riders.forEach { rider -> val isAvailable = rider.status == RiderStatus.AVAILABLE Surface( color = if (isAvailable) Color(0xFFF0FDF4) else Color(0xFFF8FAFC), shape = RoundedCornerShape(10.dp), border = androidx.compose.foundation.BorderStroke( 1.dp, if (isAvailable) FreshVegGreen else Color(0xFFE2E8F0) ), modifier = Modifier .fillMaxWidth() .clickable { onAssign(rider) } .padding(vertical = 2.dp) ) { Row( modifier = Modifier.padding(10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { Row(verticalAlignment = Alignment.CenterVertically) { Box( modifier = Modifier .size(32.dp) .background(if (isAvailable) FreshVegGreen.copy(alpha = 0.15f) else Color.LightGray.copy(alpha = 0.2f), CircleShape), contentAlignment = Alignment.Center ) { Icon( Icons.Default.DeliveryDining, contentDescription = null, tint = if (isAvailable) FreshVegGreen else Color.Gray, modifier = Modifier.size(18.dp) ) } Spacer(modifier = Modifier.width(10.dp)) Column { Text(text = rider.name, fontWeight = FontWeight.Bold, fontSize = 13.sp) Text(text = "${rider.vehicleNumber} • ${rider.phone}", fontSize = 10.sp, color = TextSecondary) } } Surface( color = if (isAvailable) FreshVegGreen else Color.Gray, shape = RoundedCornerShape(6.dp) ) { Text( text = if (isAvailable) "Assign" else rider.status.label, color = Color.White, fontSize = 10.sp, fontWeight = FontWeight.Bold, modifier = Modifier.padding(horizontal = 6.dp, vertical = 3.dp) ) } } } } } }, confirmButton = {}, dismissButton = { TextButton(onClick = onDismiss) { Text("Cancel", color = TextSecondary) } } ) }