package com.keylightpiano.pianotimeline.data

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.first

/**
 * Persists user UI preferences (shuffle, repeat mode, …) across app launches.
 *
 * This uses its own DataStore file ("user_prefs"), separate from the sync
 * revision store, so playback preferences and sync bookkeeping stay decoupled.
 *
 * Values are stored as primitives (Boolean, String) and read back on ViewModel
 * init. Reads are one-shot (`first()`) because we only need the value at startup;
 * after that the ViewModel holds the source of truth and writes through on change.
 */
private val Context.userPrefsStore: DataStore<Preferences> by preferencesDataStore(name = "user_prefs")

class SettingsStore(private val context: Context) {

    private companion object {
        val KEY_SHUFFLE = booleanPreferencesKey("shuffle_enabled")
        val KEY_REPEAT = stringPreferencesKey("repeat_mode")
        val KEY_LAST_TRACK_ID = stringPreferencesKey("last_track_id")
        val KEY_LAST_POSITION_MS = longPreferencesKey("last_position_ms")
        val KEY_NOTIFICATIONS = booleanPreferencesKey("notifications_enabled")
    }

    /** Read the stored shuffle flag (default false). */
    suspend fun getShuffle(): Boolean {
        val prefs = context.userPrefsStore.data.first()
        return prefs[KEY_SHUFFLE] ?: false
    }

    suspend fun setShuffle(enabled: Boolean) {
        context.userPrefsStore.edit { it[KEY_SHUFFLE] = enabled }
    }

    /**
     * Read the stored repeat mode by name (default "OFF").
     * Stored as the enum's name string so it's human-readable and resilient to
     * reordering the enum constants.
     */
    suspend fun getRepeatModeName(): String {
        val prefs = context.userPrefsStore.data.first()
        return prefs[KEY_REPEAT] ?: "OFF"
    }

    suspend fun setRepeatModeName(name: String) {
        context.userPrefsStore.edit { it[KEY_REPEAT] = name }
    }

    /**
     * Last-played track id + position, so the player can restore (paused) on
     * next launch. A null/absent id means "nothing to restore" (fresh install or
     * after the track was stopped).
     */
    suspend fun getLastTrackId(): String? {
        val prefs = context.userPrefsStore.data.first()
        return prefs[KEY_LAST_TRACK_ID]
    }

    suspend fun getLastPositionMs(): Long {
        val prefs = context.userPrefsStore.data.first()
        return prefs[KEY_LAST_POSITION_MS] ?: 0L
    }

    /** Persist the currently-playing track and offset. */
    suspend fun setLastPlayed(trackId: String, positionMs: Long) {
        context.userPrefsStore.edit {
            it[KEY_LAST_TRACK_ID] = trackId
            it[KEY_LAST_POSITION_MS] = positionMs
        }
    }

    /** Clear the remembered track (called when playback is stopped). */
    suspend fun clearLastPlayed() {
        context.userPrefsStore.edit {
            it.remove(KEY_LAST_TRACK_ID)
            it.remove(KEY_LAST_POSITION_MS)
        }
    }

    /**
     * "Notify me about new recordings" toggle. Currently just a stored flag —
     * the actual notification delivery (WorkManager/FCM) isn't wired up yet, so
     * reading/writing this is a no-op beyond persistence. Default off.
     */
    suspend fun getNotificationsEnabled(): Boolean {
        val prefs = context.userPrefsStore.data.first()
        return prefs[KEY_NOTIFICATIONS] ?: false
    }

    suspend fun setNotificationsEnabled(enabled: Boolean) {
        context.userPrefsStore.edit { it[KEY_NOTIFICATIONS] = enabled }
    }
}
