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.intPreferencesKey
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

// DataStore instance
private val Context.widgetDataStore: DataStore<Preferences> by preferencesDataStore(name = "widget_data")

/**
 * Data class representing a task for the widget
 */
@Serializable
data class WidgetTask(
    val id: Int,
    val title: String,
    val residenceName: String,
    val dueDate: String?,
    val isOverdue: Boolean,
    val categoryName: String,
    val priorityLevel: Int
)

/**
 * Data class representing widget summary data
 */
@Serializable
data class WidgetSummary(
    val overdueCount: Int = 0,
    val dueSoonCount: Int = 0,
    val inProgressCount: Int = 0,
    val totalTasksCount: Int = 0,
    val tasks: List<WidgetTask> = emptyList(),
    val lastUpdated: Long = System.currentTimeMillis()
)

/**
 * Repository for managing widget data persistence
 */
class WidgetDataRepository(private val context: Context) {

    private val json = Json { ignoreUnknownKeys = true }

    companion object {
        private val OVERDUE_COUNT = intPreferencesKey("overdue_count")
        private val DUE_SOON_COUNT = intPreferencesKey("due_soon_count")
        private val IN_PROGRESS_COUNT = intPreferencesKey("in_progress_count")
        private val TOTAL_TASKS_COUNT = intPreferencesKey("total_tasks_count")
        private val TASKS_JSON = stringPreferencesKey("tasks_json")
        private val LAST_UPDATED = longPreferencesKey("last_updated")
        private val IS_PRO_USER = stringPreferencesKey("is_pro_user")
        private val USER_NAME = stringPreferencesKey("user_name")

        @Volatile
        private var INSTANCE: WidgetDataRepository? = null

        fun getInstance(context: Context): WidgetDataRepository {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: WidgetDataRepository(context.applicationContext).also { INSTANCE = it }
            }
        }
    }

    /**
     * Get the widget summary as a Flow
     */
    val widgetSummary: Flow<WidgetSummary> = context.widgetDataStore.data.map { preferences ->
        val tasksJson = preferences[TASKS_JSON] ?: "[]"
        val tasks = try {
            json.decodeFromString<List<WidgetTask>>(tasksJson)
        } catch (e: Exception) {
            emptyList()
        }

        WidgetSummary(
            overdueCount = preferences[OVERDUE_COUNT] ?: 0,
            dueSoonCount = preferences[DUE_SOON_COUNT] ?: 0,
            inProgressCount = preferences[IN_PROGRESS_COUNT] ?: 0,
            totalTasksCount = preferences[TOTAL_TASKS_COUNT] ?: 0,
            tasks = tasks,
            lastUpdated = preferences[LAST_UPDATED] ?: 0L
        )
    }

    /**
     * Check if user is a Pro subscriber
     */
    val isProUser: Flow<Boolean> = context.widgetDataStore.data.map { preferences ->
        preferences[IS_PRO_USER] == "true"
    }

    /**
     * Get the user's display name
     */
    val userName: Flow<String> = context.widgetDataStore.data.map { preferences ->
        preferences[USER_NAME] ?: ""
    }

    /**
     * Update the widget data
     */
    suspend fun updateWidgetData(summary: WidgetSummary) {
        context.widgetDataStore.edit { preferences ->
            preferences[OVERDUE_COUNT] = summary.overdueCount
            preferences[DUE_SOON_COUNT] = summary.dueSoonCount
            preferences[IN_PROGRESS_COUNT] = summary.inProgressCount
            preferences[TOTAL_TASKS_COUNT] = summary.totalTasksCount
            preferences[TASKS_JSON] = json.encodeToString(summary.tasks)
            preferences[LAST_UPDATED] = System.currentTimeMillis()
        }
    }

    /**
     * Update user subscription status
     */
    suspend fun updateProStatus(isPro: Boolean) {
        context.widgetDataStore.edit { preferences ->
            preferences[IS_PRO_USER] = if (isPro) "true" else "false"
        }
    }

    /**
     * Update user name
     */
    suspend fun updateUserName(name: String) {
        context.widgetDataStore.edit { preferences ->
            preferences[USER_NAME] = name
        }
    }

    /**
     * Clear all widget data (called on logout)
     */
    suspend fun clearData() {
        context.widgetDataStore.edit { preferences ->
            preferences.clear()
        }
    }
}
