package com.prodhack.moscow2025.data.base

import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import androidx.room.RoomDatabase
import androidx.room.withTransaction

@OptIn(ExperimentalPagingApi::class)
class BaseRemoteMediator<DBEntity : Any>(
	private val db: RoomDatabase,
	private val dao: BasePaginationDAO<DBEntity>,
	private val makeRequest: suspend (page: Long, pageCount: Int) -> Result<List<DBEntity>>
) : RemoteMediator<Int, DBEntity>() {

	override suspend fun load(
		loadType: LoadType,
		state: PagingState<Int, DBEntity>
	): MediatorResult {
		return try {
			val loadKey = when (loadType) {
				LoadType.REFRESH -> 1
				LoadType.PREPEND -> return MediatorResult.Success(
					endOfPaginationReached = true
				)

				LoadType.APPEND -> {
					state.pages.size + 1
				}
			}

			val result = makeRequest(
				(loadKey.toLong() - 1) * state.config.pageSize,
				state.config.pageSize
			)

			if (result.isSuccess) {
				val data = result.getOrNull()!!
				db.withTransaction {
					if (loadType == LoadType.REFRESH) {
						dao.clearAll()
					}
					dao.upsertAll(data)
				}
				MediatorResult.Success(
					endOfPaginationReached = data.size < state.config.pageSize
				)
			} else {
				MediatorResult.Error(result.exceptionOrNull()!!)
			}
		} catch (e: Exception) {
			MediatorResult.Error(e)
		}
	}
}