package com.aistudio.bonjuteri.jwlry.ui.components 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.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.aspectRatio 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.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.AddShoppingCart import androidx.compose.material.icons.filled.Favorite import androidx.compose.material.icons.filled.FavoriteBorder import androidx.compose.material.icons.outlined.Diamond import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.FilledTonalButton import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable 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.text.font.FontWeight import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil.compose.AsyncImage import coil.request.ImageRequest import com.aistudio.bonjuteri.jwlry.model.Product import com.aistudio.bonjuteri.jwlry.ui.theme.BadgeBestSellerBg import com.aistudio.bonjuteri.jwlry.ui.theme.BadgeBestSellerText import com.aistudio.bonjuteri.jwlry.ui.theme.BadgeDiscountBg import com.aistudio.bonjuteri.jwlry.ui.theme.BadgeDiscountText import com.aistudio.bonjuteri.jwlry.ui.theme.BadgeNewBg import com.aistudio.bonjuteri.jwlry.ui.theme.BadgeNewText import com.aistudio.bonjuteri.jwlry.ui.theme.ErrorRed import com.aistudio.bonjuteri.jwlry.ui.theme.GoldPrimary import com.aistudio.bonjuteri.jwlry.ui.theme.GoldSubtle import com.aistudio.bonjuteri.jwlry.ui.theme.LightSurface import com.aistudio.bonjuteri.jwlry.ui.theme.MutedGrey import com.aistudio.bonjuteri.jwlry.ui.theme.PrimaryBlack import com.aistudio.bonjuteri.jwlry.ui.theme.PureWhite import com.aistudio.bonjuteri.jwlry.ui.theme.SurfaceBorder import com.aistudio.bonjuteri.jwlry.ui.theme.WarningAmber @OptIn(ExperimentalLayoutApi::class) @Composable fun ProductCard( product: Product, isFavorite: Boolean, onProductClick: (Product) -> Unit, onFavoriteToggle: (Product) -> Unit, onAddToCart: (Product) -> Unit, modifier: Modifier = Modifier ) { Card( modifier = modifier .fillMaxWidth() .clip(RoundedCornerShape(12.dp)) .clickable { onProductClick(product) } .testTag("product_card_${product.id}"), shape = RoundedCornerShape(12.dp), colors = CardDefaults.cardColors(containerColor = PureWhite), elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) ) { Column { // Image + Badges + Favorite Button Box( modifier = Modifier .fillMaxWidth() .aspectRatio(1f) .background(LightSurface) ) { if (product.imageUrl.isNotBlank()) { AsyncImage( model = ImageRequest.Builder(LocalContext.current) .data(product.imageUrl) .crossfade(true) .build(), contentDescription = product.title, modifier = Modifier .fillMaxWidth() .aspectRatio(1f), contentScale = ContentScale.Crop ) } else { Box( modifier = Modifier .fillMaxWidth() .aspectRatio(1f), contentAlignment = Alignment.Center ) { Icon( imageVector = Icons.Outlined.Diamond, contentDescription = "Görsel yok", tint = GoldPrimary.copy(alpha = 0.5f), modifier = Modifier.size(48.dp) ) } } // Badges in Top Left FlowRow( modifier = Modifier .align(Alignment.TopStart) .padding(6.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), verticalArrangement = Arrangement.spacedBy(4.dp) ) { if (product.isNew) { BadgeLabel(text = "YENİ", bg = BadgeNewBg, fg = BadgeNewText) } if (product.isBestSeller) { BadgeLabel(text = "ÇOK SATAN", bg = BadgeBestSellerBg, fg = BadgeBestSellerText) } if (product.hasDiscount) { BadgeLabel( text = "%${product.discountPercent} İNDİRİM", bg = BadgeDiscountBg, fg = BadgeDiscountText ) } } // Favorite Heart in Top Right IconButton( onClick = { onFavoriteToggle(product) }, modifier = Modifier .align(Alignment.TopEnd) .padding(4.dp) .size(34.dp) .background(PureWhite.copy(alpha = 0.9f), CircleShape) .testTag("fav_button_${product.id}") ) { Icon( imageVector = if (isFavorite) Icons.Filled.Favorite else Icons.Filled.FavoriteBorder, contentDescription = "Favoriye Ekle", tint = if (isFavorite) ErrorRed else MutedGrey, modifier = Modifier.size(18.dp) ) } // Out of stock overlay if stock == 0 if (!product.isInStock) { Box( modifier = Modifier .align(Alignment.BottomCenter) .fillMaxWidth() .background(PrimaryBlack.copy(alpha = 0.75f)) .padding(vertical = 4.dp), contentAlignment = Alignment.Center ) { Text( text = "TÜKENDİ", color = PureWhite, fontSize = 11.sp, fontWeight = FontWeight.Bold ) } } } // Product Details Column( modifier = Modifier.padding(10.dp) ) { // Category Text( text = product.category.uppercase(), style = MaterialTheme.typography.labelSmall.copy( fontSize = 9.sp, fontWeight = FontWeight.Bold, color = MutedGrey, letterSpacing = 0.8.sp ), maxLines = 1, overflow = TextOverflow.Ellipsis ) Spacer(modifier = Modifier.height(2.dp)) // Title Text( text = product.title, style = MaterialTheme.typography.titleMedium.copy( fontWeight = FontWeight.SemiBold, fontSize = 13.sp, lineHeight = 17.sp, color = PrimaryBlack ), maxLines = 2, overflow = TextOverflow.Ellipsis, modifier = Modifier.height(34.dp) ) Spacer(modifier = Modifier.height(4.dp)) // Stock warning if low stock if (product.isInStock && product.stock in 1..4) { Text( text = "Son ${product.stock} ürün!", style = MaterialTheme.typography.labelSmall.copy( color = WarningAmber, fontWeight = FontWeight.Bold, fontSize = 10.sp ) ) } Spacer(modifier = Modifier.height(4.dp)) // Pricing Row( verticalAlignment = Alignment.Bottom, modifier = Modifier.fillMaxWidth() ) { Text( text = product.formattedPrice, style = MaterialTheme.typography.titleLarge.copy( fontWeight = FontWeight.Bold, fontSize = 15.sp, color = PrimaryBlack ) ) if (product.hasDiscount && product.formattedOldPrice != null) { Spacer(modifier = Modifier.width(6.dp)) Text( text = product.formattedOldPrice!!, style = MaterialTheme.typography.bodySmall.copy( textDecoration = TextDecoration.LineThrough, color = MutedGrey, fontSize = 11.sp ) ) } } Spacer(modifier = Modifier.height(8.dp)) // Quick Add to Cart Button FilledTonalButton( onClick = { onAddToCart(product) }, enabled = product.isInStock, modifier = Modifier .fillMaxWidth() .height(36.dp) .testTag("add_to_cart_${product.id}"), shape = RoundedCornerShape(8.dp), colors = ButtonDefaults.filledTonalButtonColors( containerColor = GoldSubtle, contentColor = PrimaryBlack ) ) { Icon( imageVector = Icons.Filled.AddShoppingCart, contentDescription = "Sepete Ekle", modifier = Modifier.size(16.dp), tint = PrimaryBlack ) Spacer(modifier = Modifier.width(6.dp)) Text( text = if (product.isInStock) "Sepete Ekle" else "Tükendi", fontSize = 12.sp, fontWeight = FontWeight.Bold ) } } } } } @Composable private fun BadgeLabel(text: String, bg: Color, fg: Color) { Box( modifier = Modifier .background(bg, RoundedCornerShape(4.dp)) .padding(horizontal = 6.dp, vertical = 2.dp) ) { Text( text = text, color = fg, fontSize = 9.sp, fontWeight = FontWeight.Bold, letterSpacing = 0.5.sp ) } }