package com.rssuper.models

import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Before
import org.junit.Test
import java.util.Date

class FeedSubscriptionTest {

    private lateinit var moshi: Moshi
    private lateinit var adapter: com.squareup.moshi.JsonAdapter<FeedSubscription>

    @Before
    fun setup() {
        moshi = Moshi.Builder()
            .add(KotlinJsonAdapterFactory())
            .build()
        adapter = moshi.adapter(FeedSubscription::class.java)
    }

    @Test
    fun testSerialization() {
        val subscription = FeedSubscription(
            id = "sub-1",
            url = "https://example.com/feed.xml",
            title = "Tech News",
            category = "Technology",
            enabled = true,
            fetchInterval = 60,
            createdAt = Date(1672531200000),
            updatedAt = Date(1672617600000)
        )

        val json = adapter.toJson(subscription)
        assertNotNull(json)
    }

    @Test
    fun testDeserialization() {
        val json = """{
            "id": "sub-1",
            "url": "https://example.com/feed.xml",
            "title": "Tech News",
            "category": "Technology",
            "enabled": true,
            "fetchInterval": 60,
            "createdAt": 1672531200000,
            "updatedAt": 1672617600000
        }"""

        val subscription = adapter.fromJson(json)
        assertNotNull(subscription)
        assertEquals("sub-1", subscription?.id)
        assertEquals("https://example.com/feed.xml", subscription?.url)
        assertEquals("Tech News", subscription?.title)
        assertEquals("Technology", subscription?.category)
        assertEquals(true, subscription?.enabled)
        assertEquals(60, subscription?.fetchInterval)
    }

    @Test
    fun testOptionalFieldsNull() {
        val json = """{
            "id": "sub-1",
            "url": "https://example.com/feed.xml",
            "title": "Tech News",
            "enabled": true,
            "fetchInterval": 60,
            "createdAt": 1672531200000,
            "updatedAt": 1672617600000
        }"""

        val subscription = adapter.fromJson(json)
        assertNotNull(subscription)
        assertNull(subscription?.category)
        assertNull(subscription?.error)
        assertNull(subscription?.httpAuth)
    }

    @Test
    fun testHttpAuthSerialization() {
        val subscription = FeedSubscription(
            id = "sub-1",
            url = "https://example.com/feed.xml",
            title = "Private Feed",
            enabled = true,
            fetchInterval = 60,
            createdAt = Date(1672531200000),
            updatedAt = Date(1672617600000),
            httpAuth = HttpAuth(
                username = "user123",
                password = "pass456"
            )
        )

        val json = adapter.toJson(subscription)
        assertNotNull(json)
    }

    @Test
    fun testHttpAuthDeserialization() {
        val json = """{
            "id": "sub-1",
            "url": "https://example.com/feed.xml",
            "title": "Private Feed",
            "enabled": true,
            "fetchInterval": 60,
            "createdAt": 1672531200000,
            "updatedAt": 1672617600000,
            "httpAuth": {
                "username": "user123",
                "password": "pass456"
            }
        }"""

        val subscription = adapter.fromJson(json)
        assertNotNull(subscription)
        assertNotNull(subscription?.httpAuth)
        assertEquals("user123", subscription?.httpAuth?.username)
        assertEquals("pass456", subscription?.httpAuth?.password)
    }

    @Test
    fun testCopy() {
        val original = FeedSubscription(
            id = "sub-1",
            url = "https://example.com/feed.xml",
            title = "Original Title",
            enabled = true,
            fetchInterval = 60,
            createdAt = Date(1672531200000),
            updatedAt = Date(1672617600000)
        )

        val modified = original.copy(title = "Modified Title", enabled = false)

        assertEquals("sub-1", modified.id)
        assertEquals("Modified Title", modified.title)
        assertEquals(false, modified.enabled)
        assertEquals(60, modified.fetchInterval)
    }

    @Test
    fun testEqualsAndHashCode() {
        val sub1 = FeedSubscription(
            id = "sub-1",
            url = "https://example.com",
            title = "Test",
            enabled = true,
            fetchInterval = 60,
            createdAt = Date(1672531200000),
            updatedAt = Date(1672617600000)
        )
        val sub2 = FeedSubscription(
            id = "sub-1",
            url = "https://example.com",
            title = "Test",
            enabled = true,
            fetchInterval = 60,
            createdAt = Date(1672531200000),
            updatedAt = Date(1672617600000)
        )
        val sub3 = FeedSubscription(
            id = "sub-2",
            url = "https://example.com",
            title = "Test",
            enabled = true,
            fetchInterval = 60,
            createdAt = Date(1672531200000),
            updatedAt = Date(1672617600000)
        )

        assertEquals(sub1, sub2)
        assertEquals(sub1.hashCode(), sub2.hashCode())
        assert(sub1 != sub3)
    }

    @Test
    fun testToString() {
        val subscription = FeedSubscription(
            id = "sub-1",
            url = "https://example.com/feed.xml",
            title = "Tech News",
            enabled = true,
            fetchInterval = 60,
            createdAt = Date(1672531200000),
            updatedAt = Date(1672617600000)
        )

        val toString = subscription.toString()
        assertNotNull(toString)
        assert(toString.contains("id=sub-1"))
        assert(toString.contains("title=Tech News"))
    }
}
