/*
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package com.runicgateway.app.ui.session

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.runicgateway.app.core.auth.Session
import com.runicgateway.app.core.auth.SessionManager
import com.runicgateway.app.data.repository.AuthRepository
import com.runicgateway.app.data.repository.ShardFeatures
import com.runicgateway.app.data.repository.ShardFeaturesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * Activity-scoped view of the current session for the app shell (PLAN.md §4.3,
 * §5): the shared menu observes [session] to reveal signed-in groups + the
 * sign-in/out toggle, and the shell drives resume re-validation and sign-out.
 * Login itself lives in [com.runicgateway.app.ui.auth.LoginViewModel].
 */
@HiltViewModel
class SessionViewModel @Inject constructor(
    sessionManager: SessionManager,
    private val authRepository: AuthRepository,
    shardFeaturesRepository: ShardFeaturesRepository,
) : ViewModel() {

    val session: StateFlow<Session> = sessionManager.state

    /**
     * Which shard features this viewer may reach (M11). Held here beside [session]
     * because it answers the same question for the same consumer: what the shared
     * menu reveals. Role and feature config are independent gates — see
     * [com.runicgateway.app.ui.navigation.visibleEntries].
     */
    val shardFeatures: StateFlow<ShardFeatures?> = shardFeaturesRepository.features

    init {
        // The answer is per-viewer, so it is re-resolved on every session change.
        // A StateFlow conflates equal values, so a resume revalidation that returns
        // the same user does not refetch — only a real sign-in/out/role change does.
        viewModelScope.launch {
            session.collect { shardFeaturesRepository.refresh() }
        }
    }

    /** Re-validate the cached role against the backend on app resume. */
    fun revalidate() {
        viewModelScope.launch { authRepository.revalidate() }
    }

    /** Sign out of this session, or every session with [allDevices]. */
    fun signOut(allDevices: Boolean = false) {
        viewModelScope.launch { authRepository.logout(allDevices) }
    }
}
