package com.craigvg.lichun_android.ui.screens.home.components import androidx.compose.foundation.background 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.* import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import com.craigvg.lichun_android.ui.components.images.CharacterAvatar import com.craigvg.lichun_android.ui.components.stats.CozyStatBar import com.craigvg.lichun_android.ui.components.cards.BaseCard import com.craigvg.lichun_android.ui.theme.AppColors import com.craigvg.lichun_android.ui.theme.AppSpacing import com.craigvg.lichun_android.ui.theme.AppTypography import com.craigvg.lichun_android.viewmodel.PlayerViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle /** * Modal sheet showing full player profile with stats, info, and education. * Ported from iOS PlayerProfileSheet.swift */ @OptIn(ExperimentalMaterial3Api::class) @Composable fun PlayerProfileSheet( playerViewModel: PlayerViewModel = hiltViewModel(), onDismiss: () -> Unit = {} ) { val person by playerViewModel.person.collectAsStateWithLifecycle() Column( modifier = Modifier .fillMaxWidth() .background( Brush.verticalGradient( colors = listOf(AppColors.background, AppColors.surfaceSubtle) ) ) ) { // Top bar Row( modifier = Modifier .fillMaxWidth() .padding(horizontal = AppSpacing.md, vertical = AppSpacing.sm), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Spacer(modifier = Modifier.width(48.dp)) Text("Profile", style = AppTypography.headline, color = AppColors.primaryText) IconButton(onClick = onDismiss) { Icon(Icons.Default.Close, "Close", tint = AppColors.secondaryText.copy(alpha = 0.6f)) } } Column( modifier = Modifier .fillMaxWidth() .verticalScroll(rememberScrollState()) .padding(AppSpacing.md), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(AppSpacing.lg) ) { // Avatar header Column(horizontalAlignment = Alignment.CenterHorizontally) { CharacterAvatar( imageUrl = person.image, firstName = person.firstname, lastName = person.lastname, size = AppSpacing.avatarLarge ) Spacer(modifier = Modifier.height(AppSpacing.md)) Text( text = person.fullName, fontSize = 28.sp, fontWeight = FontWeight.Bold, color = AppColors.primaryText ) if (person.mood.isNotEmpty()) { Text( text = person.mood, style = AppTypography.body, color = AppColors.secondaryText, modifier = Modifier .padding(top = AppSpacing.xs) .background(AppColors.surfaceSubtle, RoundedCornerShape(AppSpacing.pillCornerRadius)) .padding(horizontal = AppSpacing.md, vertical = AppSpacing.xs) ) } } // Info section BaseCard(modifier = Modifier.fillMaxWidth()) { Column { ProfileInfoRow(icon = Icons.Default.CalendarToday, label = "Age", value = "${person.ageYears} years old") HorizontalDivider(color = AppColors.surfaceSubtle) if (person.birthday.isNotEmpty()) { ProfileInfoRow(icon = Icons.Default.Cake, label = "Birthday", value = person.birthday) HorizontalDivider(color = AppColors.surfaceSubtle) } ProfileInfoRow(icon = Icons.Default.Person, label = "Sex", value = person.sex.ifEmpty { "Unknown" }) HorizontalDivider(color = AppColors.surfaceSubtle) if (person.occupation.isNotEmpty()) { ProfileInfoRow(icon = Icons.Default.Work, label = "Occupation", value = person.occupation.replaceFirstChar { it.uppercase() }) HorizontalDivider(color = AppColors.surfaceSubtle) } if (person.education.isNotEmpty()) { ProfileInfoRow(icon = Icons.Default.School, label = "Education", value = person.education.replaceFirstChar { it.uppercase() }) HorizontalDivider(color = AppColors.surfaceSubtle) } if (person.location.isNotEmpty()) { ProfileInfoRow(icon = Icons.Default.LocationOn, label = "Location", value = person.location) } } } // Stats section BaseCard(modifier = Modifier.fillMaxWidth()) { Column(verticalArrangement = Arrangement.spacedBy(AppSpacing.md)) { Row(verticalAlignment = Alignment.CenterVertically) { Icon(Icons.Default.BarChart, null, tint = AppColors.accent, modifier = Modifier.size(20.dp)) Spacer(modifier = Modifier.width(AppSpacing.xs)) Text("Stats", style = AppTypography.headline, color = AppColors.primaryText) } // Resource pills Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(AppSpacing.lg) ) { ProfileResourcePill(emoji = "\u26a1\ufe0f", value = "${person.calcEnergy}", color = AppColors.energy) ProfileResourcePill(emoji = "\ud83d\udcb0", value = "${person.money.toInt()}", color = AppColors.money) ProfileResourcePill(emoji = "\ud83d\udc8e", value = "${person.diamonds}", color = AppColors.diamond) } CozyStatBar(label = "Health", value = (person.health * 100).toFloat() / 100f, color = AppColors.health) CozyStatBar(label = "Happiness", value = person.happiness / 100f, color = AppColors.happiness) CozyStatBar(label = "Intelligence", value = person.intelligence / 100f, color = AppColors.intelligence) CozyStatBar(label = "Prestige", value = person.prestige / 100f, color = AppColors.prestige) } } // Education section person.currentEducation?.let { edu -> BaseCard(modifier = Modifier.fillMaxWidth()) { Column(verticalArrangement = Arrangement.spacedBy(AppSpacing.md)) { Row(verticalAlignment = Alignment.CenterVertically) { Icon(Icons.Default.School, null, tint = AppColors.intelligence, modifier = Modifier.size(20.dp)) Spacer(modifier = Modifier.width(AppSpacing.xs)) Text("Current Education", style = AppTypography.headline, color = AppColors.primaryText) } EducationRow(label = "Level", value = edu.educationLevel.replaceFirstChar { it.uppercase() }) EducationRow(label = "Focus", value = edu.focus) edu.major?.let { major -> EducationRow(label = "Major", value = major) } } } } Spacer(modifier = Modifier.height(AppSpacing.xl)) } } } @Composable private fun ProfileInfoRow(icon: ImageVector, label: String, value: String) { Row( modifier = Modifier .fillMaxWidth() .padding(horizontal = AppSpacing.md, vertical = AppSpacing.sm), verticalAlignment = Alignment.CenterVertically ) { Icon(icon, null, tint = AppColors.accent, modifier = Modifier.size(16.dp)) Spacer(modifier = Modifier.width(AppSpacing.md)) Text(label, style = AppTypography.body, color = AppColors.secondaryText) Spacer(modifier = Modifier.weight(1f)) Text(value, style = AppTypography.bodyBold, color = AppColors.primaryText, maxLines = 1) } } @Composable private fun ProfileResourcePill(emoji: String, value: String, color: Color) { Row( modifier = Modifier .background(color.copy(alpha = 0.1f), RoundedCornerShape(AppSpacing.pillCornerRadius)) .padding(horizontal = AppSpacing.sm, vertical = AppSpacing.xs), verticalAlignment = Alignment.CenterVertically ) { Text(text = emoji, fontSize = 12.sp) Spacer(modifier = Modifier.width(4.dp)) Text(value, style = AppTypography.captionBold, color = AppColors.primaryText) } } @Composable private fun EducationRow(label: String, value: String) { Row(modifier = Modifier.fillMaxWidth()) { Text(label, style = AppTypography.body, color = AppColors.secondaryText) Spacer(modifier = Modifier.weight(1f)) Text(value, style = AppTypography.bodyBold, color = AppColors.primaryText) } }