package com.craigvg.lichun_android.ui.screens.retention import androidx.compose.foundation.background import androidx.compose.foundation.border 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.CircleShape 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.alpha import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.craigvg.lichun_android.domain.models.DayReward 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 rewards screen - 7-day calendar display * Ported from iOS DailyRewardsView.swift */ @OptIn(ExperimentalMaterial3Api::class) @Composable fun DailyRewardsScreen( gameStateViewModel: GameStateViewModel = hiltViewModel(), onBack: () -> Unit = {} ) { val dailyRewardState by gameStateViewModel.dailyRewardState.collectAsStateWithLifecycle() LaunchedEffect(Unit) { gameStateViewModel.fetchDailyRewards() } Scaffold( topBar = { TopAppBar( title = { Text("Daily Rewards", 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) ) { // Streak info dailyRewardState?.let { state -> Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth() ) { Icon( imageVector = Icons.Default.LocalFireDepartment, contentDescription = null, tint = AppColors.accent, modifier = Modifier.size(24.dp) ) Spacer(modifier = Modifier.width(8.dp)) Text( text = "${state.currentStreak} day streak!", style = AppTypography.headline, color = AppColors.accent ) } Spacer(modifier = Modifier.height(AppSpacing.md)) // Days grid LazyVerticalGrid( columns = GridCells.Fixed(7), modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp) ) { items(state.rewards) { reward -> DayRewardCard( reward = reward, isToday = reward.id == state.currentStreak + 1, canClaim = state.canClaim && !state.todaysClaimed && reward.id == state.currentStreak + 1, onClaim = { gameStateViewModel.claimDailyReward(reward.id) } ) } } Spacer(modifier = Modifier.height(AppSpacing.md)) // Claim button if (state.canClaim && !state.todaysClaimed) { Button( onClick = { gameStateViewModel.claimDailyReward(state.currentStreak + 1) }, modifier = Modifier.fillMaxWidth(), colors = ButtonDefaults.buttonColors( containerColor = AppColors.primary ), shape = RoundedCornerShape(AppSpacing.cornerRadius) ) { Text( text = "Claim Today's Reward", style = AppTypography.button ) } } else if (state.todaysClaimed) { Card( modifier = Modifier.fillMaxWidth(), colors = CardDefaults.cardColors( containerColor = AppColors.success.copy(alpha = 0.1f) ), shape = RoundedCornerShape(AppSpacing.cornerRadius) ) { Row( modifier = Modifier .fillMaxWidth() .padding(AppSpacing.md), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically ) { Icon( imageVector = Icons.Default.CheckCircle, contentDescription = null, tint = AppColors.success ) Spacer(modifier = Modifier.width(8.dp)) Text( text = "Today's reward claimed!", style = AppTypography.bodyBold, color = AppColors.success ) } } } } ?: run { // Loading state Box( modifier = Modifier .fillMaxWidth() .height(200.dp), contentAlignment = Alignment.Center ) { CircularProgressIndicator( color = AppColors.primary ) } } } } } @Composable fun DayRewardCard( reward: DayReward, isToday: Boolean, canClaim: Boolean, onClaim: () -> Unit ) { Card( modifier = Modifier .aspectRatio(1f) .then( if (canClaim) Modifier.clickable(onClick = onClaim) else Modifier ) .then( if (isToday) Modifier.border( width = 2.dp, brush = Brush.linearGradient( colors = listOf(AppColors.primary, AppColors.accent) ), shape = RoundedCornerShape(AppSpacing.smallCornerRadius) ) else Modifier ) .alpha(if (reward.claimed) 0.6f else 1f), shape = RoundedCornerShape(AppSpacing.smallCornerRadius), colors = CardDefaults.cardColors( containerColor = when { reward.claimed -> AppColors.success.copy(alpha = 0.2f) isToday -> AppColors.primary.copy(alpha = 0.1f) else -> AppColors.surfaceSubtle } ) ) { Column( modifier = Modifier .fillMaxSize() .padding(4.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { if (reward.claimed) { Icon( imageVector = Icons.Default.Check, contentDescription = "Claimed", tint = AppColors.success, modifier = Modifier.size(16.dp) ) } else { Icon( imageVector = Icons.Default.Diamond, contentDescription = null, tint = AppColors.diamond, modifier = Modifier.size(16.dp) ) Text( text = "${reward.diamonds}", style = AppTypography.micro, color = AppColors.primaryText ) } Text( text = "Day ${reward.id}", style = AppTypography.micro, color = AppColors.secondaryText ) } } }