package solutions.tretter.githugandroid

import android.content.Context
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.emptyPreferences
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.map
import java.io.IOException

private val Context.gameProgressDataStore by preferencesDataStore(name = "game_progress_preferences")

class GameProgressStore(private val context: Context) {
    init {
        AppLog.d("ProgressStore", "GameProgressStore initialized")
    }

    private val dataStore = context.applicationContext.gameProgressDataStore

    private val completedLevelsKey = stringPreferencesKey("completed_levels")
    private val activeLevelIdKey = stringPreferencesKey("active_level_id")
    private val showHelpOnStartKey = booleanPreferencesKey("show_help_on_start")

    data class GameProgress(
        val completedLevels: Set<String> = emptySet(),
        val activeLevelId: String? = null,
        val showHelpOnStart: Boolean = true,
    )

    val progressFlow: Flow<GameProgress> = dataStore.data
        .catch { error ->
            if (error is IOException) {
                AppLog.e("ProgressStore", "Failed reading progress preferences, using defaults", error)
                emit(emptyPreferences())
            } else {
                throw error
            }
        }
        .map { preferences ->
            val completedLevels = preferences[completedLevelsKey]
                ?.split(',')
                ?.map { it.trim() }
                ?.filter { it.isNotEmpty() }
                ?.toSet()
                ?: emptySet()
            val activeLevelId = preferences[activeLevelIdKey]?.takeIf { it.isNotBlank() }
            val showHelpOnStart = preferences[showHelpOnStartKey] ?: true
            AppLog.d(
                "ProgressStore",
                "Loaded progress completed=${completedLevels.sorted()} activeLevelId=$activeLevelId showHelpOnStart=$showHelpOnStart",
            )
            GameProgress(
                completedLevels = completedLevels,
                activeLevelId = activeLevelId,
                showHelpOnStart = showHelpOnStart,
            )
        }

    suspend fun saveProgress(completedLevels: Set<String>, activeLevelId: String?) {
        dataStore.edit { preferences ->
            preferences[completedLevelsKey] = completedLevels.joinToString(",")
            if (activeLevelId.isNullOrBlank()) {
                preferences.remove(activeLevelIdKey)
            } else {
                preferences[activeLevelIdKey] = activeLevelId
            }
        }
        AppLog.d(
            "ProgressStore",
            "Saved progress completed=${completedLevels.sorted()} activeLevelId=$activeLevelId",
        )
    }

    suspend fun saveShowHelpOnStart(showHelpOnStart: Boolean) {
        dataStore.edit { preferences ->
            preferences[showHelpOnStartKey] = showHelpOnStart
        }
        AppLog.d("ProgressStore", "Saved showHelpOnStart=$showHelpOnStart")
    }
}
