package com.zaojiao.app.core.http.di

import android.content.Context
import coil.ImageLoader
import coil.decode.SvgDecoder
import com.squareup.moshi.Moshi
import com.squareup.moshi.adapters.Rfc3339DateJsonAdapter
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import com.zaojiao.app.core.http.adapter.HexColorAdapter
import com.zaojiao.app.core.http.converter.ResultConverterFactory
import com.zaojiao.app.core.http.interceptor.AuthInterceptor
import com.zaojiao.app.core.http.interceptor.ResultInterceptor
import com.zaojiao.app.core.http.interceptor.VersionInterceptor
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import java.util.Date
import java.util.concurrent.TimeUnit
import javax.inject.Named
import javax.inject.Singleton

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


    @Provides
    @Singleton
    fun provideLoggingInterceptor(): HttpLoggingInterceptor {
        return HttpLoggingInterceptor()
            .apply {
                setLevel(HttpLoggingInterceptor.Level.BODY)
            }
    }

    @Provides
    @Singleton
    fun provideMoshi(): Moshi {
        return Moshi.Builder()
            .add(HexColorAdapter())
            .add(Date::class.java, Rfc3339DateJsonAdapter())
            .add(KotlinJsonAdapterFactory())
            .build()
    }

    @Provides
    @Singleton
    fun provideOkHttpClient(
        @Named("timeout") timeout: Long,
        loggingInterceptor: HttpLoggingInterceptor,
        authInterceptor: AuthInterceptor,
        versionInterceptor: VersionInterceptor,
        resultInterceptor: ResultInterceptor,
    ): OkHttpClient {
        return OkHttpClient.Builder()
            .connectTimeout(timeout, TimeUnit.MILLISECONDS)
            .readTimeout(timeout, TimeUnit.MILLISECONDS)
            .writeTimeout(timeout, TimeUnit.MILLISECONDS)
            .retryOnConnectionFailure(true)
            .followRedirects(false)
            .followSslRedirects(false)
            .addInterceptor(loggingInterceptor)
            .addInterceptor(versionInterceptor)
//            .addInterceptor(tokenInterceptor)
            .addInterceptor(authInterceptor)
            .addInterceptor(resultInterceptor)
            .build()
    }

    @Provides
    @Singleton
    fun provideRetrofitClient(
        @Named("endpoint") endpoint: String,
        okHttpClient: OkHttpClient,
        moshi: Moshi,
    ): Retrofit {
        return Retrofit.Builder()
            .client(okHttpClient)
            .baseUrl(endpoint)
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .addConverterFactory(ResultConverterFactory.create(moshi))
            .build()
    }

    @Provides
    @Singleton
    fun provideImageLoader(
        @Named("timeout") timeout: Long,
        @ApplicationContext application: Context,
    ): ImageLoader {
        val okHttpClient = OkHttpClient.Builder()
            .connectTimeout(timeout, TimeUnit.MILLISECONDS)
            .readTimeout(timeout, TimeUnit.MILLISECONDS)
            .writeTimeout(timeout, TimeUnit.MILLISECONDS)
            .retryOnConnectionFailure(true)
            .followRedirects(false)
            .followSslRedirects(false)
            .build()

        return ImageLoader.Builder(application)
            .callFactory(okHttpClient)
            .components { add(SvgDecoder.Factory()) }
            .respectCacheHeaders(false)
            .build()
    }
}