package com.example.myapplication.viewModels

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.paging.PagingData
import androidx.paging.cachedIn
import com.example.myapplication.MyApp
import com.example.myapplication.api.MyServerService
import com.example.myapplication.api.repository.ProductRestRepository
import com.example.myapplication.api.repository.RestCategoryRepository
import com.example.myapplication.database.entities.Product
import com.example.myapplication.database.repository.OfflineProductRepository
import com.example.myapplication.database.repository.OfflineRemoteKeyRepository
import com.example.myapplication.database.repository.ProductRepository
import kotlinx.coroutines.flow.Flow

class ProductViewModel(
    private val productRepository: ProductRepository
) : ViewModel() {
    companion object {
        val factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory{
            override fun <T: ViewModel> create(
                modelClass: Class<T>,
                extras: CreationExtras) : T {

                val app: MyApp = (checkNotNull(extras[APPLICATION_KEY]) as MyApp)

                return ProductViewModel(
                    ProductRestRepository(
                    MyServerService.getInstance(),
                    app.db.productDao(),
                    app.productRepository,
                    OfflineRemoteKeyRepository(app.db.remoteKeysDao()),
                    RestCategoryRepository(MyServerService.getInstance(), app.categoryRepository),
                    app.db
                )
                ) as T
            }
        }
    }

    fun getAll() : Flow<PagingData<Product>> {
        return productRepository.getAll().cachedIn(viewModelScope)
    }

    fun getById(id: Int) : Flow<Product> {
        return productRepository.getById(id)
    }

    fun getByCategory(cId: Int): Flow<PagingData<Product>> {
        return productRepository.getByCategory(cId).cachedIn(viewModelScope)
    }

    suspend fun insert(product: Product) {
        productRepository.insert(product)
    }
}