package app.closer.ui.paywall

import android.app.Activity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.closer.domain.repository.BillingRepository
import app.closer.domain.repository.BillingState
import com.revenuecat.purchases.CustomerInfo
import com.revenuecat.purchases.Offerings
import com.revenuecat.purchases.Package
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

data class PaywallUiState(
    val isLoading: Boolean = true,
    val offerings: Offerings? = null,
    val selectedPackage: Package? = null,
    val customerInfo: CustomerInfo? = null,
    val purchaseState: BillingState<*>? = null,
    val error: String? = null
) {
    val packages: List<Package>
        get() = offerings?.current?.availablePackages ?: emptyList()
}

@HiltViewModel
class PaywallViewModel @Inject constructor(
    private val billingRepository: BillingRepository
) : ViewModel() {

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

    init {
        loadOfferings()
        observeCustomerInfo()
    }

    private fun loadOfferings() {
        viewModelScope.launch {
            _uiState.update { it.copy(isLoading = true, error = null) }
            when (val result = billingRepository.getOfferings()) {
                is BillingState.Loading -> _uiState.update { it.copy(isLoading = true) }
                is BillingState.Success -> _uiState.update {
                    it.copy(
                        isLoading = false,
                        offerings = result.data,
                        selectedPackage = result.data.current?.availablePackages?.firstOrNull()
                    )
                }
                is BillingState.Error -> _uiState.update {
                    it.copy(isLoading = false, error = result.message)
                }
            }
        }
    }

    private fun observeCustomerInfo() {
        viewModelScope.launch {
            billingRepository.getCustomerInfo().collect { state ->
                when (state) {
                    is BillingState.Loading -> Unit
                    is BillingState.Success -> _uiState.update { it.copy(customerInfo = state.data) }
                    is BillingState.Error -> _uiState.update {
                        it.copy(error = state.message)
                    }
                }
            }
        }
    }

    fun selectPackage(pkg: Package) {
        _uiState.update { it.copy(selectedPackage = pkg) }
    }

    fun purchase(activity: Activity) {
        val pkg = _uiState.value.selectedPackage ?: return
        viewModelScope.launch {
            _uiState.update { it.copy(purchaseState = BillingState.Loading) }
            val result = billingRepository.purchasePackage(pkg)
            _uiState.update { it.copy(purchaseState = result) }
        }
    }

    fun restore() {
        viewModelScope.launch {
            _uiState.update { it.copy(purchaseState = BillingState.Loading) }
            when (val result = billingRepository.restorePurchases()) {
                is BillingState.Loading -> Unit
                is BillingState.Success -> _uiState.update {
                    it.copy(
                        purchaseState = result,
                        customerInfo = result.data,
                        error = null
                    )
                }
                is BillingState.Error -> _uiState.update {
                    it.copy(purchaseState = result, error = result.message)
                }
            }
        }
    }

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

    fun retry() = loadOfferings()
}
