package com.rssuper.database

import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import com.rssuper.database.entities.FeedItemEntity
import com.rssuper.database.entities.SearchHistoryEntity
import com.rssuper.database.entities.SubscriptionEntity
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test
import java.util.Date
import java.util.UUID

class RssDatabaseTest {
    
    private lateinit var database: RssDatabase
    
    @Before
    fun createDb() {
        val context = ApplicationProvider.getApplicationContext<Context>()
        database = Room.inMemoryDatabaseBuilder(
            context,
            RssDatabase::class.java
        )
            .allowMainThreadQueries()
            .build()
    }
    
    @After
    fun closeDb() {
        database.close()
    }
    
    @Test
    fun databaseConstruction() {
        assertNotNull(database.subscriptionDao())
        assertNotNull(database.feedItemDao())
        assertNotNull(database.searchHistoryDao())
    }
    
    @Test
    fun ftsVirtualTableExists() {
        val cursor = database.run {
            openHelper.writableDatabase.query(
                "SELECT name FROM sqlite_master WHERE type='table' AND name='feed_items_fts'",
                emptyArray()
            )
        }
        
        assertEquals(true, cursor.moveToFirst())
        cursor.close()
    }
    
    @Test
    fun subscriptionEntityRoundTrip() = runTest {
        val now = Date()
        val subscription = SubscriptionEntity(
            id = UUID.randomUUID().toString(),
            url = "https://example.com/feed",
            title = "Test Feed",
            category = "Tech",
            enabled = true,
            fetchInterval = 3600000,
            createdAt = now,
            updatedAt = now,
            lastFetchedAt = null,
            nextFetchAt = null,
            error = null,
            httpAuthUsername = null,
            httpAuthPassword = null
        )
        
        database.subscriptionDao().insertSubscription(subscription)
        
        val result = database.subscriptionDao().getSubscriptionById(subscription.id)
        assertNotNull(result)
        assertEquals(subscription.id, result?.id)
        assertEquals(subscription.title, result?.title)
    }
    
    @Test
    fun feedItemEntityRoundTrip() = runTest {
        val now = Date()
        val subscription = SubscriptionEntity(
            id = "sub1",
            url = "https://example.com/feed",
            title = "Test Feed",
            category = "Tech",
            enabled = true,
            fetchInterval = 3600000,
            createdAt = now,
            updatedAt = now,
            lastFetchedAt = null,
            nextFetchAt = null,
            error = null,
            httpAuthUsername = null,
            httpAuthPassword = null
        )
        database.subscriptionDao().insertSubscription(subscription)
        
        val item = FeedItemEntity(
            id = UUID.randomUUID().toString(),
            subscriptionId = "sub1",
            title = "Test Item",
            link = "https://example.com/item",
            description = "Test description",
            content = "Test content",
            author = "Test Author",
            published = now,
            updated = now,
            categories = "Tech",
            enclosureUrl = null,
            enclosureType = null,
            enclosureLength = null,
            guid = "guid-1",
            isRead = false,
            isStarred = false
        )
        
        database.feedItemDao().insertItem(item)
        
        val result = database.feedItemDao().getItemById(item.id)
        assertNotNull(result)
        assertEquals(item.id, result?.id)
        assertEquals(item.title, result?.title)
        assertEquals("sub1", result?.subscriptionId)
    }
    
    @Test
    fun searchHistoryEntityRoundTrip() = runTest {
        val now = Date()
        val search = SearchHistoryEntity(
            id = UUID.randomUUID().toString(),
            query = "kotlin coroutines",
            timestamp = now
        )
        
        database.searchHistoryDao().insertSearchHistory(search)
        
        val result = database.searchHistoryDao().getSearchHistoryById(search.id)
        assertNotNull(result)
        assertEquals(search.id, result?.id)
        assertEquals(search.query, result?.query)
    }
    
    @Test
    fun cascadeDeleteFeedItems() = runTest {
        val now = Date()
        val subscription = SubscriptionEntity(
            id = "sub1",
            url = "https://example.com/feed",
            title = "Test Feed",
            category = "Tech",
            enabled = true,
            fetchInterval = 3600000,
            createdAt = now,
            updatedAt = now,
            lastFetchedAt = null,
            nextFetchAt = null,
            error = null,
            httpAuthUsername = null,
            httpAuthPassword = null
        )
        database.subscriptionDao().insertSubscription(subscription)
        
        val item = FeedItemEntity(
            id = "item1",
            subscriptionId = "sub1",
            title = "Test Item",
            link = "https://example.com/item",
            description = "Test description",
            content = "Test content",
            author = "Test Author",
            published = now,
            updated = now,
            categories = "Tech",
            enclosureUrl = null,
            enclosureType = null,
            enclosureLength = null,
            guid = "guid-1",
            isRead = false,
            isStarred = false
        )
        database.feedItemDao().insertItem(item)
        
        database.subscriptionDao().deleteSubscription(subscription)
        
        val items = database.feedItemDao().getItemsBySubscription("sub1").first()
        assertEquals(0, items.size)
    }
}
