package com.diegocayo.organizame.data.local.datasource

import android.content.Context
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import com.diegocayo.organizame.data.local.dto.UserDTO
import com.diegocayo.organizame.utils.moshi.MoshiParser
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import javax.inject.Inject
import javax.inject.Singleton

interface PreferencesDataSource {
    suspend fun saveUser(user: UserDTO)
    suspend fun getUser(): UserDTO?
    suspend fun setLoginStatus(isLoggedIn: Boolean)
    suspend fun isLoggedIn(): Boolean
    suspend fun clearUser()
    suspend fun clear()
}

private val Context.dataStore by preferencesDataStore("app_prefs")

@Singleton
class PreferencesDataSourceImpl @Inject constructor(
    private val context: Context,
    private val moshiParser: MoshiParser
) : PreferencesDataSource {

    companion object {
        private val KEY_USER_DATA = stringPreferencesKey("key_user_data")
        private val KEY_IS_LOGGED_IN = booleanPreferencesKey("key_is_logged_in")
    }

    override suspend fun saveUser(user: UserDTO) {
        val json = moshiParser.toJson(user, UserDTO::class.java)
        context.dataStore.edit { preferences ->
            preferences[KEY_USER_DATA] = json
        }
    }

    override suspend fun getUser(): UserDTO? {
        val json = context.dataStore.data
            .map { preferences -> preferences[KEY_USER_DATA] }
            .first()
        return json?.let {
            moshiParser.fromJson(it, UserDTO::class.java)
        }
    }

    override suspend fun setLoginStatus(isLoggedIn: Boolean) {
        context.dataStore.edit { preferences ->
            preferences[KEY_IS_LOGGED_IN] = isLoggedIn
        }
    }

    override suspend fun isLoggedIn(): Boolean {
        return context.dataStore.data
            .map { preferences -> preferences[KEY_IS_LOGGED_IN] ?: false }
            .first()
    }

    override suspend fun clearUser() {
        context.dataStore.edit { preferences ->
            preferences.remove(KEY_USER_DATA)
        }
    }

    override suspend fun clear() {
        context.dataStore.edit { preferences ->
            preferences.clear()
        }
    }
}