package com.example.myapplication.api.rent

import android.util.Log
import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.example.myapplication.api.MyServerService
import com.example.myapplication.api.bike.toBikeRemote
import com.example.myapplication.api.item.toItemFromRent
import com.example.myapplication.database.AppContainer
import com.example.myapplication.database.AppDatabase
import com.example.myapplication.database.entities.model.Rent
import com.example.myapplication.database.entities.model.RentItemCrossRef
import com.example.myapplication.database.entities.model.ItemFromRent
import com.example.myapplication.database.entities.repository.OfflineBikeRepository
import com.example.myapplication.database.entities.repository.OfflineRentRepository
import com.example.myapplication.database.entities.repository.OfflineRentItemRepository
import com.example.myapplication.database.entities.repository.RentRepository
import com.example.myapplication.database.remotekeys.repository.OfflineRemoteKeyRepository
import kotlinx.coroutines.flow.Flow

class RestRentRepository(
    private val service: MyServerService,
    private val dbRentRepository: OfflineRentRepository,
    private val dbBikeRepository: OfflineBikeRepository,
    private val dbRentItemRepository: OfflineRentItemRepository,
    private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
    private val database: AppDatabase
) : RentRepository {
    override fun getAllRents(userId: Int?): Flow<PagingData<Rent>> {
        Log.d(RestRentRepository::class.simpleName, "Get rents")

        val pagingSourceFactory = { dbRentRepository.getAllRentsPagingSource(userId) }

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

    override suspend fun getRent(uid: Int): List<ItemFromRent> {
        val rent = service.getRent(uid)

        dbRentItemRepository.deleteRentItems(uid)
        rent.items.map {
            dbRentItemRepository.insertRentItem(
                RentItemCrossRef(
                    uid,
                    it.id,
                    it.frozenWeight,
                    it.count
                )
            )
        }
        return rent.items.map { x -> x.toItemFromRent(dbBikeRepository.getBike(x.bikeId).bike.toBikeRemote()) }
    }

    override suspend fun insertRent(rent: Rent): Long {
        return dbRentRepository.insertRent(service.createRent(rent.toRentRemote()).toRent())
    }

    override suspend fun deleteRent(rent: Rent) {
        service.deleteRent(rent.uid)
        dbRentRepository.deleteRent(rent)
    }
}