package com.swoosh.microblog.data.db

import com.swoosh.microblog.data.model.PostStatus
import com.swoosh.microblog.data.model.QueueStatus
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test

class ConvertersTest {

    private lateinit var converters: Converters

    @Before
    fun setup() {
        converters = Converters()
    }

    // --- PostStatus conversions ---

    @Test
    fun `fromPostStatus DRAFT returns DRAFT string`() {
        assertEquals("DRAFT", converters.fromPostStatus(PostStatus.DRAFT))
    }

    @Test
    fun `fromPostStatus PUBLISHED returns PUBLISHED string`() {
        assertEquals("PUBLISHED", converters.fromPostStatus(PostStatus.PUBLISHED))
    }

    @Test
    fun `fromPostStatus SCHEDULED returns SCHEDULED string`() {
        assertEquals("SCHEDULED", converters.fromPostStatus(PostStatus.SCHEDULED))
    }

    @Test
    fun `toPostStatus DRAFT returns PostStatus DRAFT`() {
        assertEquals(PostStatus.DRAFT, converters.toPostStatus("DRAFT"))
    }

    @Test
    fun `toPostStatus PUBLISHED returns PostStatus PUBLISHED`() {
        assertEquals(PostStatus.PUBLISHED, converters.toPostStatus("PUBLISHED"))
    }

    @Test
    fun `toPostStatus SCHEDULED returns PostStatus SCHEDULED`() {
        assertEquals(PostStatus.SCHEDULED, converters.toPostStatus("SCHEDULED"))
    }

    @Test
    fun `PostStatus round-trip conversion preserves value`() {
        for (status in PostStatus.values()) {
            val str = converters.fromPostStatus(status)
            val restored = converters.toPostStatus(str)
            assertEquals("Round-trip failed for $status", status, restored)
        }
    }

    @Test
    fun `toPostStatus returns DRAFT fallback on invalid string`() {
        assertEquals(PostStatus.DRAFT, converters.toPostStatus("INVALID"))
    }

    // --- QueueStatus conversions ---

    @Test
    fun `fromQueueStatus NONE returns NONE string`() {
        assertEquals("NONE", converters.fromQueueStatus(QueueStatus.NONE))
    }

    @Test
    fun `fromQueueStatus QUEUED_PUBLISH returns correct string`() {
        assertEquals("QUEUED_PUBLISH", converters.fromQueueStatus(QueueStatus.QUEUED_PUBLISH))
    }

    @Test
    fun `fromQueueStatus QUEUED_SCHEDULED returns correct string`() {
        assertEquals("QUEUED_SCHEDULED", converters.fromQueueStatus(QueueStatus.QUEUED_SCHEDULED))
    }

    @Test
    fun `fromQueueStatus UPLOADING returns correct string`() {
        assertEquals("UPLOADING", converters.fromQueueStatus(QueueStatus.UPLOADING))
    }

    @Test
    fun `fromQueueStatus FAILED returns correct string`() {
        assertEquals("FAILED", converters.fromQueueStatus(QueueStatus.FAILED))
    }

    @Test
    fun `toQueueStatus NONE returns QueueStatus NONE`() {
        assertEquals(QueueStatus.NONE, converters.toQueueStatus("NONE"))
    }

    @Test
    fun `toQueueStatus QUEUED_PUBLISH returns correct enum`() {
        assertEquals(QueueStatus.QUEUED_PUBLISH, converters.toQueueStatus("QUEUED_PUBLISH"))
    }

    @Test
    fun `toQueueStatus FAILED returns correct enum`() {
        assertEquals(QueueStatus.FAILED, converters.toQueueStatus("FAILED"))
    }

    @Test
    fun `QueueStatus round-trip conversion preserves value`() {
        for (status in QueueStatus.values()) {
            val str = converters.fromQueueStatus(status)
            val restored = converters.toQueueStatus(str)
            assertEquals("Round-trip failed for $status", status, restored)
        }
    }

    @Test
    fun `toQueueStatus returns NONE fallback on invalid string`() {
        assertEquals(QueueStatus.NONE, converters.toQueueStatus("NONEXISTENT"))
    }

    // --- String list JSON serialization ---

    @Test
    fun `stringListToJson with null returns null`() {
        assertNull(Converters.stringListToJson(null))
    }

    @Test
    fun `stringListToJson with empty list returns null`() {
        assertNull(Converters.stringListToJson(emptyList()))
    }

    @Test
    fun `stringListToJson with single item returns JSON array`() {
        val result = Converters.stringListToJson(listOf("https://example.com/img.jpg"))
        assertNotNull(result)
        assertTrue(result!!.startsWith("["))
        assertTrue(result.endsWith("]"))
        assertTrue(result.contains("https://example.com/img.jpg"))
    }

    @Test
    fun `stringListToJson with multiple items returns JSON array`() {
        val result = Converters.stringListToJson(
            listOf("https://example.com/img1.jpg", "https://example.com/img2.jpg")
        )
        assertNotNull(result)
        assertTrue(result!!.contains("img1.jpg"))
        assertTrue(result.contains("img2.jpg"))
    }

    @Test
    fun `jsonToStringList with null returns empty list`() {
        assertEquals(emptyList<String>(), Converters.jsonToStringList(null))
    }

    @Test
    fun `jsonToStringList with empty string returns empty list`() {
        assertEquals(emptyList<String>(), Converters.jsonToStringList(""))
    }

    @Test
    fun `jsonToStringList with blank string returns empty list`() {
        assertEquals(emptyList<String>(), Converters.jsonToStringList("   "))
    }

    @Test
    fun `jsonToStringList with invalid JSON returns empty list`() {
        assertEquals(emptyList<String>(), Converters.jsonToStringList("not json"))
    }

    @Test
    fun `jsonToStringList with single item JSON array`() {
        val result = Converters.jsonToStringList("""["https://example.com/img.jpg"]""")
        assertEquals(1, result.size)
        assertEquals("https://example.com/img.jpg", result[0])
    }

    @Test
    fun `jsonToStringList with multiple items JSON array`() {
        val result = Converters.jsonToStringList(
            """["https://example.com/img1.jpg","https://example.com/img2.jpg","https://example.com/img3.jpg"]"""
        )
        assertEquals(3, result.size)
        assertEquals("https://example.com/img1.jpg", result[0])
        assertEquals("https://example.com/img2.jpg", result[1])
        assertEquals("https://example.com/img3.jpg", result[2])
    }

    @Test
    fun `stringListToJson and jsonToStringList round-trip`() {
        val original = listOf(
            "https://example.com/img1.jpg",
            "https://example.com/img2.jpg",
            "https://example.com/img3.jpg"
        )
        val json = Converters.stringListToJson(original)
        val restored = Converters.jsonToStringList(json)
        assertEquals(original, restored)
    }

    @Test
    fun `stringListToJson handles URLs with special characters`() {
        val urls = listOf(
            "https://example.com/img?id=1&name=test",
            "https://example.com/path/to/image (1).jpg"
        )
        val json = Converters.stringListToJson(urls)
        val restored = Converters.jsonToStringList(json)
        assertEquals(urls, restored)
    }

    @Test
    fun `jsonToStringList with empty JSON array returns empty list`() {
        val result = Converters.jsonToStringList("[]")
        assertEquals(emptyList<String>(), result)
    }
}
