package com.example.livingai.pages.listings

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.cachedIn
import androidx.paging.filter
import com.example.livingai.domain.model.AnimalProfile
import com.example.livingai.domain.usecases.ProfileListing.ProfileListingUseCase
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch

sealed class ListingsEvent {
    object Refresh : ListingsEvent()
}

class ListingsViewModel(
    private val profileListingUseCase: ProfileListingUseCase
) : ViewModel() {

    var searchQuery = MutableStateFlow("")
    var selectedSpecies = MutableStateFlow<String?>(null)
    var selectedBreed = MutableStateFlow<String?>(null)
    var minAge = MutableStateFlow("")
    var maxAge = MutableStateFlow("")

    private val _events = Channel<ListingsEvent>()
    val events = _events.receiveAsFlow()

    private val filters = combine(
        searchQuery,
        selectedSpecies,
        selectedBreed,
        minAge,
        maxAge
    ) { query, species, breed, minAgeStr, maxAgeStr ->
        FilterState(query, species, breed, minAgeStr, maxAgeStr)
    }

    @OptIn(FlowPreview::class, ExperimentalCoroutinesApi::class)
    val animalProfiles: Flow<androidx.paging.PagingData<AnimalProfile>> = filters.flatMapLatest { filter ->
        profileListingUseCase.getAnimalProfiles().map { pagingData ->
            val min = filter.minAge.toIntOrNull() ?: 0
            val max = filter.maxAge.toIntOrNull() ?: Int.MAX_VALUE
            
            pagingData.filter { profile: AnimalProfile ->
                val matchesQuery = profile.name.contains(filter.query, ignoreCase = true) || 
                                   profile.breed.contains(filter.query, ignoreCase = true)
                
                val matchesSpecies = filter.species == null || profile.species.equals(filter.species, ignoreCase = true)
                val matchesBreed = filter.breed == null || profile.breed.equals(filter.breed, ignoreCase = true)
                
                val matchesAge = profile.age in min..max
                
                matchesQuery && matchesSpecies && matchesBreed && matchesAge
            }
        }
    }.cachedIn(viewModelScope)

    fun deleteAnimalProfile(animalId: String) {
        viewModelScope.launch {
            profileListingUseCase.deleteAnimalProfile(animalId)
            _events.send(ListingsEvent.Refresh)
        }
    }
    
    private data class FilterState(
        val query: String,
        val species: String?,
        val breed: String?,
        val minAge: String,
        val maxAge: String
    )
}
