package com.swoosh.microblog.data

import android.content.Context
import androidx.test.core.app.ApplicationProvider
import com.swoosh.microblog.data.model.PostFilter
import com.swoosh.microblog.data.model.SortOrder
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config

@RunWith(RobolectricTestRunner::class)
@Config(application = android.app.Application::class)
class FeedPreferencesTest {

    private lateinit var context: Context
    private lateinit var feedPreferences: FeedPreferences

    @Before
    fun setup() {
        context = ApplicationProvider.getApplicationContext()
        // Clear any previously stored preferences
        context.getSharedPreferences(FeedPreferences.PREFS_NAME, Context.MODE_PRIVATE)
            .edit().clear().commit()
        feedPreferences = FeedPreferences(context)
    }

    // --- Default values ---

    @Test
    fun `default filter is ALL`() {
        assertEquals(PostFilter.ALL, feedPreferences.filter)
    }

    @Test
    fun `default sortOrder is NEWEST`() {
        assertEquals(SortOrder.NEWEST, feedPreferences.sortOrder)
    }

    // --- Filter persistence ---

    @Test
    fun `setting filter to PUBLISHED persists`() {
        feedPreferences.filter = PostFilter.PUBLISHED
        assertEquals(PostFilter.PUBLISHED, feedPreferences.filter)
    }

    @Test
    fun `setting filter to DRAFT persists`() {
        feedPreferences.filter = PostFilter.DRAFT
        assertEquals(PostFilter.DRAFT, feedPreferences.filter)
    }

    @Test
    fun `setting filter to SCHEDULED persists`() {
        feedPreferences.filter = PostFilter.SCHEDULED
        assertEquals(PostFilter.SCHEDULED, feedPreferences.filter)
    }

    @Test
    fun `setting filter to ALL persists`() {
        feedPreferences.filter = PostFilter.DRAFT
        feedPreferences.filter = PostFilter.ALL
        assertEquals(PostFilter.ALL, feedPreferences.filter)
    }

    @Test
    fun `filter persists across instances`() {
        feedPreferences.filter = PostFilter.SCHEDULED
        val newInstance = FeedPreferences(context)
        assertEquals(PostFilter.SCHEDULED, newInstance.filter)
    }

    // --- Sort order persistence ---

    @Test
    fun `setting sortOrder to OLDEST persists`() {
        feedPreferences.sortOrder = SortOrder.OLDEST
        assertEquals(SortOrder.OLDEST, feedPreferences.sortOrder)
    }

    @Test
    fun `setting sortOrder to RECENTLY_UPDATED persists`() {
        feedPreferences.sortOrder = SortOrder.RECENTLY_UPDATED
        assertEquals(SortOrder.RECENTLY_UPDATED, feedPreferences.sortOrder)
    }

    @Test
    fun `setting sortOrder to NEWEST persists`() {
        feedPreferences.sortOrder = SortOrder.RECENTLY_UPDATED
        feedPreferences.sortOrder = SortOrder.NEWEST
        assertEquals(SortOrder.NEWEST, feedPreferences.sortOrder)
    }

    @Test
    fun `sortOrder persists across instances`() {
        feedPreferences.sortOrder = SortOrder.OLDEST
        val newInstance = FeedPreferences(context)
        assertEquals(SortOrder.OLDEST, newInstance.sortOrder)
    }

    // --- Filter and sort are independent ---

    @Test
    fun `changing filter does not affect sortOrder`() {
        feedPreferences.sortOrder = SortOrder.RECENTLY_UPDATED
        feedPreferences.filter = PostFilter.DRAFT
        assertEquals(SortOrder.RECENTLY_UPDATED, feedPreferences.sortOrder)
    }

    @Test
    fun `changing sortOrder does not affect filter`() {
        feedPreferences.filter = PostFilter.SCHEDULED
        feedPreferences.sortOrder = SortOrder.OLDEST
        assertEquals(PostFilter.SCHEDULED, feedPreferences.filter)
    }

    // --- Invalid stored values fallback to defaults ---

    @Test
    fun `invalid stored filter falls back to ALL`() {
        context.getSharedPreferences(FeedPreferences.PREFS_NAME, Context.MODE_PRIVATE)
            .edit().putString(FeedPreferences.KEY_FILTER, "INVALID_VALUE").commit()
        val prefs = FeedPreferences(context)
        assertEquals(PostFilter.ALL, prefs.filter)
    }

    @Test
    fun `invalid stored sortOrder falls back to NEWEST`() {
        context.getSharedPreferences(FeedPreferences.PREFS_NAME, Context.MODE_PRIVATE)
            .edit().putString(FeedPreferences.KEY_SORT_ORDER, "INVALID_VALUE").commit()
        val prefs = FeedPreferences(context)
        assertEquals(SortOrder.NEWEST, prefs.sortOrder)
    }

    // --- All filter values round-trip ---

    @Test
    fun `all PostFilter values round-trip correctly`() {
        for (filter in PostFilter.values()) {
            feedPreferences.filter = filter
            assertEquals("Round-trip failed for $filter", filter, feedPreferences.filter)
        }
    }

    @Test
    fun `all SortOrder values round-trip correctly`() {
        for (order in SortOrder.values()) {
            feedPreferences.sortOrder = order
            assertEquals("Round-trip failed for $order", order, feedPreferences.sortOrder)
        }
    }
}
