package id.iiyh.inatrading.feature.explore.presentation

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import id.iiyh.inatrading.feature.explore.data.model.LocationItem
import id.iiyh.inatrading.feature.explore.domain.LocationRepository
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

private const val LOCATION_PAGE_LIMIT = 10

data class ExploreUiState(
    val items: List<LocationItem> = emptyList(),
    val isInitialLoading: Boolean = false,
    val isAppending: Boolean = false,
    val errorMessage: String? = null,
    val currentPage: Int = 0,
    val totalPage: Int = 0,
    val totalItem: Int = 0,
    val searchQuery: String = "",
) {
    val hasMore: Boolean
        get() = totalPage == 0 || currentPage < totalPage || items.size < totalItem

    val filteredItems: List<LocationItem>
        get() = items.filter { location ->
            val query = searchQuery.trim()
            if (query.isBlank()) {
                true
            } else {
                listOf(
                    location.name,
                    location.type,
                    location.city,
                    location.province,
                    location.country,
                    location.address,
                    location.description,
                ).any { it.orEmpty().contains(query, ignoreCase = true) }
            }
        }
}

@HiltViewModel
class ExploreViewModel @Inject constructor(
    private val locationRepository: LocationRepository,
) : ViewModel() {

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

    init {
        loadInitial()
    }

    fun loadInitial() {
        _uiState.update {
            it.copy(
                items = emptyList(),
                isInitialLoading = true,
                isAppending = false,
                errorMessage = null,
                currentPage = 0,
                totalPage = 0,
                totalItem = 0,
            )
        }
        loadPage(1)
    }

    fun loadNextPage() {
        val state = _uiState.value
        if (state.isInitialLoading || state.isAppending || !state.hasMore) return
        loadPage(state.currentPage + 1)
    }

    fun onSearchQueryChange(value: String) {
        _uiState.update { it.copy(searchQuery = value) }
    }

    private fun loadPage(page: Int) {
        viewModelScope.launch {
            _uiState.update {
                it.copy(
                    isInitialLoading = page == 1,
                    isAppending = page > 1,
                    errorMessage = if (page == 1) null else it.errorMessage,
                )
            }

            locationRepository.getLocations(page = page, limit = LOCATION_PAGE_LIMIT)
                .onSuccess { result ->
                    _uiState.update { state ->
                        state.copy(
                            items = if (page == 1) result.items else state.items + result.items,
                            isInitialLoading = false,
                            isAppending = false,
                            errorMessage = null,
                            currentPage = page,
                            totalPage = result.totalPage,
                            totalItem = result.totalItem,
                        )
                    }
                }
                .onFailure { error ->
                    _uiState.update {
                        it.copy(
                            isInitialLoading = false,
                            isAppending = false,
                            errorMessage = error.message ?: "Gagal memuat lokasi",
                        )
                    }
                }
        }
    }
}
