package com.aiosman.ravenow.data.api

import android.icu.text.SimpleDateFormat
import android.icu.util.TimeZone
import com.aiosman.ravenow.AppStore
import com.aiosman.ravenow.ConstVars
import com.auth0.android.jwt.JWT
import kotlinx.coroutines.runBlocking
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.Date
import java.util.Locale

fun getSafeOkHttpClient(
    authInterceptor: AuthInterceptor? = null
): OkHttpClient {
    return OkHttpClient.Builder()
        .apply {
            authInterceptor?.let {
                addInterceptor(it)
            }
        }
        .build()
}

class AuthInterceptor() : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val requestBuilder = chain.request().newBuilder()
        val token = AppStore.token
        token?.let {
            val jwt = JWT(token)
            val expiresAt = jwt.expiresAt?.time?.minus(3000)
            val currentTime = System.currentTimeMillis()
            val isExpired = expiresAt != null && currentTime > expiresAt
            if (isExpired) {
                runBlocking {
                    val newToken = refreshToken()
                    if (newToken != null) {
                        AppStore.token = newToken
                    }
                }
            }
        }

        requestBuilder.addHeader("Authorization", "Bearer ${AppStore.token}")
        requestBuilder.addHeader("DEVICE-OS", "Android")

        val response = chain.proceed(requestBuilder.build())
        return response
    }

    private suspend fun refreshToken(): String? {
        val client = Retrofit.Builder()
            .baseUrl(ApiClient.RETROFIT_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(getSafeOkHttpClient())
            .build()
            .create(RaveNowAPI::class.java)

        val resp = client.refreshToken(AppStore.token ?: "")
        val newToken = resp.body()?.token
        if (newToken != null) {
            AppStore.token = newToken
        }
        return newToken
    }
}

object ApiClient {
    val BASE_SERVER = ConstVars.BASE_SERVER
    val BASE_API_URL = "${BASE_SERVER}/api/v1"
    val RETROFIT_URL = "${BASE_API_URL}/"
    const val TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"
    private val okHttpClient: OkHttpClient by lazy {
        getSafeOkHttpClient(authInterceptor = AuthInterceptor())
    }
    private val retrofit: Retrofit by lazy {
        Retrofit.Builder()
            .baseUrl(RETROFIT_URL)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }
    val api: RaveNowAPI by lazy {
        retrofit.create(RaveNowAPI::class.java)
    }

    fun formatTime(date: Date): String {
        val dateFormat = SimpleDateFormat(TIME_FORMAT, Locale.getDefault())
        return dateFormat.format(date)
    }

    fun dateFromApiString(apiString: String): Date {
        val timeFormat = TIME_FORMAT
        val simpleDateFormat = SimpleDateFormat(timeFormat, Locale.getDefault())
        simpleDateFormat.timeZone = TimeZone.getTimeZone("UTC")
        val date = simpleDateFormat.parse(apiString)

        simpleDateFormat.timeZone = TimeZone.getDefault()
        val localDateString = simpleDateFormat.format(date)
        return simpleDateFormat.parse(localDateString)
    }
}