package app.closer.ui.games

import app.closer.ui.theme.closerBackgroundBrush
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.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
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.material3.Button
import app.closer.ui.components.CloserHeartLoader
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
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.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
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.domain.model.GameType
import app.closer.domain.usecase.GameSessionManager
import app.closer.ui.components.CategoryGlyph
import app.closer.ui.components.BrandMessageRotator
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
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 ────────────────────────────────────────────────────────────────

data class WaitingForPartnerUiState(
    val isLoading: Boolean = true,
    val gameType: String = GameType.WHEEL,
    val partnerName: String = "Partner",
    val navigateTo: String? = null
)

@HiltViewModel
class WaitingForPartnerViewModel @Inject constructor(
    private val gameSessionManager: GameSessionManager
) : ViewModel() {
    private val _uiState = MutableStateFlow(WaitingForPartnerUiState())
    val uiState: StateFlow<WaitingForPartnerUiState> = _uiState.asStateFlow()

    private var coupleId: String? = null

    init {
        viewModelScope.launch {
            val userId = gameSessionManager.currentUserId ?: return@launch
            val couple = runCatching { gameSessionManager.getCoupleForUser(userId) }.getOrNull()
                ?: return@launch
            coupleId = couple.id

            val partnerId = couple.userIds.firstOrNull { it != userId }
            // getUser() throws on Firestore failure (e.g. PERMISSION_DENIED); never let
            // that escape this launch or the whole app crashes on the waiting screen.
            val partnerName = partnerId
                ?.let { runCatching { gameSessionManager.getUser(it) }.getOrNull() }
                ?.displayName ?: "Partner"

            gameSessionManager.observeActiveSession(couple.id).collect { session ->
                if (session == null) {
                    _uiState.update { it.copy(navigateTo = AppRoute.PLAY) }
                } else {
                    _uiState.update {
                        it.copy(
                            isLoading = false,
                            gameType = session.gameType,
                            partnerName = partnerName
                        )
                    }
                }
            }
        }
    }

    /** Force-end the partner's active session so this user can start a new game. */
    fun abandonPartnerGame() {
        val cId = coupleId ?: return
        viewModelScope.launch {
            gameSessionManager.abandonSession(cId)
            _uiState.update { it.copy(navigateTo = AppRoute.PLAY) }
        }
    }

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

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

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

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

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(closerBackgroundBrush())
    ) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .safeDrawingPadding()
                .navigationBarsPadding()
                .padding(horizontal = 24.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            when {
                state.isLoading -> {
                    CloserHeartLoader(size = 64.dp)
                    Text(
                        text = "Loading...",
                        style = MaterialTheme.typography.bodyLarge,
                        modifier = Modifier.padding(top = 16.dp)
                    )
                    BrandMessageRotator(
                        modifier = Modifier.padding(top = 16.dp),
                        style = MaterialTheme.typography.bodySmall
                    )
                }
                else -> {
                    CategoryGlyph(
                        categoryId = gameTypeGlyphKey(state.gameType),
                        size = 80.dp,
                        iconSize = 38.dp
                    )

                    Text(
                        text = "Waiting for ${state.partnerName}",
                        style = MaterialTheme.typography.headlineSmall,
                        modifier = Modifier.padding(top = 24.dp),
                        textAlign = TextAlign.Center
                    )

                    Text(
                        text = "${state.partnerName} is playing a ${gameTypeLabel(state.gameType)} game.",
                        style = MaterialTheme.typography.bodyLarge,
                        color = MaterialTheme.colorScheme.onSurfaceVariant,
                        modifier = Modifier.padding(top = 8.dp, bottom = 24.dp),
                        textAlign = TextAlign.Center
                    )

                    BrandMessageRotator(
                        modifier = Modifier.padding(bottom = 16.dp),
                        style = MaterialTheme.typography.bodySmall
                    )

                    Button(
                        onClick = { onNavigate(AppRoute.PLAY) },
                        modifier = Modifier.fillMaxWidth()
                    ) {
                        Text("Back to Games")
                    }
                    TextButton(onClick = viewModel::abandonPartnerGame) {
                        Text(
                            "End their game",
                            style = MaterialTheme.typography.bodySmall,
                            color = MaterialTheme.colorScheme.onSurfaceVariant
                        )
                    }
                }
            }
        }
    }
}

private fun gameTypeLabel(gameType: String): String = when (gameType) {
    GameType.WHEEL -> "Wheel"
    GameType.THIS_OR_THAT -> "This or That"
    GameType.HOW_WELL -> "How Well Do You Know Me"
    GameType.DESIRE_SYNC -> "Desire Sync"
    else -> gameType
}

private fun gameTypeGlyphKey(gameType: String): String = when (gameType) {
    GameType.WHEEL -> "play"
    GameType.THIS_OR_THAT -> "question"
    GameType.HOW_WELL -> "predict"
    GameType.DESIRE_SYNC -> "sex_and_desire"
    else -> "play"
}
