package com.jishisongfu.duobibi.ui.records

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.jishisongfu.duobibi.data.repo.PriceRepository
import com.jishisongfu.duobibi.util.OverallStats
import com.jishisongfu.duobibi.util.StatsCalculator
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn
import javax.inject.Inject

data class ProductGroup(
    val clusterId: Long,
    val title: String,
    val recordCount: Int,
    val minPrice: Double,
    val maxPrice: Double,
    val minSourceApp: String,
    val sources: List<String>,
    val typicalPrice: Double?,
    val latestAt: Long,
)

@HiltViewModel
class RecordsViewModel @Inject constructor(
    private val repo: PriceRepository,
) : ViewModel() {

    private val _query = MutableStateFlow("")
    val query: StateFlow<String> = _query

    val groups: StateFlow<List<ProductGroup>> = combine(
        repo.observeAllClusters(),
        repo.observeAllRecords(),
        _query,
    ) { clusters, records, q ->
        val byCluster = records.groupBy { it.clusterId }
        clusters.mapNotNull { c ->
            val items = byCluster[c.id].orEmpty()
            if (items.isEmpty()) return@mapNotNull null
            if (q.isNotBlank() && !c.title.contains(q.trim(), ignoreCase = true)) return@mapNotNull null
            val minRec = items.minBy { it.price }
            ProductGroup(
                clusterId = c.id,
                title = c.title,
                recordCount = items.size,
                minPrice = minRec.price,
                maxPrice = items.maxOf { it.price },
                minSourceApp = minRec.sourceApp,
                sources = items.map { it.sourceApp }.distinct(),
                typicalPrice = c.typicalPrice,
                latestAt = items.maxOf { it.createdAt },
            )
        }.sortedByDescending { it.latestAt }
    }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), emptyList())

    val overall: StateFlow<OverallStats?> = combine(
        repo.observeAllClusters(),
        repo.observeAllRecords(),
    ) { clusters, records ->
        StatsCalculator.computeOverall(clusters, records)
    }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), null)

    fun setQuery(q: String) { _query.value = q }
}
