package solutions.tretter.mindmachine.data

import android.content.Context
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import solutions.tretter.mindmachine.domain.AppSettings
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

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

class SettingsRepository(private val context: Context) {
    private object Keys {
        val safetyAcknowledged = booleanPreferencesKey("safety_ack")
        val safetyVersion = intPreferencesKey("safety_version")
        val countdownPref = stringPreferencesKey("countdown_pref")
        val countdownSeconds = intPreferencesKey("countdown_seconds")
        val forceAudioWithoutHeadphones = booleanPreferencesKey("force_audio_without_headphones")
        val showImmersiveProgressBar = booleanPreferencesKey("show_immersive_progress_bar")
        val preferLowestRefreshRate = booleanPreferencesKey("prefer_lowest_refresh_rate")
        val monochromeFlashMode = booleanPreferencesKey("monochrome_flash_mode")
        val immersiveBrightnessPercent = intPreferencesKey("immersive_brightness_percent")
        val lastPresetId = stringPreferencesKey("last_preset")
        val noAds = booleanPreferencesKey("no_ads")
    }

    val settings: Flow<AppSettings> = context.dataStore.data.map { p ->
        AppSettings(
            safetyAcknowledged = p[Keys.safetyAcknowledged] ?: false,
            safetyAcknowledgedVersion = p[Keys.safetyVersion] ?: 0,
            countdownSeconds = p[Keys.countdownSeconds]
                ?: legacyCountdownStringToSeconds(p[Keys.countdownPref])
                ?: 5,
            forceAudioWithoutHeadphones = p[Keys.forceAudioWithoutHeadphones] ?: false,
            showImmersiveProgressBar = p[Keys.showImmersiveProgressBar] ?: true,
            preferLowestRefreshRate = p[Keys.preferLowestRefreshRate] ?: true,
            monochromeFlashMode = p[Keys.monochromeFlashMode] ?: false,
            immersiveBrightnessPercent = (p[Keys.immersiveBrightnessPercent] ?: 50).coerceIn(5, 100),
            lastPresetId = p[Keys.lastPresetId],
            noAds = p[Keys.noAds] ?: false,
        )
    }

    /**
     * Called on app startup.
     * Ensures a first-run default of 50% brightness for immersive sessions.
     *
     * Only applies when the user has never set a value.
     */
    suspend fun ensureFirstRunDefaults() {
        context.dataStore.edit { prefs ->
            if (prefs[Keys.immersiveBrightnessPercent] == null) {
                prefs[Keys.immersiveBrightnessPercent] = 50
            }
            if (prefs[Keys.preferLowestRefreshRate] == null) {
                prefs[Keys.preferLowestRefreshRate] = true
            }
        }
    }

    suspend fun acknowledgeSafety(version: Int) {
        context.dataStore.edit {
            it[Keys.safetyAcknowledged] = true
            it[Keys.safetyVersion] = version
        }
    }

    suspend fun updateCountdownSeconds(value: Int) = context.dataStore.edit {
        it[Keys.countdownSeconds] = value.coerceIn(0, 10)
    }

    suspend fun updateForceAudioWithoutHeadphones(value: Boolean) = context.dataStore.edit {
        it[Keys.forceAudioWithoutHeadphones] = value
    }

    suspend fun updateShowImmersiveProgressBar(value: Boolean) = context.dataStore.edit {
        it[Keys.showImmersiveProgressBar] = value
    }

    suspend fun updatePreferLowestRefreshRate(value: Boolean) = context.dataStore.edit {
        it[Keys.preferLowestRefreshRate] = value
    }

    suspend fun updateMonochromeFlashMode(value: Boolean) = context.dataStore.edit {
        it[Keys.monochromeFlashMode] = value
    }

    suspend fun updateImmersiveBrightnessPercent(value: Int) = context.dataStore.edit {
        it[Keys.immersiveBrightnessPercent] = value.coerceIn(5, 100)
    }

    suspend fun updateLastPreset(id: String) = context.dataStore.edit { it[Keys.lastPresetId] = id }

    suspend fun updateNoAds(value: Boolean) = context.dataStore.edit { it[Keys.noAds] = value }

    private fun legacyCountdownStringToSeconds(raw: String?): Int? = when (raw) {
        "OFF" -> 0
        "FIVE" -> 5
        "TEN" -> 10
        else -> null
    }
}
