package com.durian.tssparty.di

import android.content.Context
import androidx.room.Room
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.durian.tssparty.data.local.AppSettingDao
import com.durian.tssparty.data.local.ShareRecordDao
import com.durian.tssparty.data.local.TssDatabase
import com.durian.tssparty.data.local.TssNativeBridge
import com.durian.tssparty.data.remote.GrpcClient
import com.durian.tssparty.data.repository.TssRepository
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

    // Migration from version 1 to 2: add app_settings table
    private val MIGRATION_1_2 = object : Migration(1, 2) {
        override fun migrate(database: SupportSQLiteDatabase) {
            database.execSQL(
                "CREATE TABLE IF NOT EXISTS `app_settings` (" +
                "`key` TEXT NOT NULL PRIMARY KEY, " +
                "`value` TEXT NOT NULL)"
            )
        }
    }

    @Provides
    @Singleton
    fun provideGson(): Gson {
        return GsonBuilder().create()
    }

    @Provides
    @Singleton
    fun provideDatabase(@ApplicationContext context: Context): TssDatabase {
        return Room.databaseBuilder(
            context,
            TssDatabase::class.java,
            "tss_party.db"
        )
            .addMigrations(MIGRATION_1_2)
            .build()
    }

    @Provides
    @Singleton
    fun provideShareRecordDao(database: TssDatabase): ShareRecordDao {
        return database.shareRecordDao()
    }

    @Provides
    @Singleton
    fun provideAppSettingDao(database: TssDatabase): AppSettingDao {
        return database.appSettingDao()
    }

    @Provides
    @Singleton
    fun provideGrpcClient(): GrpcClient {
        return GrpcClient()
    }

    @Provides
    @Singleton
    fun provideTssNativeBridge(gson: Gson): TssNativeBridge {
        return TssNativeBridge(gson)
    }

    @Provides
    @Singleton
    fun provideTssRepository(
        grpcClient: GrpcClient,
        tssNativeBridge: TssNativeBridge,
        shareRecordDao: ShareRecordDao,
        appSettingDao: AppSettingDao
    ): TssRepository {
        return TssRepository(grpcClient, tssNativeBridge, shareRecordDao, appSettingDao)
    }
}
