package com.example.myapplication.database.room.repository

import android.content.Context
import com.example.myapplication.api.MyServerService
import com.example.myapplication.api.bike.repository.RestBikeRepository
import com.example.myapplication.api.rent.repository.RestRentRepository
import com.example.myapplication.api.rent.rentitem.repository.RestRentItemRepository
import com.example.myapplication.api.item.repository.RestItemRepository
import com.example.myapplication.api.user.repository.RestUserRepository
import com.example.myapplication.api.useritem.repository.RestUserItemRepository
import com.example.myapplication.database.AppDatabase
import com.example.myapplication.database.remotekeys.repository.offline.OfflineRemoteKeyRepository
import com.example.myapplication.database.room.repository.offline.OfflineBikeRepository
import com.example.myapplication.database.room.repository.offline.OfflineItemRepository
import com.example.myapplication.database.room.repository.offline.OfflineRentItemRepository
import com.example.myapplication.database.room.repository.offline.OfflineRentRepository
import com.example.myapplication.database.room.repository.offline.OfflineUserItemRepository
import com.example.myapplication.database.room.repository.offline.OfflineUserRepository

interface AppContainer {
    val bikeRestRepository: RestBikeRepository
    val itemRestRepository: RestItemRepository
    val userRestRepository: RestUserRepository
    val rentRestRepository: RestRentRepository
    val rentItemRestRepository: RestRentItemRepository
    val userItemRestRepository: RestUserItemRepository

    companion object {
        const val TIMEOUT = 5000L
        const val LIMIT = 10
    }
}

class AppDataContainer(private val context: Context) : AppContainer {
    private val bikeRepository: OfflineBikeRepository by lazy {
        OfflineBikeRepository(AppDatabase.getInstance(context).bikeDao())
    }
    private val rentRepository: OfflineRentRepository by lazy {
        OfflineRentRepository(AppDatabase.getInstance(context).rentDao())
    }
    private val rentItemRepository: OfflineRentItemRepository by lazy {
        OfflineRentItemRepository(AppDatabase.getInstance(context).rentItemCrossRefDao())
    }
    private val itemRepository: OfflineItemRepository by lazy {
        OfflineItemRepository(AppDatabase.getInstance(context).itemDao())
    }
    private val userRepository: OfflineUserRepository by lazy {
        OfflineUserRepository(AppDatabase.getInstance(context).userDao())
    }
    private val userItemRepository: OfflineUserItemRepository by lazy {
        OfflineUserItemRepository(AppDatabase.getInstance(context).userItemCrossRefDao())
    }
    private val remoteKeyRepository: OfflineRemoteKeyRepository by lazy {
        OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao())
    }
    override val bikeRestRepository: RestBikeRepository by lazy {
        RestBikeRepository(
            MyServerService.getInstance(),
            bikeRepository,
            itemRepository,
            remoteKeyRepository,
            AppDatabase.getInstance(context)
        )
    }
    override val itemRestRepository: RestItemRepository by lazy {
        RestItemRepository(
            MyServerService.getInstance(),
            itemRepository,
            userItemRepository,
            rentItemRepository,
        )
    }
    override val userRestRepository: RestUserRepository by lazy {
        RestUserRepository(
            MyServerService.getInstance(),
            userRepository,
            userItemRepository,
        )
    }
    override val rentRestRepository: RestRentRepository by lazy {
        RestRentRepository(
            MyServerService.getInstance(),
            rentRepository,
            bikeRepository,
            rentItemRepository,
            remoteKeyRepository,
            AppDatabase.getInstance(context)
        )
    }
    override val userItemRestRepository: RestUserItemRepository by lazy {
        RestUserItemRepository(
            MyServerService.getInstance(),
            userItemRepository,
        )
    }
    override val rentItemRestRepository: RestRentItemRepository by lazy {
        RestRentItemRepository(
            MyServerService.getInstance(),
            rentItemRepository,
        )
    }
}