package com.craigvg.lichun_android.ui.screens.retention import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack 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.draw.clip import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.craigvg.lichun_android.domain.models.DailyQuest 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.GameStateViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle /** * Daily quests screen - Quest cards with progress * Ported from iOS DailyQuestsView.swift */ @OptIn(ExperimentalMaterial3Api::class) @Composable fun DailyQuestsScreen( gameStateViewModel: GameStateViewModel = hiltViewModel(), onBack: () -> Unit = {} ) { val questsState by gameStateViewModel.dailyQuestsState.collectAsStateWithLifecycle() val questEngagement by gameStateViewModel.questEngagement.collectAsStateWithLifecycle() LaunchedEffect(Unit) { gameStateViewModel.fetchDailyQuests() } Scaffold( topBar = { TopAppBar( title = { Text("Daily Quests", style = AppTypography.headline) }, navigationIcon = { IconButton(onClick = onBack) { Icon( imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back", tint = AppColors.primaryText ) } }, colors = TopAppBarDefaults.topAppBarColors( containerColor = AppColors.surfaceElevated ) ) }, containerColor = AppColors.background ) { paddingValues -> Column( modifier = Modifier .fillMaxSize() .padding(paddingValues) .padding(AppSpacing.md) ) { // Quest progress header Text( text = "Complete quests to earn rewards!", style = AppTypography.body, color = AppColors.secondaryText ) Spacer(modifier = Modifier.height(AppSpacing.sm)) questsState?.let { state -> // Progress summary val completedCount = state.quests.count { it.completed } val totalCount = state.quests.size Row( verticalAlignment = Alignment.CenterVertically ) { Icon( imageVector = Icons.Default.TaskAlt, contentDescription = null, tint = AppColors.success, modifier = Modifier.size(20.dp) ) Spacer(modifier = Modifier.width(8.dp)) Text( text = "$completedCount of $totalCount completed", style = AppTypography.bodyBold, color = AppColors.secondaryText ) } Spacer(modifier = Modifier.height(AppSpacing.md)) // Quests list + deeper quest-loop depth section (streak + weekly). LazyColumn( modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(AppSpacing.sm) ) { items(state.quests) { quest -> QuestCard( quest = quest, onClaim = { gameStateViewModel.claimQuestReward(quest.id) } ) } item { Spacer(modifier = Modifier.height(AppSpacing.md)) Text( text = "Keep It Going", style = AppTypography.headline, color = AppColors.primaryText ) Spacer(modifier = Modifier.height(AppSpacing.sm)) QuestDepthSection(engagement = questEngagement) Spacer(modifier = Modifier.height(AppSpacing.xl)) } } } ?: run { // Loading state Box( modifier = Modifier .fillMaxWidth() .height(200.dp), contentAlignment = Alignment.Center ) { CircularProgressIndicator( color = AppColors.primary ) } } } } } @Composable fun QuestCard( quest: DailyQuest, onClaim: () -> Unit ) { Card( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(AppSpacing.cornerRadius), colors = CardDefaults.cardColors( containerColor = if (quest.completed) { quest.category.color.copy(alpha = 0.1f) } else { AppColors.surfaceSubtle } ) ) { Column( modifier = Modifier .fillMaxWidth() .padding(AppSpacing.md) ) { Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically ) { // Category icon Box( modifier = Modifier .size(40.dp) .clip(RoundedCornerShape(8.dp)) .background(quest.category.color.copy(alpha = 0.2f)), contentAlignment = Alignment.Center ) { Icon( imageVector = when (quest.category) { com.craigvg.lichun_android.domain.models.QuestCategory.SOCIAL -> Icons.Default.People com.craigvg.lichun_android.domain.models.QuestCategory.CAREER -> Icons.Default.Work com.craigvg.lichun_android.domain.models.QuestCategory.ACTIVITIES -> Icons.Default.DirectionsRun com.craigvg.lichun_android.domain.models.QuestCategory.EDUCATION -> Icons.Default.School com.craigvg.lichun_android.domain.models.QuestCategory.WEALTH -> Icons.Default.AttachMoney }, contentDescription = null, tint = quest.category.color, modifier = Modifier.size(24.dp) ) } Spacer(modifier = Modifier.width(AppSpacing.sm)) Column(modifier = Modifier.weight(1f)) { Text( text = quest.name, style = AppTypography.bodyBold, color = AppColors.primaryText ) Text( text = quest.description, style = AppTypography.caption, color = AppColors.secondaryText ) } if (quest.canClaim) { Button( onClick = onClaim, colors = ButtonDefaults.buttonColors( containerColor = AppColors.success ), shape = RoundedCornerShape(AppSpacing.smallCornerRadius), contentPadding = PaddingValues(horizontal = 12.dp, vertical = 8.dp) ) { Text( text = "Claim", style = AppTypography.captionBold ) } } else if (quest.claimed) { Icon( imageVector = Icons.Default.CheckCircle, contentDescription = "Claimed", tint = AppColors.success, modifier = Modifier.size(28.dp) ) } } Spacer(modifier = Modifier.height(AppSpacing.xs)) // Progress bar Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically ) { Box( modifier = Modifier .weight(1f) .height(8.dp) .clip(RoundedCornerShape(4.dp)) .background(quest.category.color.copy(alpha = 0.2f)) ) { Box( modifier = Modifier .fillMaxWidth(quest.progressPercentage) .fillMaxHeight() .clip(RoundedCornerShape(4.dp)) .background(quest.category.color) ) } Spacer(modifier = Modifier.width(8.dp)) Text( text = quest.progressText, style = AppTypography.captionBold, color = quest.category.color ) } // Reward if (!quest.claimed) { Spacer(modifier = Modifier.height(AppSpacing.xs)) Row( verticalAlignment = Alignment.CenterVertically ) { Text( text = "Reward: ", style = AppTypography.caption, color = AppColors.secondaryText ) Text( text = quest.reward.displayReward, style = AppTypography.captionBold, color = AppColors.diamond ) } } } } }