package com.example.dattingapp import android.content.Context import android.content.Intent import android.os.Bundle import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.Favorite import androidx.compose.material.icons.filled.LocationOn import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember 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.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel import coil.compose.AsyncImage import com.example.dattingapp.homes.networkandapi.LikedUiState import com.example.dattingapp.homes.networkandapi.LikedViewModel import com.example.dattingapp.homes.profile.LikedUserResponse import com.example.dattingapp.ui.theme.DattingAPPTheme import java.time.LocalDate import java.time.Period import java.time.format.DateTimeFormatter class LikeANdMatchActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { DattingAPPTheme { val likedViewModel: LikedViewModel = viewModel() val context = LocalContext.current val type = intent.getStringExtra("TYPE") ?: "Likes" val uiState by when (type) { "Likes" -> likedViewModel.likesUiState.collectAsState() "Liked" -> likedViewModel.likedUiState.collectAsState() else -> likedViewModel.matchesUiState.collectAsState() } LaunchedEffect(Unit) { likedViewModel.likedResponse(context, type) } Scaffold( modifier = Modifier.fillMaxSize(), topBar = { @OptIn(ExperimentalMaterial3Api::class) TopAppBar( title = { Text( text = when (type) { "Likes" -> "My Likes" "Liked" -> "Liked Me" else -> "My Matches" }, fontWeight = FontWeight.Bold, fontSize = 18.sp ) }, navigationIcon = { IconButton(onClick = { finish() }) { Icon( imageVector = Icons.Default.ArrowBack, contentDescription = "Back" ) } }, colors = TopAppBarDefaults.topAppBarColors( containerColor = MaterialTheme.colorScheme.surface ) ) } ) { innerPadding -> Box( modifier = Modifier .fillMaxSize() .padding(innerPadding), contentAlignment = Alignment.Center ) { when (val state = uiState) { is LikedUiState.Idle, is LikedUiState.Loading -> { CircularProgressIndicator() } is LikedUiState.Success -> { ProfileGrid( context = context, likedResponse = state.LikeData, isLoading = false, errorMessage = null ) } is LikedUiState.Error -> { Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.padding(16.dp) ) { Text( text = state.message, color = MaterialTheme.colorScheme.error, fontWeight = FontWeight.Medium ) Button(onClick = { likedViewModel.likedResponse(context, type) }) { Text("Retry") } } } } } } } } } } @Composable fun ProfileCard( context: Context, likedProfile: LikedUserResponse, modifier: Modifier = Modifier, onNameClick: () -> Unit = {}, ) { Card( shape = RoundedCornerShape(16.dp), colors = CardDefaults.cardColors(containerColor = Color.White), elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), modifier = modifier.fillMaxWidth() ) { Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { Box( modifier = Modifier .fillMaxWidth() .height(180.dp) .clip(RoundedCornerShape(12.dp)) .clickable { val intent = Intent(context, FriendProfile::class.java).apply { putExtra("USER_ID", likedProfile.id) } context.startActivity(intent) onNameClick() } ) { // FIX: media can be null from the server, so use ?. here AsyncImage( model = likedProfile.profile_image_url?.takeIf { it.isNotBlank() } ?: likedProfile.media?.firstOrNull(), contentDescription = likedProfile.full_name, contentScale = ContentScale.Crop, modifier = Modifier.fillMaxSize() ) Box( modifier = Modifier .fillMaxSize() .background( Brush.verticalGradient( colors = listOf(Color.Transparent, Color.Black.copy(alpha = 0.7f)), startY = 100f ) ) ) Surface( shape = RoundedCornerShape(20.dp), color = Color.White.copy(alpha = 0.9f), modifier = Modifier .padding(8.dp) .align(Alignment.TopStart) ) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(4.dp), modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp) ) { Icon( imageVector = Icons.Default.Favorite, contentDescription = null, tint = Color(0xFF6C5CE7), modifier = Modifier.size(12.dp) ) Text( text = "${likedProfile.compatibility_percentage ?: 0}%", fontSize = 11.sp, fontWeight = FontWeight.Bold, color = Color(0xFF2D3436) ) } } Column( modifier = Modifier .align(Alignment.BottomStart) .padding(8.dp) ) { val displayName = likedProfile.full_name?.ifBlank { "User" } ?: "User" val age = remember(likedProfile.birth_date) { calculateAge(likedProfile.birth_date) } val nameAndAge = if (age != null) "$displayName, $age" else displayName Log.d("user", "${likedProfile.id}") Text( text = nameAndAge, color = Color.White, fontWeight = FontWeight.Bold, fontSize = 14.sp ) Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(2.dp) ) { Icon( imageVector = Icons.Default.LocationOn, contentDescription = null, tint = Color.White.copy(alpha = 0.8f), modifier = Modifier.size(10.dp) ) Text( text = "${likedProfile.distance_km ?: 0.0} km", color = Color.White.copy(alpha = 0.8f), fontSize = 10.sp ) } } } } } } @Composable fun ProfileGrid( context: Context, likedResponse: List, isLoading: Boolean, errorMessage: String?, onRetry: () -> Unit = {}, modifier: Modifier = Modifier ) { if (likedResponse.isEmpty() && !isLoading) { Box(modifier = modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Text("No profiles found.", color = Color.Gray) } return } LazyVerticalGrid( columns = GridCells.Fixed(2), contentPadding = PaddingValues(12.dp), horizontalArrangement = Arrangement.spacedBy(12.dp), verticalArrangement = Arrangement.spacedBy(12.dp), modifier = modifier.fillMaxSize() ) { items(likedResponse) { profile -> ProfileCard(context, likedProfile = profile) } } } private fun calculateAge(birthDateStr: String?): Int? { if (birthDateStr.isNullOrBlank()) return null return try { val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") val birthDate = LocalDate.parse(birthDateStr.take(10), formatter) Period.between(birthDate, LocalDate.now()).years } catch (e: Exception) { null } } @Preview(showBackground = true) @Composable fun ProfileGridPreview() { val sampleLikedUsers = listOf( LikedUserResponse( id = 55, full_name = "Sarah Jenkins", gender = "female", birth_date = "1995-08-20", city = "Shanghai", county = "District A", country = "China", relationship_goal = "dating", bio = "Coffee lover and traveler.", profile_image_url = "", video_url = null, distance_km = 4.1, compatibility_percentage = 92, media = emptyList() ) ) val context = LocalContext.current DattingAPPTheme { ProfileGrid( context = context, likedResponse = sampleLikedUsers, isLoading = false, errorMessage = null ) } }