package com.zyzf.coffeepreorder.api.user

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.toUser
import com.zyzf.coffeepreorder.api.model.toUserRemote
import com.zyzf.coffeepreorder.database.AppContainer
import com.zyzf.coffeepreorder.database.AppDatabase
import com.zyzf.coffeepreorder.database.model.User
import com.zyzf.coffeepreorder.database.repository.OfflineRemoteKeyRepository
import com.zyzf.coffeepreorder.database.repository.OfflineUserRepository
import com.zyzf.coffeepreorder.database.repository.UserRepository
import kotlinx.coroutines.flow.Flow

class RestUserRepository(
    private val service: MyServerService,
    private val dbUserRepository: OfflineUserRepository,
    private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
    private val database: AppDatabase
) : UserRepository {
    override fun getAll(): Flow<PagingData<User>> {
        Log.d(RestUserRepository::class.simpleName, "Get users")

        val pagingSourceFactory = { dbUserRepository.getAllUserPagingSource() }

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

    override suspend fun getByUid(uid: Int): User =
        service.getUser(uid).toUser()!!

    override suspend fun tryLogin(login: String, password: String): User? =
        service.tryLogin(login, password).toUser()


    override suspend fun insert(user: User): Long {
        return service.createUser(user.toUserRemote()).toUser()?.uid?.toLong()!!
    }

    override suspend fun update(user: User): Int {
        return service.updateUser(user.uid, user.toUserRemote()).toUser()?.uid!!
    }

    override suspend fun delete(user: User) {
        service.deleteUser(user.uid).toUser()
    }
}