package com.tt.honeyDue.widget

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
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

/**
 * DataStore-backed key/value store for widget task data.
 *
 * iOS uses an App Group shared container with UserDefaults + JSON files to
 * bridge main app and widget extension processes. On Android, Glance widgets
 * run in the same process as the hosting app, so a simple DataStore instance
 * is sufficient.
 *
 * Keys:
 *  - widget_tasks_json          — JSON-serialized List<WidgetTaskDto>
 *  - pending_completion_ids     — comma-separated Long ids queued for sync
 *  - last_refresh_time          — Long epoch millis of the most recent save
 *  - user_tier                  — "free" | "premium"
 */
internal val Context.widgetIosParityDataStore: DataStore<Preferences> by preferencesDataStore(
    name = "widget_data_ios_parity"
)

internal object WidgetDataStoreKeys {
    val WIDGET_TASKS_JSON = stringPreferencesKey("widget_tasks_json")
    val PENDING_COMPLETION_IDS = stringPreferencesKey("pending_completion_ids")
    val LAST_REFRESH_TIME = longPreferencesKey("last_refresh_time")
    val USER_TIER = stringPreferencesKey("user_tier")
}

/**
 * Thin suspend-fun wrapper around [widgetIosParityDataStore]. All reads resolve
 * the current snapshot; all writes are transactional via [edit].
 */
class WidgetDataStore(private val context: Context) {

    private val store get() = context.widgetIosParityDataStore

    suspend fun readTasksJson(): String =
        store.data.first()[WidgetDataStoreKeys.WIDGET_TASKS_JSON] ?: "[]"

    suspend fun writeTasksJson(json: String, refreshTimeMs: Long) {
        store.edit { prefs ->
            prefs[WidgetDataStoreKeys.WIDGET_TASKS_JSON] = json
            prefs[WidgetDataStoreKeys.LAST_REFRESH_TIME] = refreshTimeMs
        }
    }

    suspend fun readPendingCompletionIds(): Set<Long> {
        val raw = store.data.first()[WidgetDataStoreKeys.PENDING_COMPLETION_IDS] ?: return emptySet()
        if (raw.isBlank()) return emptySet()
        return raw.split(',')
            .mapNotNull { it.trim().toLongOrNull() }
            .toSet()
    }

    suspend fun writePendingCompletionIds(ids: Set<Long>) {
        val encoded = ids.joinToString(",")
        store.edit { prefs ->
            if (encoded.isEmpty()) {
                prefs.remove(WidgetDataStoreKeys.PENDING_COMPLETION_IDS)
            } else {
                prefs[WidgetDataStoreKeys.PENDING_COMPLETION_IDS] = encoded
            }
        }
    }

    suspend fun readLastRefreshTime(): Long =
        store.data.first()[WidgetDataStoreKeys.LAST_REFRESH_TIME] ?: 0L

    suspend fun readTier(): String =
        store.data.first()[WidgetDataStoreKeys.USER_TIER] ?: "free"

    suspend fun writeTier(tier: String) {
        store.edit { prefs ->
            prefs[WidgetDataStoreKeys.USER_TIER] = tier
        }
    }

    /** Remove every key owned by this store. Used on logout / test teardown. */
    suspend fun clearAll() {
        store.edit { prefs ->
            prefs.remove(WidgetDataStoreKeys.WIDGET_TASKS_JSON)
            prefs.remove(WidgetDataStoreKeys.PENDING_COMPLETION_IDS)
            prefs.remove(WidgetDataStoreKeys.LAST_REFRESH_TIME)
            prefs.remove(WidgetDataStoreKeys.USER_TIER)
        }
    }
}
