package app.closer.ui.pairing

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.closer.crypto.CoupleEncryptionManager
import app.closer.crypto.RecoveryKeyManager
import app.closer.domain.repository.AuthRepository
import app.closer.domain.repository.CoupleRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject

data class RecoveryUiState(
    val phrase: String = "",
    val isLoading: Boolean = false,
    val error: String? = null,
    val success: Boolean = false
)

@HiltViewModel
class RecoveryViewModel @Inject constructor(
    private val authRepository: AuthRepository,
    private val coupleRepository: CoupleRepository,
    private val encryptionManager: CoupleEncryptionManager
) : ViewModel() {

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

    fun onPhraseChanged(phrase: String) = _uiState.update { it.copy(phrase = phrase, error = null) }

    fun recover() {
        val phrase = _uiState.value.phrase.trim()
        if (phrase.isBlank()) {
            _uiState.update { it.copy(error = "Enter your recovery phrase.") }
            return
        }
        _uiState.update { it.copy(isLoading = true, error = null) }
        viewModelScope.launch {
            val userId = authRepository.currentUserId ?: run {
                _uiState.update { it.copy(isLoading = false, error = "Not signed in.") }
                return@launch
            }
            val couple = coupleRepository.getCoupleForUser(userId)
            if (couple == null || couple.wrappedCoupleKey == null) {
                _uiState.update { it.copy(isLoading = false, error = "Couldn't load couple data. Try again.") }
                return@launch
            }
            val wrapped = RecoveryKeyManager.WrappedKey(
                cipherB64 = couple.wrappedCoupleKey,
                saltB64 = couple.kdfSalt ?: "",
                params = couple.kdfParams ?: ""
            )
            encryptionManager.unwrapAndStore(couple.id, wrapped, phrase)
                .onSuccess {
                    _uiState.update { it.copy(isLoading = false, success = true) }
                }
                .onFailure { e ->
                    val msg = when {
                        e.message?.contains("AEADBadTag", ignoreCase = true) == true ||
                        e.message?.contains("decryption", ignoreCase = true) == true ->
                            "That phrase doesn't match. Check with your partner and try again."
                        else -> "Recovery failed. Please check your phrase and try again."
                    }
                    _uiState.update { it.copy(isLoading = false, error = msg) }
                }
        }
    }

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