package com.seven.ikar.kotlin.core.session

import android.content.Context
import android.content.SharedPreferences
import com.seven.ikar.kotlin.core.model.AuthSessionDto
import com.seven.ikar.kotlin.core.security.AndroidKeystoreCipher
import kotlinx.serialization.json.Json

class SessionStore(context: Context, private val json: Json) {
    private val preferences: SharedPreferences =
        context.getSharedPreferences("ikar_kotlin_session", Context.MODE_PRIVATE)
    private val cipher = AndroidKeystoreCipher("ikar.session.v1")

    fun read(): AuthSessionDto? {
        val encrypted = preferences.getString(KEY_ENCRYPTED_SESSION, null)
        if (encrypted != null) {
            val raw = cipher.decrypt(encrypted) ?: run {
                clear()
                return null
            }
            return decode(raw)
        }

        val legacy = preferences.getString(KEY_LEGACY_SESSION, null) ?: return null
        val session = decode(legacy) ?: run {
            clear()
            return null
        }
        save(session)
        return session
    }

    fun save(session: AuthSessionDto) {
        val encrypted = cipher.encrypt(json.encodeToString(AuthSessionDto.serializer(), session))
        preferences.edit()
            .putString(KEY_ENCRYPTED_SESSION, encrypted)
            .remove(KEY_LEGACY_SESSION)
            .commit()
    }

    fun clear() {
        preferences.edit()
            .remove(KEY_ENCRYPTED_SESSION)
            .remove(KEY_LEGACY_SESSION)
            .commit()
    }

    private fun decode(raw: String): AuthSessionDto? =
        runCatching { json.decodeFromString<AuthSessionDto>(raw) }.getOrNull()

    companion object {
        private const val KEY_ENCRYPTED_SESSION = "encrypted_session"
        private const val KEY_LEGACY_SESSION = "session"
    }
}
