package com.zyzf.coffeepreorder.api.coffee

import android.util.Log
import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.zyzf.coffeepreorder.api.MyServerService
import com.zyzf.coffeepreorder.api.model.toCoffee
import com.zyzf.coffeepreorder.api.model.toCoffeeRemote
import com.zyzf.coffeepreorder.database.AppContainer
import com.zyzf.coffeepreorder.database.AppDatabase
import com.zyzf.coffeepreorder.database.model.Coffee
import com.zyzf.coffeepreorder.database.repository.CoffeeRepository
import com.zyzf.coffeepreorder.database.repository.OfflineCoffeeRepository
import com.zyzf.coffeepreorder.database.repository.OfflineRemoteKeyRepository
import kotlinx.coroutines.flow.Flow

class RestCoffeeRepository(
    private val service: MyServerService,
    private val dbCoffeeRepository: OfflineCoffeeRepository,
    private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
    private val database: AppDatabase
) : CoffeeRepository {
    override fun getAllCoffees(): Flow<PagingData<Coffee>> {
        Log.d(RestCoffeeRepository::class.simpleName, "Get coffees")

        val pagingSourceFactory = { dbCoffeeRepository.getAllCoffeesPagingSource() }

        @OptIn(ExperimentalPagingApi::class)
        return Pager(
            config = PagingConfig(
                pageSize = AppContainer.LIMIT,
                enablePlaceholders = false
            ),
            remoteMediator = CoffeeRemoteMediator(
                service,
                dbCoffeeRepository,
                dbRemoteKeyRepository,
                database,
            ),
            pagingSourceFactory = pagingSourceFactory
        ).flow
    }

    override suspend fun getByUid(uid: Int): Coffee =
        service.getCoffee(uid).toCoffee()

    override suspend fun insert(coffee: Coffee): Long {
        return service.createCoffee(coffee.toCoffeeRemote()).toCoffee().uid.toLong()
    }

    override suspend fun update(coffee: Coffee): Int {
        return service.updateCoffee(coffee.uid, coffee.toCoffeeRemote()).toCoffee().uid
    }

    override suspend fun delete(coffee: Coffee) {
        service.deleteCoffee(coffee.uid).toCoffee()
    }
}