package com.pixelized.biblib.module

import android.app.Application
import android.content.SharedPreferences
import com.google.gson.Gson
import com.pixelized.biblib.database.BibLibDatabase
import com.pixelized.biblib.network.client.IBibLibClient
import com.pixelized.biblib.network.factory.BookFactory
import com.pixelized.biblib.network.factory.GenreFactory
import com.pixelized.biblib.network.factory.SeriesFactory
import com.pixelized.biblib.network.factory.UserFactory
import com.pixelized.biblib.repository.apiCache.APICacheRepository
import com.pixelized.biblib.repository.apiCache.IAPICacheRepository
import com.pixelized.biblib.repository.book.BookRepository
import com.pixelized.biblib.repository.book.IBookRepository
import com.pixelized.biblib.repository.credential.CredentialRepository
import com.pixelized.biblib.repository.credential.ICredentialRepository
import com.pixelized.biblib.repository.googleSignIn.GoogleSingInRepository
import com.pixelized.biblib.repository.googleSignIn.IGoogleSingInRepository
import com.pixelized.biblib.repository.search.ISearchRepository
import com.pixelized.biblib.repository.search.SearchRepository
import com.pixelized.biblib.repository.user.IUserRepository
import com.pixelized.biblib.repository.user.UserRepository
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
class RepositoryModule {

    @Provides
    @Singleton
    fun provideGoogleSingInRepository(
        application: Application,
    ): IGoogleSingInRepository {
        return GoogleSingInRepository(
            application = application
        )
    }

    @Provides
    @Singleton
    fun provideCredentialRepository(
        preferences: SharedPreferences,
    ): ICredentialRepository {
        return CredentialRepository(
            preferences = preferences,
        )
    }

    @Provides
    @Singleton
    fun provideAPICacheRepository(
        gson: Gson,
        preferences: SharedPreferences,
    ): IAPICacheRepository {
        return APICacheRepository(
            gson = gson,
            preferences = preferences,
        )
    }

    @Provides
    @Singleton
    fun provideBookRepository(
        client: IBibLibClient,
        cache: IAPICacheRepository,
        database: BibLibDatabase,
        bookFactory: BookFactory,
        seriesFactory: SeriesFactory,
        genresFactory: GenreFactory,
    ): IBookRepository {
        return BookRepository(
            client = client,
            cache = cache,
            database = database,
            bookFactory = bookFactory,
            seriesFactory = seriesFactory,
            genresFactory = genresFactory,
        )
    }

    @Provides
    @Singleton
    fun provideSearchRepository(
        database: BibLibDatabase,
    ): ISearchRepository {
        return SearchRepository(
            database = database,
        )
    }

    @Provides
    @Singleton
    fun provideUserRepository(
        client: IBibLibClient,
        factory: UserFactory,
        preferences: SharedPreferences,
    ): IUserRepository {
        return UserRepository(
            client = client,
            factory = factory,
            preference = preferences,
        )
    }
}