package app.closer.ui.challenges

import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.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.Check
import androidx.compose.material.icons.filled.Lock
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.closer.core.navigation.AppRoute
import app.closer.data.challenges.ChallengesCatalog
import app.closer.data.remote.FirestoreChallengeDataSource
import app.closer.domain.model.ChallengeProgressState
import app.closer.domain.model.ConnectionChallenge
import app.closer.domain.repository.AuthRepository
import app.closer.domain.repository.CoupleRepository
import app.closer.ui.theme.CloserPalette
import app.closer.ui.theme.closerBackgroundBrush
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

// ── ViewModel ─────────────────────────────────────────────────────────────────

enum class ChallengesPhase { LOADING, PICK, ACTIVE }

data class ChallengesUiState(
    val phase: ChallengesPhase = ChallengesPhase.LOADING,
    val activeChallenge: ConnectionChallenge? = null,
    val progress: ChallengeProgressState? = null,
    val coupleId: String? = null,
    val userId: String? = null,
    val partnerId: String? = null,
    val error: String? = null,
    val navigateTo: String? = null
)

@HiltViewModel
class ConnectionChallengesViewModel @Inject constructor(
    private val authRepository: AuthRepository,
    private val coupleRepository: CoupleRepository,
    private val challengeDataSource: FirestoreChallengeDataSource
) : ViewModel() {

    private val _uiState = MutableStateFlow(ChallengesUiState())
    val uiState: StateFlow<ChallengesUiState> = _uiState.asStateFlow()

    private var progressJob: Job? = null

    init {
        load()
    }

    private fun load() {
        viewModelScope.launch {
            val uid = authRepository.currentUserId ?: run {
                _uiState.update { it.copy(phase = ChallengesPhase.PICK) }
                return@launch
            }
            val couple = coupleRepository.getCoupleForUser(uid) ?: run {
                _uiState.update { it.copy(phase = ChallengesPhase.PICK) }
                return@launch
            }
            val partnerId = couple.userIds.firstOrNull { it != uid } ?: uid

            val activeChallengeId = runCatching {
                challengeDataSource.getActiveChallengeId(couple.id)
            }.getOrNull()

            if (activeChallengeId != null) {
                val challenge = ChallengesCatalog.findById(activeChallengeId)
                if (challenge != null) {
                    observeChallenge(couple.id, uid, partnerId, challenge)
                    return@launch
                }
            }

            _uiState.update {
                it.copy(
                    phase = ChallengesPhase.PICK,
                    coupleId = couple.id,
                    userId = uid,
                    partnerId = partnerId
                )
            }
        }
    }

    private fun observeChallenge(
        coupleId: String,
        userId: String,
        partnerId: String,
        challenge: ConnectionChallenge
    ) {
        progressJob?.cancel()
        progressJob = viewModelScope.launch {
            challengeDataSource.observeProgress(coupleId, challenge.id, userId, partnerId)
                .collect { progress ->
                    _uiState.update {
                        it.copy(
                            phase = ChallengesPhase.ACTIVE,
                            coupleId = coupleId,
                            userId = userId,
                            partnerId = partnerId,
                            activeChallenge = challenge,
                            progress = progress
                        )
                    }
                    // Auto-complete challenge when all days jointly done.
                    if (progress.jointCompletedDays.size == challenge.durationDays &&
                        progress.status == "active"
                    ) {
                        runCatching { challengeDataSource.finishChallenge(coupleId, challenge.id) }
                    }
                }
        }
    }

    fun startChallenge(challenge: ConnectionChallenge) {
        val state = _uiState.value
        val coupleId = state.coupleId ?: return
        val userId = state.userId ?: return
        val partnerId = state.partnerId ?: userId
        viewModelScope.launch {
            runCatching { challengeDataSource.startChallenge(coupleId, challenge.id) }
                .onSuccess { observeChallenge(coupleId, userId, partnerId, challenge) }
                .onFailure {
                    Log.w(TAG, "Could not start challenge", it)
                    _uiState.update { s -> s.copy(error = "Could not start challenge. Try again.") }
                }
        }
    }

    fun markTodayComplete() {
        val state = _uiState.value
        val coupleId = state.coupleId ?: return
        val userId = state.userId ?: return
        val progress = state.progress ?: return
        val challenge = state.activeChallenge ?: return
        val day = progress.myNextDay
        if (day > challenge.durationDays) return
        viewModelScope.launch {
            runCatching { challengeDataSource.markDayComplete(coupleId, challenge.id, userId, day) }
                .onFailure { Log.w(TAG, "Could not mark day $day complete", it) }
        }
    }

    fun dismissError() = _uiState.update { it.copy(error = null) }

    fun onNavigated() = _uiState.update { it.copy(navigateTo = null) }

    companion object {
        private const val TAG = "ChallengesViewModel"
    }
}

// ── Screen ────────────────────────────────────────────────────────────────────

@Composable
fun ConnectionChallengesScreen(
    onNavigate: (String) -> Unit = {},
    viewModel: ConnectionChallengesViewModel = hiltViewModel()
) {
    val state by viewModel.uiState.collectAsState()

    LaunchedEffect(state.navigateTo) {
        state.navigateTo?.let { onNavigate(it); viewModel.onNavigated() }
    }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(closerBackgroundBrush())
    ) {
        when (state.phase) {
            ChallengesPhase.LOADING -> ChallengesLoadingScreen()
            ChallengesPhase.PICK -> ChallengesPickScreen(
                onBack = { onNavigate(AppRoute.PLAY) },
                onPick = { viewModel.startChallenge(it) }
            )
            ChallengesPhase.ACTIVE -> ChallengesActiveScreen(
                challenge = state.activeChallenge!!,
                progress = state.progress ?: ChallengeProgressState(),
                onBack = { onNavigate(AppRoute.PLAY) },
                onMarkComplete = { viewModel.markTodayComplete() }
            )
        }
    }
}

// ── Loading ───────────────────────────────────────────────────────────────────

@Composable
private fun ChallengesLoadingScreen() {
    Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
        CircularProgressIndicator(color = CloserPalette.PurpleDeep)
    }
}

// ── Pick ──────────────────────────────────────────────────────────────────────

@Composable
private fun ChallengesPickScreen(
    onBack: () -> Unit,
    onPick: (ConnectionChallenge) -> Unit
) {
    LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            .safeDrawingPadding()
            .navigationBarsPadding(),
        contentPadding = PaddingValues(horizontal = 20.dp, vertical = 16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        item {
            Row(
                modifier = Modifier.fillMaxWidth(),
                verticalAlignment = Alignment.CenterVertically
            ) {
                IconButton(onClick = onBack) {
                    Icon(
                        Icons.AutoMirrored.Filled.ArrowBack,
                        contentDescription = "Back",
                        tint = MaterialTheme.colorScheme.onBackground
                    )
                }
                Spacer(Modifier.width(4.dp))
                Column {
                    Text(
                        text = "Connection Challenges",
                        style = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.SemiBold),
                        color = MaterialTheme.colorScheme.onBackground
                    )
                    Text(
                        text = "Pick a series to build a habit together.",
                        style = MaterialTheme.typography.bodyMedium,
                        color = MaterialTheme.colorScheme.onSurfaceVariant
                    )
                }
            }
        }

        items(ChallengesCatalog.all) { challenge ->
            ChallengePickCard(challenge = challenge, onPick = onPick)
        }

        item { Spacer(Modifier.height(8.dp)) }
    }
}

@Composable
private fun ChallengePickCard(
    challenge: ConnectionChallenge,
    onPick: (ConnectionChallenge) -> Unit
) {
    Card(
        onClick = { if (!challenge.isPremium) onPick(challenge) },
        modifier = Modifier.fillMaxWidth(),
        shape = RoundedCornerShape(20.dp),
        colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
        elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
    ) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp),
            horizontalArrangement = Arrangement.spacedBy(14.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Surface(
                shape = RoundedCornerShape(16.dp),
                color = CloserPalette.PurpleDeep.copy(alpha = 0.10f),
                modifier = Modifier.size(52.dp)
            ) {
                Box(contentAlignment = Alignment.Center) {
                    Text(
                        text = challenge.emoji,
                        style = MaterialTheme.typography.headlineSmall
                    )
                }
            }

            Column(modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(4.dp)) {
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.SpaceBetween,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Text(
                        text = challenge.title,
                        style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.SemiBold),
                        color = MaterialTheme.colorScheme.onSurface,
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis,
                        modifier = Modifier.weight(1f)
                    )
                    Spacer(Modifier.width(8.dp))
                    if (challenge.isPremium) {
                        Surface(
                            shape = RoundedCornerShape(999.dp),
                            color = CloserPalette.Gold.copy(alpha = 0.15f)
                        ) {
                            Row(
                                modifier = Modifier.padding(horizontal = 8.dp, vertical = 3.dp),
                                verticalAlignment = Alignment.CenterVertically,
                                horizontalArrangement = Arrangement.spacedBy(3.dp)
                            ) {
                                Icon(Icons.Filled.Lock, contentDescription = null, tint = CloserPalette.Gold, modifier = Modifier.size(10.dp))
                                Text("Premium", style = MaterialTheme.typography.labelSmall, color = CloserPalette.Gold, fontWeight = FontWeight.SemiBold)
                            }
                        }
                    } else {
                        Surface(
                            shape = RoundedCornerShape(999.dp),
                            color = CloserPalette.PurpleDeep.copy(alpha = 0.10f)
                        ) {
                            Text(
                                text = "${challenge.durationDays} days",
                                modifier = Modifier.padding(horizontal = 8.dp, vertical = 3.dp),
                                style = MaterialTheme.typography.labelSmall,
                                color = CloserPalette.PurpleDeep,
                                fontWeight = FontWeight.SemiBold
                            )
                        }
                    }
                }
                Text(
                    text = challenge.description,
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                    maxLines = 2,
                    overflow = TextOverflow.Ellipsis
                )
                Text(
                    text = challenge.category,
                    style = MaterialTheme.typography.labelSmall,
                    color = CloserPalette.PurpleDeep.copy(alpha = 0.7f)
                )
            }
        }
    }
}

// ── Active ────────────────────────────────────────────────────────────────────

@Composable
private fun ChallengesActiveScreen(
    challenge: ConnectionChallenge,
    progress: ChallengeProgressState,
    onBack: () -> Unit,
    onMarkComplete: () -> Unit
) {
    val alreadyDoneToday = progress.myNextDay > (progress.myCompletedDays.maxOrNull() ?: 0) + 1 ||
        progress.myCompletedDays.contains(progress.myNextDay - 1)

    // Has current user completed today?
    val todayDone = progress.myCompletedDays.contains(progress.myNextDay.coerceAtMost(challenge.durationDays)) ||
        progress.myNextDay > challenge.durationDays

    val allComplete = progress.isComplete || progress.jointCompletedDays.size == challenge.durationDays

    LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            .safeDrawingPadding()
            .navigationBarsPadding(),
        contentPadding = PaddingValues(horizontal = 20.dp, vertical = 16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        item {
            // Header
            Row(
                modifier = Modifier.fillMaxWidth(),
                verticalAlignment = Alignment.CenterVertically
            ) {
                IconButton(onClick = onBack) {
                    Icon(
                        Icons.AutoMirrored.Filled.ArrowBack,
                        contentDescription = "Back",
                        tint = MaterialTheme.colorScheme.onBackground
                    )
                }
                Spacer(Modifier.width(4.dp))
                Column(modifier = Modifier.weight(1f)) {
                    Text(
                        text = challenge.title,
                        style = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.SemiBold),
                        color = MaterialTheme.colorScheme.onBackground,
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis
                    )
                    Text(
                        text = if (allComplete) "Completed 🎉" else "Day ${progress.myNextDay.coerceAtMost(challenge.durationDays)} of ${challenge.durationDays}",
                        style = MaterialTheme.typography.bodyMedium,
                        color = MaterialTheme.colorScheme.onSurfaceVariant
                    )
                }
                // Streak badge
                if (progress.jointStreak > 0) {
                    Surface(
                        shape = RoundedCornerShape(999.dp),
                        color = CloserPalette.PurpleDeep.copy(alpha = 0.12f)
                    ) {
                        Text(
                            text = "🔥 ${progress.jointStreak}",
                            modifier = Modifier.padding(horizontal = 12.dp, vertical = 6.dp),
                            style = MaterialTheme.typography.labelMedium,
                            color = CloserPalette.PurpleDeep,
                            fontWeight = FontWeight.SemiBold
                        )
                    }
                }
            }
        }

        item {
            // Day tracker strip
            DayTrackerStrip(
                totalDays = challenge.durationDays,
                myCompletedDays = progress.myCompletedDays,
                partnerCompletedDays = progress.partnerCompletedDays,
                currentDay = progress.myNextDay
            )
        }

        if (!allComplete) {
            val displayDay = progress.myNextDay.coerceAtMost(challenge.durationDays)
            val dayPrompt = challenge.days.getOrNull(displayDay - 1)

            if (dayPrompt != null) {
                item {
                    // Today's prompt card
                    Card(
                        modifier = Modifier.fillMaxWidth(),
                        shape = RoundedCornerShape(24.dp),
                        colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
                        elevation = CardDefaults.cardElevation(defaultElevation = 6.dp)
                    ) {
                        Column(
                            modifier = Modifier.padding(20.dp),
                            verticalArrangement = Arrangement.spacedBy(12.dp)
                        ) {
                            Surface(
                                shape = RoundedCornerShape(999.dp),
                                color = CloserPalette.PurpleDeep.copy(alpha = 0.10f)
                            ) {
                                Text(
                                    text = "Day $displayDay",
                                    modifier = Modifier.padding(horizontal = 10.dp, vertical = 4.dp),
                                    style = MaterialTheme.typography.labelSmall,
                                    color = CloserPalette.PurpleDeep,
                                    fontWeight = FontWeight.SemiBold
                                )
                            }
                            Text(
                                text = dayPrompt.prompt,
                                style = MaterialTheme.typography.bodyLarge.copy(fontWeight = FontWeight.Medium),
                                color = MaterialTheme.colorScheme.onSurface,
                                lineHeight = MaterialTheme.typography.bodyLarge.lineHeight
                            )
                            if (dayPrompt.hint.isNotBlank()) {
                                Text(
                                    text = dayPrompt.hint,
                                    style = MaterialTheme.typography.bodySmall,
                                    color = MaterialTheme.colorScheme.onSurfaceVariant
                                )
                            }
                        }
                    }
                }

                item {
                    // Partner status row
                    val partnerDoneToday = progress.partnerCompletedDays.contains(displayDay)
                    Surface(
                        shape = RoundedCornerShape(16.dp),
                        color = if (partnerDoneToday)
                            CloserPalette.Evergreen.copy(alpha = 0.10f)
                        else
                            MaterialTheme.colorScheme.surface.copy(alpha = 0.6f)
                    ) {
                        Row(
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(14.dp),
                            verticalAlignment = Alignment.CenterVertically,
                            horizontalArrangement = Arrangement.spacedBy(10.dp)
                        ) {
                            if (partnerDoneToday) {
                                Icon(Icons.Filled.Check, contentDescription = null, tint = CloserPalette.Evergreen, modifier = Modifier.size(18.dp))
                                Text("Partner completed today", style = MaterialTheme.typography.bodySmall, color = CloserPalette.Evergreen, fontWeight = FontWeight.Medium)
                            } else {
                                Text("⏳", style = MaterialTheme.typography.bodySmall)
                                Text("Waiting for your partner", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
                            }
                        }
                    }
                }

                item {
                    // CTA
                    val iDoneToday = progress.myCompletedDays.contains(displayDay)
                    Button(
                        onClick = onMarkComplete,
                        enabled = !iDoneToday,
                        modifier = Modifier
                            .fillMaxWidth()
                            .heightIn(min = 54.dp),
                        shape = RoundedCornerShape(18.dp),
                        colors = ButtonDefaults.buttonColors(
                            containerColor = CloserPalette.PurpleDeep,
                            disabledContainerColor = CloserPalette.PurpleDeep.copy(alpha = 0.35f)
                        )
                    ) {
                        Text(
                            text = if (iDoneToday) "Done for today ✓" else "I did it today",
                            style = MaterialTheme.typography.labelLarge,
                            color = Color.White
                        )
                    }
                }
            }
        } else {
            item {
                // Completion state
                Card(
                    modifier = Modifier.fillMaxWidth(),
                    shape = RoundedCornerShape(24.dp),
                    colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
                    elevation = CardDefaults.cardElevation(defaultElevation = 6.dp)
                ) {
                    Column(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(28.dp),
                        horizontalAlignment = Alignment.CenterHorizontally,
                        verticalArrangement = Arrangement.spacedBy(12.dp)
                    ) {
                        Text("🎉", style = MaterialTheme.typography.displaySmall)
                        Text(
                            text = "Challenge complete!",
                            style = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.SemiBold),
                            color = MaterialTheme.colorScheme.onSurface,
                            textAlign = TextAlign.Center
                        )
                        Text(
                            text = "You and your partner finished \"${challenge.title}\" together. That's ${challenge.durationDays} days in a row.",
                            style = MaterialTheme.typography.bodyMedium,
                            color = MaterialTheme.colorScheme.onSurfaceVariant,
                            textAlign = TextAlign.Center
                        )
                    }
                }
            }
        }

        item { Spacer(Modifier.height(8.dp)) }
    }
}

@Composable
private fun DayTrackerStrip(
    totalDays: Int,
    myCompletedDays: List<Int>,
    partnerCompletedDays: List<Int>,
    currentDay: Int
) {
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        for (day in 1..totalDays) {
            val myDone = day in myCompletedDays
            val partnerDone = day in partnerCompletedDays
            val jointDone = myDone && partnerDone
            val isCurrent = day == currentDay.coerceAtMost(totalDays) && !myDone

            val bg = when {
                jointDone -> CloserPalette.PurpleDeep
                myDone -> CloserPalette.PurpleDeep.copy(alpha = 0.45f)
                isCurrent -> CloserPalette.PurpleDeep.copy(alpha = 0.15f)
                else -> MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f)
            }

            Box(
                modifier = Modifier
                    .weight(1f)
                    .height(36.dp)
                    .clip(RoundedCornerShape(10.dp))
                    .background(bg),
                contentAlignment = Alignment.Center
            ) {
                if (jointDone) {
                    Icon(Icons.Filled.Check, contentDescription = null, tint = Color.White, modifier = Modifier.size(14.dp))
                } else {
                    Text(
                        text = "$day",
                        style = MaterialTheme.typography.labelSmall,
                        color = if (myDone || isCurrent) Color.White else MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f),
                        fontWeight = FontWeight.SemiBold
                    )
                }
            }
        }
    }
}
