package com.diegocayo.organizame.data.di

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStoreFile
import androidx.room.Room
import com.diegocayo.organizame.data.local.OrganizaMeDatabase
import com.diegocayo.organizame.data.local.dao.EventDao
import com.diegocayo.organizame.data.local.dao.SubjectDao
import com.diegocayo.organizame.data.local.dao.TaskDao
import com.diegocayo.organizame.data.repository.EventRepositoryImpl
import com.diegocayo.organizame.data.repository.SubjectRepositoryImpl
import com.diegocayo.organizame.data.repository.TaskRepositoryImpl
import com.diegocayo.organizame.domain.repository.EventRepository
import com.diegocayo.organizame.domain.repository.SubjectRepository
import com.diegocayo.organizame.domain.repository.TaskRepository
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 DatabaseModule {

    private const val PREFERENCES_NAME = "organizame_preferences"

    @Provides
    @Singleton
    fun provideDatabase(
        @ApplicationContext context: Context
    ): OrganizaMeDatabase = Room.databaseBuilder(
        context,
        OrganizaMeDatabase::class.java,
        "organizame_database"
    )
        .addMigrations(
            OrganizaMeDatabase.MIGRATION_2_3,
            OrganizaMeDatabase.MIGRATION_3_4
        )
        .build()

    @Provides
    @Singleton
    fun provideDataStore(
        @ApplicationContext context: Context
    ): DataStore<Preferences> = PreferenceDataStoreFactory.create(
        produceFile = { context.preferencesDataStoreFile(PREFERENCES_NAME) }
    )

    @Provides
    @Singleton
    fun provideSubjectDao(database: OrganizaMeDatabase): SubjectDao = database.subjectDao()

    @Provides
    @Singleton
    fun provideTaskDao(database: OrganizaMeDatabase): TaskDao = database.taskDao()

    @Provides
    @Singleton
    fun provideEventDao(database: OrganizaMeDatabase): EventDao = database.eventDao()

    @Provides
    @Singleton
    fun provideSubjectRepository(
        subjectDao: SubjectDao
    ): SubjectRepository = SubjectRepositoryImpl(subjectDao)

    @Provides
    @Singleton
    fun provideTaskRepository(
        taskDao: TaskDao,
        subjectRepository: SubjectRepository
    ): TaskRepository = TaskRepositoryImpl(taskDao, subjectRepository)

    @Provides
    @Singleton
    fun provideEventRepository(
        eventDao: EventDao,
        subjectRepository: SubjectRepository
    ): EventRepository = EventRepositoryImpl(eventDao, subjectRepository)
} 