package com.example.dattingapp.homes import android.content.Intent import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Favorite import androidx.compose.material.icons.filled.MusicNote import androidx.compose.material.icons.filled.TextSnippet import androidx.compose.material.icons.outlined.Settings import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil.compose.AsyncImage import com.example.dattingapp.LikeANdMatchActivity import com.example.dattingapp.R import com.example.dattingapp.ShowPostingActivity import com.example.dattingapp.homes.networkandapi.PostInteractionStore // NEW import com.example.dattingapp.homes.profile.Author import com.example.dattingapp.homes.profile.Media import com.example.dattingapp.homes.profile.Post import com.example.dattingapp.homes.profile.ProfileData import com.example.dattingapp.homes.profile.UserResponse import com.example.dattingapp.ui.theme.BrandMagenta import com.example.dattingapp.ui.theme.BrandPurple import com.example.dattingapp.ui.theme.DattingAPPTheme import com.example.dattingapp.ui.theme.TextMuted import com.example.dattingapp.ui.theme.textDark import java.time.LocalDate import java.time.Period import java.time.format.DateTimeFormatter // Helper function to calculate age from birth_date string (e.g., "1995-05-15") private fun calculateAge(birthDateStr: String?): Int? { if (birthDateStr.isNullOrBlank()) return null return try { val formatter = DateTimeFormatter.ISO_LOCAL_DATE val birthDate = LocalDate.parse(birthDateStr.take(10), formatter) Period.between(birthDate, LocalDate.now()).years } catch (e: Exception) { null } } @Composable fun MyProfileScreen( profileResponse: UserResponse?, isLoading: Boolean, errorMessage: String?, onRetry: () -> Unit = {}, onEditClick: () -> Unit = {}, onUpgradeClick: () -> Unit = {}, onSettingsClick: () -> Unit = {}, onLikesClick: () -> Unit = {}, onLikedClick: () -> Unit = {}, onMatchClick: () -> Unit = {} ) { val context = LocalContext.current val scrollState = rememberScrollState() val profile = profileResponse?.profile val age = calculateAge(profile?.birth_date) // NEW: posts deleted anywhere in the app val deletedIds by PostInteractionStore.deletedIds.collectAsState() val visiblePosts = (profileResponse?.posts ?: emptyList()).filter { it.id !in deletedIds } Column( modifier = Modifier .fillMaxSize() .background(Color.White) .verticalScroll(scrollState) ) { // ==================================================== // HEADER & COVER IMAGE // ==================================================== Box( modifier = Modifier .fillMaxWidth() .height(260.dp) ) { Image( painter = painterResource(id = R.drawable.locationpermissionbg), contentDescription = "Cover Banner", modifier = Modifier .fillMaxWidth() .height(200.dp), contentScale = ContentScale.Crop ) // SETTINGS BUTTON IconButton( onClick = onSettingsClick, modifier = Modifier .align(Alignment.TopEnd) .padding(top = 16.dp, end = 16.dp) .size(36.dp) .clip(CircleShape) .background(Color.Black.copy(alpha = 0.3f)) ) { Icon( imageVector = Icons.Outlined.Settings, contentDescription = "Settings", tint = Color.White, modifier = Modifier.size(20.dp) ) } // PROFILE IMAGE & VERIFIED BADGE Box( modifier = Modifier .align(Alignment.BottomStart) .padding(start = 24.dp) .size(110.dp) ) { AsyncImage( model = profile?.profile_image_url, contentDescription = "Profile Picture", contentScale = ContentScale.Crop, placeholder = painterResource(id = R.drawable.locationpermissionbg), error = painterResource(id = R.drawable.locationpermissionbg), modifier = Modifier .fillMaxSize() .clip(CircleShape) .border(width = 4.dp, color = Color.White, shape = CircleShape) ) Box( modifier = Modifier .align(Alignment.BottomEnd) .size(28.dp) .clip(CircleShape) .background(BrandMagenta) .border(width = 2.dp, color = Color.White, shape = CircleShape), contentAlignment = Alignment.Center ) { Icon( imageVector = Icons.Default.Check, contentDescription = "Verified", tint = Color.White, modifier = Modifier.size(16.dp) ) } } } // ==================================================== // USER INFORMATION SECTION // ==================================================== Column( modifier = Modifier .fillMaxWidth() .padding(horizontal = 24.dp, vertical = 8.dp) ) { Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp) ) { Text( text = if (age != null) "${profile?.full_name ?: ""}, $age" else (profile?.full_name ?: ""), fontSize = 22.sp, fontWeight = FontWeight.Bold, color = textDark ) } } Spacer(modifier = Modifier.height(4.dp)) val locationText = listOfNotNull(profile?.city, profile?.country).joinToString(", ") if (locationText.isNotBlank()) { Text( text = "📍 $locationText", fontSize = 13.sp, color = TextMuted ) Spacer(modifier = Modifier.height(6.dp)) } if (!profile?.bio.isNullOrBlank()) { Card( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(12.dp), colors = CardDefaults.cardColors(containerColor = Color(0xFFF9F9F9)), border = CardDefaults.outlinedCardBorder().copy(width = 0.5.dp) ) { Text( text = profile.bio!!, fontSize = 13.sp, color = textDark, lineHeight = 18.sp, modifier = Modifier.padding(12.dp) ) } Spacer(modifier = Modifier.height(10.dp)) } if (!profile?.interests.isNullOrEmpty()) { FlowRow( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp) ) { profile.interests.forEach { interest -> Surface( shape = RoundedCornerShape(16.dp), color = BrandMagenta.copy(alpha = 0.1f) ) { Text( text = interest, color = BrandMagenta, fontSize = 12.sp, fontWeight = FontWeight.Medium, modifier = Modifier.padding(horizontal = 12.dp, vertical = 6.dp) ) } } } } } Spacer(modifier = Modifier.height(12.dp)) // ==================================================== // PREMIUM BANNER // ==================================================== Box( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp) .clip(RoundedCornerShape(16.dp)) .background(brush = Brush.horizontalGradient(colors = listOf(BrandMagenta, BrandPurple))) .padding(16.dp) ) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Column { Text( text = "VibeCheck Premium", color = Color.White, fontSize = 16.sp, fontWeight = FontWeight.Bold ) Spacer(modifier = Modifier.height(2.dp)) Text( text = "Unlock unlimited likes & more", color = Color.White.copy(alpha = 0.8f), fontSize = 12.sp ) } Button( onClick = onUpgradeClick, colors = ButtonDefaults.buttonColors(containerColor = Color.White), shape = RoundedCornerShape(20.dp), contentPadding = PaddingValues(horizontal = 14.dp, vertical = 4.dp) ) { Text( text = "Upgrade", color = BrandMagenta, fontSize = 12.sp, fontWeight = FontWeight.Bold ) } } } Spacer(modifier = Modifier.height(16.dp)) // ==================================================== // STATISTICS CARDS // ==================================================== Row( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp) ) { StatCard( number = profileResponse?.liked_users_count?.toString() ?: "0", label = "Likes", modifier = Modifier.weight(1f), onClick = { val intent = Intent(context, LikeANdMatchActivity::class.java).apply { putExtra("TYPE", "Likes") } context.startActivity(intent) onLikesClick() } ) StatCard( number = profileResponse?.liked_by_users_count?.toString() ?: "0", label = "Liked", modifier = Modifier.weight(1f), onClick = { val intent = Intent(context, LikeANdMatchActivity::class.java).apply { putExtra("TYPE", "Liked") } context.startActivity(intent) onLikedClick() } ) StatCard( number = profileResponse?.matches_count?.toString() ?: "0", label = "Matches", modifier = Modifier.weight(1f), onClick = { val intent = Intent(context, LikeANdMatchActivity::class.java).apply { putExtra("TYPE", "Matches") } context.startActivity(intent) onMatchClick() } ) } Spacer(modifier = Modifier.height(20.dp)) // ==================================================== // POSTED SECTION // ==================================================== Text( text = "Posted", fontSize = 18.sp, fontWeight = FontWeight.Bold, color = textDark, modifier = Modifier.padding(horizontal = 16.dp) ) Spacer(modifier = Modifier.height(10.dp)) ProfilePostsGrid(posts = visiblePosts) // CHANGED: deleted posts are filtered out Spacer(modifier = Modifier.height(30.dp)) } } // ============================================================ // STAT CARD // ============================================================ @Composable private fun StatCard( number: String, label: String, modifier: Modifier = Modifier, numberColor: Color = textDark, onClick: () -> Unit ) { Card( modifier = modifier.clickable { onClick() }, shape = RoundedCornerShape(12.dp), colors = CardDefaults.cardColors(containerColor = Color(0xFFFAFAFA)), border = CardDefaults.outlinedCardBorder().copy(width = 0.5.dp) ) { Column( modifier = Modifier .fillMaxWidth() .padding(vertical = 8.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = number, fontSize = 16.sp, fontWeight = FontWeight.Bold, color = numberColor ) Spacer(modifier = Modifier.height(2.dp)) Text( text = label, fontSize = 11.sp, color = TextMuted ) } } } // ============================================================ // STAGGERED PROFILE POSTS GRID // ============================================================ @Composable private fun ProfilePostsGrid(posts: List) { if (posts.isEmpty()) { Box( modifier = Modifier .fillMaxWidth() .height(120.dp), contentAlignment = Alignment.Center ) { Text(text = "No posts yet", color = TextMuted, fontSize = 14.sp) } return } val columns = remember(posts) { val col1 = mutableListOf() val col2 = mutableListOf() posts.forEachIndexed { index, post -> if (index % 2 == 0) col1.add(post) else col2.add(post) } Pair(col1, col2) } Row( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp), horizontalArrangement = Arrangement.spacedBy(6.dp) ) { Column( modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(6.dp) ) { columns.first.forEachIndexed { idx, post -> val aspectRatio = if (idx % 2 == 0) 0.8f else 1.2f MasonryProfilePostItem(post = post, aspectRatio = aspectRatio) } } Column( modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(6.dp) ) { columns.second.forEachIndexed { idx, post -> val aspectRatio = if (idx % 2 == 0) 1.2f else 0.8f MasonryProfilePostItem(post = post, aspectRatio = aspectRatio) } } } } @Composable private fun MasonryProfilePostItem(post: Post, aspectRatio: Float) { val context = LocalContext.current val primaryMedia = post.media.firstOrNull()?.url val isImage = post.post_type.equals("image", ignoreCase = true) || !primaryMedia.isNullOrEmpty() Card( shape = RoundedCornerShape(12.dp), elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), modifier = Modifier .fillMaxWidth() .aspectRatio(aspectRatio) .clickable { val intent = Intent(context, ShowPostingActivity::class.java).apply { putExtra("Post_ID", post.id) } context.startActivity(intent) } ) { Box(modifier = Modifier.fillMaxSize()) { if (isImage && !primaryMedia.isNullOrEmpty()) { AsyncImage( model = primaryMedia, contentDescription = "Post Image", contentScale = ContentScale.Crop, modifier = Modifier.fillMaxSize() ) Box( modifier = Modifier .fillMaxSize() .background( Brush.verticalGradient( colors = listOf(Color.Transparent, Color.Black.copy(alpha = 0.65f)), startY = 100f ) ) ) Column( modifier = Modifier .align(Alignment.BottomStart) .padding(8.dp), verticalArrangement = Arrangement.spacedBy(2.dp) ) { if (!post.feeling.isNullOrBlank()) { Text( text = post.feeling, color = Color.White.copy(alpha = 0.9f), fontSize = 9.sp, fontWeight = FontWeight.Bold ) } if (!post.content.isNullOrBlank()) { Text( text = post.content, color = Color.White, fontSize = 11.sp, maxLines = 1, overflow = TextOverflow.Ellipsis ) } } } else { Column( modifier = Modifier .fillMaxSize() .padding(10.dp), verticalArrangement = Arrangement.SpaceBetween ) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(3.dp) ) { Icon( imageVector = when (post.post_type.lowercase()) { "music" -> Icons.Default.MusicNote else -> Icons.Default.TextSnippet }, contentDescription = null, tint = Color.White, modifier = Modifier.size(10.dp) ) Text( text = post.post_type.uppercase(), color = Color.White.copy(alpha = 0.9f), fontSize = 7.sp, fontWeight = FontWeight.ExtraBold ) } } Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { if (!post.feeling.isNullOrBlank()) { Surface( shape = RoundedCornerShape(6.dp), color = Color.White.copy(alpha = 0.2f) ) { Text( text = "feeling ${post.feeling}", color = Color.White, fontSize = 7.sp, modifier = Modifier.padding(horizontal = 4.dp, vertical = 2.dp), maxLines = 1, overflow = TextOverflow.Ellipsis ) } } Text( text = post.content ?: "", color = Color.White, fontSize = 11.sp, fontWeight = FontWeight.SemiBold, maxLines = 3, overflow = TextOverflow.Ellipsis, lineHeight = 14.sp ) } Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(2.dp) ) { Icon( imageVector = Icons.Default.Favorite, contentDescription = null, tint = Color.White.copy(alpha = 0.8f), modifier = Modifier.size(9.dp) ) Text( text = "${post.like_count}", color = Color.White.copy(alpha = 0.8f), fontSize = 8.sp ) } } } } } } // ============================================================ // PREVIEW // ============================================================ @Preview(showBackground = true, showSystemUi = true) @Composable fun MyProfileScreenSuccessPreview() { DattingAPPTheme { val mockUserResponse = UserResponse( id = 1, email_or_phone = "elena@example.com", status = "active", profile = ProfileData( full_name = "Elena", gender = "Female", birth_date = "2002-04-12", city = "New York", county = null, country = "USA", relationship_goal = "Long-term partnership", bio = "\"Always looking for the best flat white in the city. Amateur photographer, professional dog petter...\"", profile_image_url = "https://picsum.photos/300/300", video_url = null, interests = listOf("Photography", "Dogs", "Coffee Shop Lover", "Art Galleries") ), created_at = "2026-01-01", posts = listOf( Post( id = 101, content = "Enjoying the art exhibition!", post_type = "image", content_format = "standard", feeling = "Happy", location = null, author = Author(1, "Elena", "New York", "USA", 98), like_count = 12, comment_count = 3, liked_by_me = false, media = listOf( Media(1, "image", "image/jpeg", 1024, 1, "https://picsum.photos/400/400?random=1"), Media(2, "image", "image/jpeg", 1024, 2, "https://picsum.photos/400/400?random=2"), Media(3, "image", "image/jpeg", 1024, 3, "https://picsum.photos/400/400?random=3") ), created_at = "2026-02-10" ), Post( id = 102, content = "Weekend coffee vibes ☕", post_type = "image", content_format = "standard", feeling = "Relaxed", location = null, author = Author(1, "Elena", "New York", "USA", 98), like_count = 25, comment_count = 5, liked_by_me = false, media = listOf( Media(4, "image", "image/jpeg", 1024, 1, "https://picsum.photos/400/400?random=4"), Media(5, "image", "image/jpeg", 1024, 2, "https://picsum.photos/400/400?random=5"), Media(6, "image", "image/jpeg", 1024, 3, "https://picsum.photos/400/400?random=6") ), created_at = "2026-02-12" ) ), liked_users = emptyList(), liked_by_users = emptyList(), matches = emptyList(), liked_users_count = 42, liked_by_users_count = 128, matches_count = 18 ) MyProfileScreen( profileResponse = mockUserResponse, isLoading = false, errorMessage = null ) } }