package de.krisenvorrat.app.di

import android.content.Context
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.withTransaction
import androidx.sqlite.db.SupportSQLiteDatabase
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import de.krisenvorrat.app.data.db.KrisenvorratDatabase
import de.krisenvorrat.app.data.db.Migrations
import de.krisenvorrat.app.data.db.dao.CategoryDao
import de.krisenvorrat.app.data.db.dao.ItemDao
import de.krisenvorrat.app.data.db.dao.LocationDao
import de.krisenvorrat.app.data.db.dao.MessageDao
import de.krisenvorrat.app.data.db.dao.PendingSyncOpDao
import de.krisenvorrat.app.data.db.dao.SettingsDao
import de.krisenvorrat.app.data.export.DatabaseTransaction
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
internal object DatabaseModule {

    @Provides
    @Singleton
    fun provideDatabase(@ApplicationContext context: Context): KrisenvorratDatabase =
        Room.databaseBuilder(context, KrisenvorratDatabase::class.java, "krisenvorrat.db")
            .addCallback(DefaultDataCallback)
            .addMigrations(Migrations.MIGRATION_1_2, Migrations.MIGRATION_2_3, Migrations.MIGRATION_3_4)
            .build()

    private object DefaultDataCallback : RoomDatabase.Callback() {
        override fun onCreate(db: SupportSQLiteDatabase) {
            super.onCreate(db)
            db.execSQL("INSERT INTO locations (name) VALUES ('Keller')")
            listOf(
                "Lebensmittel",
                "Wasser",
                "Medikamente",
                "Ausrüstung",
                "Hygiene",
                "Energie & Licht",
                "Dokumente"
            ).forEach { name ->
                db.execSQL("INSERT INTO categories (name) VALUES ('$name')")
            }
        }
    }

    @Provides
    fun provideItemDao(db: KrisenvorratDatabase): ItemDao = db.itemDao()

    @Provides
    fun provideCategoryDao(db: KrisenvorratDatabase): CategoryDao = db.categoryDao()

    @Provides
    fun provideLocationDao(db: KrisenvorratDatabase): LocationDao = db.locationDao()

    @Provides
    fun providePendingSyncOpDao(db: KrisenvorratDatabase): PendingSyncOpDao = db.pendingSyncOpDao()

    @Provides
    fun provideSettingsDao(db: KrisenvorratDatabase): SettingsDao = db.settingsDao()

    @Provides
    fun provideMessageDao(db: KrisenvorratDatabase): MessageDao = db.messageDao()

    @Provides
    @Singleton
    fun provideDatabaseTransaction(db: KrisenvorratDatabase): DatabaseTransaction =
        DatabaseTransaction { block -> db.withTransaction(block) }
}
