package com.syaroful.agrilinkvocpro.data

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import com.auth0.jwt.JWT
import com.auth0.jwt.exceptions.JWTDecodeException
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import java.util.Date

class UserPreferences(private val context: Context) {
    companion object {
        private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "user_prefs")
        private val TOKEN_KEY = stringPreferencesKey("auth_token")
        private val JWT_TOKEN = stringPreferencesKey("jwt_token")
    }

    // Flow untuk token biasa
    val tokenFlow: Flow<String?> = context.dataStore.data.map { preferences ->
        preferences[TOKEN_KEY]
    }

    suspend fun saveToken(token: String) {
        context.dataStore.edit { preferences ->
            preferences[TOKEN_KEY] = token
        }
    }

    suspend fun clearToken() {
        context.dataStore.edit { preferences ->
            preferences.remove(TOKEN_KEY)
        }
    }

    // Flow untuk JWT token
    val jwtTokenFlow: Flow<String?> = context.dataStore.data.map { preferences ->
        preferences[JWT_TOKEN]
    }

    suspend fun saveJwtToken(token: String) {
        context.dataStore.edit { preferences ->
            preferences[JWT_TOKEN] = token
        }
    }

    suspend fun clearJwtToken() {
        context.dataStore.edit { preferences ->
            preferences.remove(JWT_TOKEN)
        }
    }

    // Fungsi untuk cek apakah user sudah login berdasarkan JWT token valid dan belum expired
    fun isUserLoggedIn(): Flow<Boolean> = jwtTokenFlow.map { token ->
        !token.isNullOrEmpty() && !isTokenExpired(token)
    }

    // Fungsi private untuk cek expired JWT token menggunakan library Auth0 java-jwt
    private fun isTokenExpired(token: String): Boolean {
        return try {
            val jwt = JWT.decode(token)
            val expiresAt: Date? = jwt.expiresAt
            expiresAt?.let { Date().after(it) } != false
        } catch (e: JWTDecodeException) {
            true
        }
        return true
    }
}