package lu.rewardflow.terminal.di

import android.content.Context
import androidx.room.Room
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import lu.rewardflow.terminal.BuildConfig
import lu.rewardflow.terminal.data.api.LoyaltyApi
import lu.rewardflow.terminal.data.db.AppDatabase
import lu.rewardflow.terminal.data.db.dao.PendingTransactionDao
import lu.rewardflow.terminal.data.network.AuthInterceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import java.util.concurrent.TimeUnit
import javax.inject.Singleton

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

    @Provides
    @Singleton
    fun provideMoshi(): Moshi = Moshi.Builder()
        .addLast(KotlinJsonAdapterFactory())
        .build()

    @Provides
    @Singleton
    fun provideOkHttpClient(authInterceptor: AuthInterceptor): OkHttpClient {
        val builder = OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            // AuthInterceptor must run BEFORE logging so the rewritten URL
            // and the Authorization header show up in the log line.
            .addInterceptor(authInterceptor)

        if (BuildConfig.DEBUG) {
            val logging = HttpLoggingInterceptor()
            logging.level = HttpLoggingInterceptor.Level.BODY
            builder.addInterceptor(logging)
        }

        return builder.build()
    }

    @Provides
    @Singleton
    fun provideRetrofit(okHttpClient: OkHttpClient, moshi: Moshi): Retrofit {
        // Placeholder baseUrl: AuthInterceptor rewrites the host on every
        // request to the device's paired api_url. Retrofit just needs SOME
        // valid URL at construction. Keeping DEFAULT_API_URL here so dev
        // builds work out-of-the-box pointing at 10.0.2.2:8000 before the
        // device is paired.
        return Retrofit.Builder()
            .baseUrl(BuildConfig.DEFAULT_API_URL + "/")
            .client(okHttpClient)
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .build()
    }

    @Provides
    @Singleton
    fun provideLoyaltyApi(retrofit: Retrofit): LoyaltyApi {
        return retrofit.create(LoyaltyApi::class.java)
    }

    @Provides
    @Singleton
    fun provideDatabase(@ApplicationContext context: Context): AppDatabase {
        return Room.databaseBuilder(
            context,
            AppDatabase::class.java,
            "rewardflow_terminal.db",
        ).build()
    }

    @Provides
    fun providePendingTransactionDao(db: AppDatabase): PendingTransactionDao {
        return db.pendingTransactionDao()
    }
}
