/*
 * F7cloud Talk - Android Client
 *
 * SPDX-FileCopyrightText: 2022-2024 Marcel Hibbe <dev@mhibbe.de>
 * SPDX-FileCopyrightText: 2022 Andy Scherzinger <info@andy-scherzinger.de>
 * SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro@alvarobrey.com>
 * SPDX-FileCopyrightText: 2022 Nextcloud GmbH
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package ru.f7cloud.talk.dagger.modules

import android.content.Context
import ru.f7cloud.talk.account.data.LoginRepository
import ru.f7cloud.talk.account.data.io.LocalLoginDataSource
import ru.f7cloud.talk.account.data.network.NetworkLoginDataSource
import ru.f7cloud.talk.api.NcApi
import ru.f7cloud.talk.api.NcApiCoroutines
import ru.f7cloud.talk.chat.data.ChatMessageRepository
import ru.f7cloud.talk.chat.data.network.ChatNetworkDataSource
import ru.f7cloud.talk.chat.data.network.OfflineFirstChatRepository
import ru.f7cloud.talk.chat.data.network.RetrofitChatNetwork
import ru.f7cloud.talk.chooseaccount.StatusRepository
import ru.f7cloud.talk.chooseaccount.StatusRepositoryImplementation
import ru.f7cloud.talk.contacts.ContactsRepository
import ru.f7cloud.talk.contacts.ContactsRepositoryImpl
import ru.f7cloud.talk.conversationcreation.ConversationCreationRepository
import ru.f7cloud.talk.conversationcreation.ConversationCreationRepositoryImpl
import ru.f7cloud.talk.conversationinfoedit.data.ConversationInfoEditRepository
import ru.f7cloud.talk.conversationinfoedit.data.ConversationInfoEditRepositoryImpl
import ru.f7cloud.talk.conversationlist.data.OfflineConversationsRepository
import ru.f7cloud.talk.conversationlist.data.network.ConversationsNetworkDataSource
import ru.f7cloud.talk.conversationlist.data.network.OfflineFirstConversationsRepository
import ru.f7cloud.talk.conversationlist.data.network.RetrofitConversationsNetwork
import ru.f7cloud.talk.data.database.dao.ChatBlocksDao
import ru.f7cloud.talk.data.database.dao.ChatMessagesDao
import ru.f7cloud.talk.data.database.dao.ConversationsDao
import ru.f7cloud.talk.data.network.NetworkMonitor
import ru.f7cloud.talk.data.source.local.TalkDatabase
import ru.f7cloud.talk.data.storage.ArbitraryStoragesRepository
import ru.f7cloud.talk.data.storage.ArbitraryStoragesRepositoryImpl
import ru.f7cloud.talk.data.user.UsersRepository
import ru.f7cloud.talk.data.user.UsersRepositoryImpl
import ru.f7cloud.talk.invitation.data.InvitationsRepository
import ru.f7cloud.talk.invitation.data.InvitationsRepositoryImpl
import ru.f7cloud.talk.openconversations.data.OpenConversationsRepository
import ru.f7cloud.talk.openconversations.data.OpenConversationsRepositoryImpl
import ru.f7cloud.talk.polls.repositories.PollRepository
import ru.f7cloud.talk.polls.repositories.PollRepositoryImpl
import ru.f7cloud.talk.raisehand.RequestAssistanceRepository
import ru.f7cloud.talk.raisehand.RequestAssistanceRepositoryImpl
import ru.f7cloud.talk.remotefilebrowser.repositories.RemoteFileBrowserItemsRepository
import ru.f7cloud.talk.remotefilebrowser.repositories.RemoteFileBrowserItemsRepositoryImpl
import ru.f7cloud.talk.repositories.callrecording.CallRecordingRepository
import ru.f7cloud.talk.repositories.callrecording.CallRecordingRepositoryImpl
import ru.f7cloud.talk.repositories.conversations.ConversationsRepository
import ru.f7cloud.talk.repositories.conversations.ConversationsRepositoryImpl
import ru.f7cloud.talk.repositories.reactions.ReactionsRepository
import ru.f7cloud.talk.repositories.reactions.ReactionsRepositoryImpl
import ru.f7cloud.talk.repositories.unifiedsearch.UnifiedSearchRepository
import ru.f7cloud.talk.repositories.unifiedsearch.UnifiedSearchRepositoryImpl
import ru.f7cloud.talk.shareditems.repositories.SharedItemsRepository
import ru.f7cloud.talk.shareditems.repositories.SharedItemsRepositoryImpl
import ru.f7cloud.talk.threadsoverview.data.ThreadsRepository
import ru.f7cloud.talk.threadsoverview.data.ThreadsRepositoryImpl
import ru.f7cloud.talk.translate.repositories.TranslateRepository
import ru.f7cloud.talk.translate.repositories.TranslateRepositoryImpl
import ru.f7cloud.talk.users.UserManager
import ru.f7cloud.talk.utils.DateUtils
import ru.f7cloud.talk.utils.preferences.AppPreferences
import dagger.Module
import dagger.Provides
import okhttp3.OkHttpClient

@Suppress("TooManyFunctions")
@Module
class RepositoryModule {

    @Provides
    fun provideConversationsRepository(ncApi: NcApi, ncApiCoroutines: NcApiCoroutines): ConversationsRepository =
        ConversationsRepositoryImpl(ncApi, ncApiCoroutines)

    @Provides
    fun provideSharedItemsRepository(ncApi: NcApi, dateUtils: DateUtils): SharedItemsRepository =
        SharedItemsRepositoryImpl(ncApi, dateUtils)

    @Provides
    fun provideUnifiedSearchRepository(ncApi: NcApi): UnifiedSearchRepository = UnifiedSearchRepositoryImpl(ncApi)

    @Provides
    fun provideDialogPollRepository(ncApi: NcApi): PollRepository = PollRepositoryImpl(ncApi)

    @Provides
    fun provideRemoteFileBrowserItemsRepository(okHttpClient: OkHttpClient): RemoteFileBrowserItemsRepository =
        RemoteFileBrowserItemsRepositoryImpl(okHttpClient)

    @Provides
    fun provideUsersRepository(database: TalkDatabase): UsersRepository = UsersRepositoryImpl(database.usersDao())

    @Provides
    fun provideArbitraryStoragesRepository(database: TalkDatabase): ArbitraryStoragesRepository =
        ArbitraryStoragesRepositoryImpl(database.arbitraryStoragesDao())

    @Provides
    fun provideReactionsRepository(ncApi: NcApi, dao: ChatMessagesDao): ReactionsRepository =
        ReactionsRepositoryImpl(ncApi, dao)

    @Provides
    fun provideCallRecordingRepository(ncApi: NcApi): CallRecordingRepository = CallRecordingRepositoryImpl(ncApi)

    @Provides
    fun provideRequestAssistanceRepository(ncApi: NcApi): RequestAssistanceRepository =
        RequestAssistanceRepositoryImpl(ncApi)

    @Provides
    fun provideOpenConversationsRepository(ncApiCoroutines: NcApiCoroutines): OpenConversationsRepository =
        OpenConversationsRepositoryImpl(ncApiCoroutines)

    @Provides
    fun translateRepository(ncApi: NcApi): TranslateRepository = TranslateRepositoryImpl(ncApi)

    @Provides
    fun provideChatNetworkDataSource(ncApi: NcApi, ncApiCoroutines: NcApiCoroutines): ChatNetworkDataSource =
        RetrofitChatNetwork(ncApi, ncApiCoroutines)

    @Provides
    fun provideConversationsNetworkDataSource(ncApi: NcApi): ConversationsNetworkDataSource =
        RetrofitConversationsNetwork(ncApi)

    @Provides
    fun provideConversationInfoEditRepository(
        ncApi: NcApi,
        ncApiCoroutines: NcApiCoroutines
    ): ConversationInfoEditRepository = ConversationInfoEditRepositoryImpl(ncApi, ncApiCoroutines)

    @Provides
    fun provideInvitationsRepository(ncApi: NcApi, ncApiCoroutines: NcApiCoroutines): InvitationsRepository =
        InvitationsRepositoryImpl(ncApi, ncApiCoroutines)

    @Provides
    fun provideOfflineFirstChatRepository(
        chatMessagesDao: ChatMessagesDao,
        chatBlocksDao: ChatBlocksDao,
        dataSource: ChatNetworkDataSource,
        networkMonitor: NetworkMonitor
    ): ChatMessageRepository =
        OfflineFirstChatRepository(
            chatMessagesDao,
            chatBlocksDao,
            dataSource,
            networkMonitor
        )

    @Provides
    fun provideOfflineFirstConversationsRepository(
        dao: ConversationsDao,
        dataSource: ConversationsNetworkDataSource,
        chatNetworkDataSource: ChatNetworkDataSource,
        networkMonitor: NetworkMonitor
    ): OfflineConversationsRepository =
        OfflineFirstConversationsRepository(
            dao,
            dataSource,
            chatNetworkDataSource,
            networkMonitor
        )

    @Provides
    fun provideContactsRepository(ncApiCoroutines: NcApiCoroutines): ContactsRepository =
        ContactsRepositoryImpl(ncApiCoroutines)

    @Provides
    fun provideConversationCreationRepository(ncApiCoroutines: NcApiCoroutines): ConversationCreationRepository =
        ConversationCreationRepositoryImpl(ncApiCoroutines)

    @Provides
    fun provideThreadsRepository(ncApiCoroutines: NcApiCoroutines): ThreadsRepository =
        ThreadsRepositoryImpl(ncApiCoroutines)

    @Provides
    fun provideNetworkDataSource(okHttpClient: OkHttpClient): NetworkLoginDataSource =
        NetworkLoginDataSource(okHttpClient)

    @Provides
    fun providesLocalDataSource(
        userManager: UserManager,
        appPreferences: AppPreferences,
        context: Context
    ): LocalLoginDataSource = LocalLoginDataSource(userManager, appPreferences, context)

    @Provides
    fun provideLoginRepository(
        networkLoginDataSource: NetworkLoginDataSource,
        localLoginDataSource: LocalLoginDataSource
    ): LoginRepository = LoginRepository(networkLoginDataSource, localLoginDataSource)

    @Provides
    fun provideStatusRepository(ncApiCoroutines: NcApiCoroutines): StatusRepository =
        StatusRepositoryImplementation(ncApiCoroutines)
}
