package id.iiyh.inatrading.feature.product.presentation

import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import id.iiyh.inatrading.core.data.local.SessionManager
import id.iiyh.inatrading.core.data.remote.SessionExpiredException
import id.iiyh.inatrading.feature.auth.domain.repository.AuthRepository
import id.iiyh.inatrading.feature.cart.domain.CartRepository
import id.iiyh.inatrading.feature.product.data.model.ProductDetail
import id.iiyh.inatrading.feature.product.data.model.ProductModel
import id.iiyh.inatrading.feature.product.domain.ProductRepository
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject

const val CART_ADDED_MESSAGE = "__cart_added__"

data class ProductDetailUiState(
    val product: ProductDetail? = null,
    val isLoading: Boolean = false,
    val errorMessage: String? = null,
    val isLoggedIn: Boolean = false,
    val isAddingToCart: Boolean = false,
    val cartMessage: String? = null,
    val sessionExpired: Boolean = false,
    val canAddToCart: Boolean = false,
)

@HiltViewModel
class ProductDetailViewModel @Inject constructor(
    savedStateHandle: SavedStateHandle,
    private val productRepository: ProductRepository,
    private val cartRepository: CartRepository,
    private val authRepository: AuthRepository,
    sessionManager: SessionManager,
) : ViewModel() {

    private val productId: String = checkNotNull(savedStateHandle["productId"])

    private val _uiState = MutableStateFlow(ProductDetailUiState(isLoading = true))
    val uiState: StateFlow<ProductDetailUiState> = combine(
        _uiState,
        sessionManager.token,
    ) { state, token ->
        state.copy(isLoggedIn = !token.isNullOrBlank())
    }.stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5_000),
        initialValue = ProductDetailUiState(isLoading = true),
    )

    init {
        loadProduct()
    }

    fun loadProduct() {
        viewModelScope.launch {
            _uiState.update { it.copy(isLoading = true, errorMessage = null) }
            productRepository.getProductDetail(productId)
                .onSuccess { product ->
                    _uiState.update {
                        it.copy(
                            product = product,
                            isLoading = false,
                            errorMessage = null,
                            canAddToCart = product.primaryCartModel()?.let { model ->
                                model.primaryAvailableStock() > 0 && model.displayCartPrice() > 0.0
                            } == true,
                        )
                    }
                }
                .onFailure { error ->
                    _uiState.update {
                        it.copy(
                            isLoading = false,
                            errorMessage = error.message ?: "Gagal memuat detail produk",
                        )
                    }
                }
        }
    }

    fun addToCart() {
        val product = _uiState.value.product ?: return
        val sellerId = product.seller?.id
            ?: run {
                _uiState.update { it.copy(cartMessage = "Seller produk tidak ditemukan") }
                return
            }
        val model = product.primaryCartModel()
            ?: run {
                _uiState.update { it.copy(cartMessage = "Model produk belum tersedia") }
                return
            }
        val productModelId = model.id
            ?: run {
                _uiState.update { it.copy(cartMessage = "ID model produk tidak ditemukan") }
                return
            }
        val warehouseId = model.primaryWarehouseId()
            ?: run {
                _uiState.update { it.copy(cartMessage = "Warehouse produk tidak ditemukan") }
                return
            }
        if (model.primaryAvailableStock() <= 0) {
            _uiState.update { it.copy(cartMessage = "Stok produk habis") }
            return
        }
        if (model.displayCartPrice() <= 0.0) {
            _uiState.update { it.copy(cartMessage = "Produk ini belum memiliki harga untuk ditambahkan ke keranjang") }
            return
        }

        viewModelScope.launch {
            _uiState.update { it.copy(isAddingToCart = true, cartMessage = null, sessionExpired = false) }
            cartRepository.addToCart(
                sellerId = sellerId,
                productModelId = productModelId,
                warehouseId = warehouseId,
                quantity = 1,
                productMeasurementId = model.primaryMeasurementId(),
            ).onSuccess {
                _uiState.update {
                    it.copy(
                        isAddingToCart = false,
                        cartMessage = CART_ADDED_MESSAGE,
                    )
                }
            }.onFailure { error ->
                if (error is SessionExpiredException) {
                    authRepository.logout()
                    _uiState.update {
                        it.copy(
                            isAddingToCart = false,
                            sessionExpired = true,
                            cartMessage = null,
                        )
                    }
                } else {
                    _uiState.update {
                        it.copy(
                            isAddingToCart = false,
                            cartMessage = error.message ?: "Gagal menambahkan produk ke keranjang",
                        )
                    }
                }
            }
        }
    }

    fun consumeCartMessage() {
        _uiState.update { it.copy(cartMessage = null) }
    }

    fun consumeSessionExpired() {
        _uiState.update { it.copy(sessionExpired = false) }
    }
}

private fun ProductDetail.primaryCartModel(): ProductModel? = productModels.firstOrNull()

private fun ProductModel.primaryWarehouseId(): String? =
    productMeasurements.firstOrNull()
        ?.warehouses
        ?.firstOrNull()
        ?.id
        ?: warehouses.firstOrNull()?.id

private fun ProductModel.primaryMeasurementId(): String =
    productMeasurements.firstOrNull()?.id.orEmpty()

private fun ProductModel.primaryAvailableStock(): Int =
    productMeasurements.firstOrNull()
        ?.warehouses
        ?.firstOrNull()
        ?.stock
        ?: warehouses.firstOrNull()?.stock
        ?: 0

private fun ProductModel.displayCartPrice(): Double {
    return promotionPrice?.takeIf { it > 0.0 }
        ?: price?.takeIf { it > 0.0 }
        ?: 0.0
}
