package app.closer.ui.wheel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.closer.core.billing.CouplePremiumChecker
import app.closer.core.navigation.AppRoute
import app.closer.domain.model.GameType
import app.closer.domain.model.QuestionCategory
import app.closer.domain.repository.QuestionRepository
import app.closer.domain.usecase.GameSessionManager
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.first
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

data class CategoryPickerItem(
    val category: QuestionCategory,
    val questionCount: Int,
    val isLocked: Boolean
)

data class CategoryPickerUiState(
    val isLoading: Boolean = true,
    val error: String? = null,
    val categories: List<CategoryPickerItem> = emptyList(),
    val navigateTo: String? = null
)

@HiltViewModel
class CategoryPickerViewModel @Inject constructor(
    private val repository: QuestionRepository,
    private val premiumChecker: CouplePremiumChecker,
    private val gameSessionManager: GameSessionManager
) : ViewModel() {

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

    init {
        checkActiveSession()
        load()
    }

    /**
     * If the couple already has a game in progress, don't let the user spin a new
     * wheel: join the active wheel (so the partner answers the same spun set) or, for
     * any other game, fall back to the waiting screen.
     */
    private fun checkActiveSession() {
        viewModelScope.launch {
            val uid = gameSessionManager.currentUserId ?: return@launch
            val couple = gameSessionManager.getCoupleForUser(uid) ?: run {
                _uiState.update { it.copy(navigateTo = AppRoute.CREATE_INVITE) }
                return@launch
            }
            val active = runCatching { gameSessionManager.getActiveSession(couple.id) }
                .getOrNull() ?: return@launch
            val target = if (active.gameType == GameType.WHEEL) {
                AppRoute.wheelSession(active.id)
            } else {
                AppRoute.WAITING_FOR_PARTNER
            }
            _uiState.update { it.copy(navigateTo = target) }
        }
    }

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

    fun load() {
        viewModelScope.launch {
            // Use copy() rather than full reassignment so a pending navigateTo from
            // checkActiveSession isn't clobbered by the category load finishing.
            _uiState.update { it.copy(isLoading = true, error = null) }
            try {
                val hasPremium = premiumChecker.isPremium().first()
                val items = repository.getCategories().map { category ->
                    CategoryPickerItem(
                        category = category,
                        questionCount = repository.getQuestionCountByCategory(category.id),
                        isLocked = category.access == "premium" && !hasPremium
                    )
                }
                _uiState.update { it.copy(isLoading = false, categories = items, error = null) }
            } catch (e: Exception) {
                _uiState.update {
                    it.copy(isLoading = false, error = e.message ?: "Could not load categories.")
                }
            }
        }
    }
}
